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,6 +23,8 @@
23 */ 23 */
24 24
25 static uint8_t *tb_ret_addr; 25 static uint8_t *tb_ret_addr;
  26 +static uint8_t *udiv_addr;
  27 +static uint8_t *div_addr;
26 28
27 #define FAST_PATH 29 #define FAST_PATH
28 #if TARGET_PHYS_ADDR_BITS <= 32 30 #if TARGET_PHYS_ADDR_BITS <= 32
@@ -118,7 +120,7 @@ static const int tcg_target_call_oarg_regs[2] = { @@ -118,7 +120,7 @@ static const int tcg_target_call_oarg_regs[2] = {
118 }; 120 };
119 121
120 static const int tcg_target_callee_save_regs[] = { 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 TCG_REG_R14, 124 TCG_REG_R14,
123 TCG_REG_R15, 125 TCG_REG_R15,
124 TCG_REG_R16, 126 TCG_REG_R16,
@@ -135,6 +137,22 @@ static const int tcg_target_callee_save_regs[] = { @@ -135,6 +137,22 @@ static const int tcg_target_callee_save_regs[] = {
135 TCG_REG_R31 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 static uint32_t reloc_pc24_val (void *pc, tcg_target_long target) 156 static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
139 { 157 {
140 tcg_target_long disp; 158 tcg_target_long disp;
@@ -799,9 +817,25 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) @@ -799,9 +817,25 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
799 #endif 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 void tcg_target_qemu_prologue (TCGContext *s) 836 void tcg_target_qemu_prologue (TCGContext *s)
803 { 837 {
804 - int i, frame_size; 838 + int i, j, frame_size;
805 839
806 frame_size = 0 840 frame_size = 0
807 + 4 /* back chain */ 841 + 4 /* back chain */
@@ -837,6 +871,49 @@ void tcg_target_qemu_prologue (TCGContext *s) @@ -837,6 +871,49 @@ void tcg_target_qemu_prologue (TCGContext *s)
837 tcg_out32 (s, MTSPR | RS (0) | LR); 871 tcg_out32 (s, MTSPR | RS (0) | LR);
838 tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); 872 tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
839 tcg_out32 (s, BCLR | BO_ALWAYS); 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 static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1, 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,41 +1095,6 @@ static void tcg_out_brcond2(TCGContext *s,
1018 tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); 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 static void tcg_out_div2 (TCGContext *s, int uns) 1098 static void tcg_out_div2 (TCGContext *s, int uns)
1057 { 1099 {
1058 void *label1_ptr, *label2_ptr; 1100 void *label1_ptr, *label2_ptr;
@@ -1067,7 +1109,7 @@ static void tcg_out_div2 (TCGContext *s, int uns) @@ -1067,7 +1109,7 @@ static void tcg_out_div2 (TCGContext *s, int uns)
1067 label1_ptr = s->code_ptr; 1109 label1_ptr = s->code_ptr;
1068 tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE); 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 label2_ptr = s->code_ptr; 1114 label2_ptr = s->code_ptr;
1073 tcg_out32 (s, B); 1115 tcg_out32 (s, B);