Commit fa4fbfb98ad09b1a5bde2c78db5cb1c13363bdf2

Authored by malc
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);
... ...