Commit fa4fbfb98ad09b1a5bde2c78db5cb1c13363bdf2
1 parent
5d794885
Emit trampolines manually in prologue
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4715 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
80 additions
and
38 deletions
tcg/ppc/tcg-target.c
| ... | ... | @@ -23,6 +23,8 @@ |
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | 25 | static uint8_t *tb_ret_addr; |
| 26 | +static uint8_t *udiv_addr; | |
| 27 | +static uint8_t *div_addr; | |
| 26 | 28 | |
| 27 | 29 | #define FAST_PATH |
| 28 | 30 | #if TARGET_PHYS_ADDR_BITS <= 32 |
| ... | ... | @@ -118,7 +120,7 @@ static const int tcg_target_call_oarg_regs[2] = { |
| 118 | 120 | }; |
| 119 | 121 | |
| 120 | 122 | static const int tcg_target_callee_save_regs[] = { |
| 121 | - TCG_REG_R13, /* sould r13 be saved? */ | |
| 123 | + TCG_REG_R13, /* should r13 be saved? */ | |
| 122 | 124 | TCG_REG_R14, |
| 123 | 125 | TCG_REG_R15, |
| 124 | 126 | TCG_REG_R16, |
| ... | ... | @@ -135,6 +137,22 @@ static const int tcg_target_callee_save_regs[] = { |
| 135 | 137 | TCG_REG_R31 |
| 136 | 138 | }; |
| 137 | 139 | |
| 140 | +static const int div_save_regs[] = { | |
| 141 | + TCG_REG_R4, | |
| 142 | + TCG_REG_R5, | |
| 143 | + TCG_REG_R7, | |
| 144 | + TCG_REG_R8, | |
| 145 | + TCG_REG_R9, | |
| 146 | + TCG_REG_R10, | |
| 147 | + TCG_REG_R11, | |
| 148 | + TCG_REG_R12, | |
| 149 | + TCG_REG_R13, /* should r13 be saved? */ | |
| 150 | + TCG_REG_R24, | |
| 151 | + TCG_REG_R25, | |
| 152 | + TCG_REG_R26, | |
| 153 | + TCG_REG_R27, | |
| 154 | +}; | |
| 155 | + | |
| 138 | 156 | static uint32_t reloc_pc24_val (void *pc, tcg_target_long target) |
| 139 | 157 | { |
| 140 | 158 | tcg_target_long disp; |
| ... | ... | @@ -799,9 +817,25 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) |
| 799 | 817 | #endif |
| 800 | 818 | } |
| 801 | 819 | |
| 820 | +static uint64_t ppc_udiv_helper (uint64_t a, uint32_t b) | |
| 821 | +{ | |
| 822 | + uint64_t rem, quo; | |
| 823 | + quo = a / b; | |
| 824 | + rem = a % b; | |
| 825 | + return (rem << 32) | (uint32_t) quo; | |
| 826 | +} | |
| 827 | + | |
| 828 | +static uint64_t ppc_div_helper (int64_t a, int32_t b) | |
| 829 | +{ | |
| 830 | + int64_t rem, quo; | |
| 831 | + quo = a / b; | |
| 832 | + rem = a % b; | |
| 833 | + return (rem << 32) | (uint32_t) quo; | |
| 834 | +} | |
| 835 | + | |
| 802 | 836 | void tcg_target_qemu_prologue (TCGContext *s) |
| 803 | 837 | { |
| 804 | - int i, frame_size; | |
| 838 | + int i, j, frame_size; | |
| 805 | 839 | |
| 806 | 840 | frame_size = 0 |
| 807 | 841 | + 4 /* back chain */ |
| ... | ... | @@ -837,6 +871,49 @@ void tcg_target_qemu_prologue (TCGContext *s) |
| 837 | 871 | tcg_out32 (s, MTSPR | RS (0) | LR); |
| 838 | 872 | tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); |
| 839 | 873 | tcg_out32 (s, BCLR | BO_ALWAYS); |
| 874 | + | |
| 875 | + /* div trampolines */ | |
| 876 | + for (j = 0; j < 2; ++j) { | |
| 877 | + tcg_target_long target; | |
| 878 | + | |
| 879 | + frame_size = 8 + ARRAY_SIZE (div_save_regs) * 4; | |
| 880 | + frame_size = (frame_size + 15) & ~15; | |
| 881 | + | |
| 882 | + if (j == 0) { | |
| 883 | + target = (tcg_target_long) ppc_udiv_helper; | |
| 884 | + udiv_addr = s->code_ptr; | |
| 885 | + } | |
| 886 | + else { | |
| 887 | + target = (tcg_target_long) ppc_div_helper; | |
| 888 | + div_addr = s->code_ptr; | |
| 889 | + } | |
| 890 | + | |
| 891 | + tcg_out32 (s, MFSPR | RT (0) | LR); | |
| 892 | + tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff)); | |
| 893 | + for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i) | |
| 894 | + tcg_out32 (s, (STW | |
| 895 | + | RS (div_save_regs[i]) | |
| 896 | + | RA (1) | |
| 897 | + | (i * 4 + 8) | |
| 898 | + ) | |
| 899 | + ); | |
| 900 | + tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size - 4)); | |
| 901 | + tcg_out_mov (s, 4, 6); | |
| 902 | + tcg_out_b (s, LK, target); | |
| 903 | + tcg_out_mov (s, 6, 4); | |
| 904 | + | |
| 905 | + for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i) | |
| 906 | + tcg_out32 (s, (LWZ | |
| 907 | + | RT (div_save_regs[i]) | |
| 908 | + | RA (1) | |
| 909 | + | (i * 4 + 8) | |
| 910 | + ) | |
| 911 | + ); | |
| 912 | + tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size - 4)); | |
| 913 | + tcg_out32 (s, MTSPR | RS (0) | LR); | |
| 914 | + tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); | |
| 915 | + tcg_out32 (s, BCLR | BO_ALWAYS); | |
| 916 | + } | |
| 840 | 917 | } |
| 841 | 918 | |
| 842 | 919 | static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1, |
| ... | ... | @@ -1018,41 +1095,6 @@ static void tcg_out_brcond2(TCGContext *s, |
| 1018 | 1095 | tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); |
| 1019 | 1096 | } |
| 1020 | 1097 | |
| 1021 | -static uint64_t __attribute ((used)) ppc_udiv_helper (uint64_t a, uint32_t b) | |
| 1022 | -{ | |
| 1023 | - uint64_t rem, quo; | |
| 1024 | - quo = a / b; | |
| 1025 | - rem = a % b; | |
| 1026 | - return (rem << 32) | (uint32_t) quo; | |
| 1027 | -} | |
| 1028 | - | |
| 1029 | -static uint64_t __attribute ((used)) ppc_div_helper (int64_t a, int32_t b) | |
| 1030 | -{ | |
| 1031 | - int64_t rem, quo; | |
| 1032 | - quo = a / b; | |
| 1033 | - rem = a % b; | |
| 1034 | - return (rem << 32) | (uint32_t) quo; | |
| 1035 | -} | |
| 1036 | - | |
| 1037 | -#define MAKE_TRAMPOLINE(name) \ | |
| 1038 | -extern void name##_trampoline (void); \ | |
| 1039 | -asm (#name "_trampoline:\n" \ | |
| 1040 | - " mflr 0\n" \ | |
| 1041 | - " addi 1,1,-112\n" \ | |
| 1042 | - " mr 4,6\n" \ | |
| 1043 | - " stmw 7,0(1)\n" \ | |
| 1044 | - " stw 0,108(0)\n" \ | |
| 1045 | - " bl ppc_" #name "_helper\n" \ | |
| 1046 | - " lmw 7,0(1)\n" \ | |
| 1047 | - " lwz 0,108(0)\n" \ | |
| 1048 | - " addi 1,1,112\n" \ | |
| 1049 | - " mtlr 0\n" \ | |
| 1050 | - " blr\n" \ | |
| 1051 | - ) | |
| 1052 | - | |
| 1053 | -MAKE_TRAMPOLINE (div); | |
| 1054 | -MAKE_TRAMPOLINE (udiv); | |
| 1055 | - | |
| 1056 | 1098 | static void tcg_out_div2 (TCGContext *s, int uns) |
| 1057 | 1099 | { |
| 1058 | 1100 | void *label1_ptr, *label2_ptr; |
| ... | ... | @@ -1067,7 +1109,7 @@ static void tcg_out_div2 (TCGContext *s, int uns) |
| 1067 | 1109 | label1_ptr = s->code_ptr; |
| 1068 | 1110 | tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE); |
| 1069 | 1111 | |
| 1070 | - tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_trampoline : div_trampoline)); | |
| 1112 | + tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_addr : div_addr)); | |
| 1071 | 1113 | |
| 1072 | 1114 | label2_ptr = s->code_ptr; |
| 1073 | 1115 | tcg_out32 (s, B); | ... | ... |