Commit 77b73de67632ed04acad4d816741ba27427cadac
1 parent
877d8ad7
Use rem/div[u]_i32 drop div[u]2_i32
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4722 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
26 additions
and
113 deletions
tcg/ppc/tcg-target.c
... | ... | @@ -23,8 +23,6 @@ |
23 | 23 | */ |
24 | 24 | |
25 | 25 | static uint8_t *tb_ret_addr; |
26 | -static uint8_t *udiv_addr; | |
27 | -static uint8_t *div_addr; | |
28 | 26 | |
29 | 27 | #define FAST_PATH |
30 | 28 | #if TARGET_PHYS_ADDR_BITS <= 32 |
... | ... | @@ -137,22 +135,6 @@ static const int tcg_target_callee_save_regs[] = { |
137 | 135 | TCG_REG_R31 |
138 | 136 | }; |
139 | 137 | |
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 | - | |
156 | 138 | static uint32_t reloc_pc24_val (void *pc, tcg_target_long target) |
157 | 139 | { |
158 | 140 | tcg_target_long disp; |
... | ... | @@ -817,22 +799,6 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) |
817 | 799 | #endif |
818 | 800 | } |
819 | 801 | |
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 | - | |
836 | 802 | void tcg_target_qemu_prologue (TCGContext *s) |
837 | 803 | { |
838 | 804 | int i, j, frame_size; |
... | ... | @@ -871,49 +837,6 @@ void tcg_target_qemu_prologue (TCGContext *s) |
871 | 837 | tcg_out32 (s, MTSPR | RS (0) | LR); |
872 | 838 | tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); |
873 | 839 | 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 | - } | |
917 | 840 | } |
918 | 841 | |
919 | 842 | static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1, |
... | ... | @@ -1095,34 +1018,6 @@ static void tcg_out_brcond2(TCGContext *s, |
1095 | 1018 | tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); |
1096 | 1019 | } |
1097 | 1020 | |
1098 | -static void tcg_out_div2 (TCGContext *s, int uns) | |
1099 | -{ | |
1100 | - void *label1_ptr, *label2_ptr; | |
1101 | - | |
1102 | - if (uns) | |
1103 | - tcg_out32 (s, CMPLI | BF (7) | RA (3)); | |
1104 | - else { | |
1105 | - tcg_out32 (s, SRAWI | RS (4) | RA (0) | 31); | |
1106 | - tcg_out32 (s, CMPL | BF (7) | RA (3) | RB (4)); | |
1107 | - } | |
1108 | - | |
1109 | - label1_ptr = s->code_ptr; | |
1110 | - tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE); | |
1111 | - | |
1112 | - tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_addr : div_addr)); | |
1113 | - | |
1114 | - label2_ptr = s->code_ptr; | |
1115 | - tcg_out32 (s, B); | |
1116 | - | |
1117 | - reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr); | |
1118 | - | |
1119 | - tcg_out32 (s, (uns ? DIVWU : DIVW) | TAB (6, 4, 5)); | |
1120 | - tcg_out32 (s, MULLW | TAB (0, 6, 5)); | |
1121 | - tcg_out32 (s, SUBF | TAB (3, 0, 4)); | |
1122 | - | |
1123 | - reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr); | |
1124 | -} | |
1125 | - | |
1126 | 1021 | static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, |
1127 | 1022 | const int *const_args) |
1128 | 1023 | { |
... | ... | @@ -1301,6 +1196,27 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, |
1301 | 1196 | else |
1302 | 1197 | tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2])); |
1303 | 1198 | break; |
1199 | + | |
1200 | + case INDEX_op_div_i32: | |
1201 | + tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2])); | |
1202 | + break; | |
1203 | + | |
1204 | + case INDEX_op_divu_i32: | |
1205 | + tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2])); | |
1206 | + break; | |
1207 | + | |
1208 | + case INDEX_op_rem_i32: | |
1209 | + tcg_out32 (s, DIVW | TAB (0, args[1], args[2])); | |
1210 | + tcg_out32 (s, MULLW | TAB (0, 0, args[2])); | |
1211 | + tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); | |
1212 | + break; | |
1213 | + | |
1214 | + case INDEX_op_remu_i32: | |
1215 | + tcg_out32 (s, DIVWU | TAB (0, args[1], args[2])); | |
1216 | + tcg_out32 (s, MULLW | TAB (0, 0, args[2])); | |
1217 | + tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); | |
1218 | + break; | |
1219 | + | |
1304 | 1220 | case INDEX_op_mulu2_i32: |
1305 | 1221 | if (args[0] == args[2] || args[0] == args[3]) { |
1306 | 1222 | tcg_out32 (s, MULLW | TAB (0, args[2], args[3])); |
... | ... | @@ -1312,12 +1228,6 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, |
1312 | 1228 | tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3])); |
1313 | 1229 | } |
1314 | 1230 | break; |
1315 | - case INDEX_op_div2_i32: | |
1316 | - tcg_out_div2 (s, 0); | |
1317 | - break; | |
1318 | - case INDEX_op_divu2_i32: | |
1319 | - tcg_out_div2 (s, 1); | |
1320 | - break; | |
1321 | 1231 | |
1322 | 1232 | case INDEX_op_shl_i32: |
1323 | 1233 | if (const_args[2]) { |
... | ... | @@ -1458,9 +1368,11 @@ static const TCGTargetOpDef ppc_op_defs[] = { |
1458 | 1368 | |
1459 | 1369 | { INDEX_op_add_i32, { "r", "r", "ri" } }, |
1460 | 1370 | { INDEX_op_mul_i32, { "r", "r", "ri" } }, |
1371 | + { INDEX_op_div_i32, { "r", "r", "r" } }, | |
1372 | + { INDEX_op_divu_i32, { "r", "r", "r" } }, | |
1373 | + { INDEX_op_rem_i32, { "r", "r", "r" } }, | |
1374 | + { INDEX_op_remu_i32, { "r", "r", "r" } }, | |
1461 | 1375 | { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, |
1462 | - { INDEX_op_div2_i32, { "D", "A", "B", "1", "C" } }, | |
1463 | - { INDEX_op_divu2_i32, { "D", "A", "B", "1", "C" } }, | |
1464 | 1376 | { INDEX_op_sub_i32, { "r", "r", "ri" } }, |
1465 | 1377 | { INDEX_op_and_i32, { "r", "r", "ri" } }, |
1466 | 1378 | { INDEX_op_or_i32, { "r", "r", "ri" } }, | ... | ... |