Commit fe6f943f3bfba8d15ae2f063fad47997af5fb644
1 parent
000a2d86
Immediate versions of some operations
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4962 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
57 additions
and
27 deletions
tcg/ppc64/tcg-target.c
... | ... | @@ -22,6 +22,8 @@ |
22 | 22 | * THE SOFTWARE. |
23 | 23 | */ |
24 | 24 | |
25 | +#define TCG_CT_CONST_U32 0x100 | |
26 | + | |
25 | 27 | static uint8_t *tb_ret_addr; |
26 | 28 | |
27 | 29 | #define FAST_PATH |
... | ... | @@ -226,6 +228,9 @@ static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str) |
226 | 228 | tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4); |
227 | 229 | tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5); |
228 | 230 | break; |
231 | + case 'Z': | |
232 | + ct->ct |= TCG_CT_CONST_U32; | |
233 | + break; | |
229 | 234 | default: |
230 | 235 | return -1; |
231 | 236 | } |
... | ... | @@ -243,6 +248,8 @@ static int tcg_target_const_match (tcg_target_long val, |
243 | 248 | ct = arg_ct->ct; |
244 | 249 | if (ct & TCG_CT_CONST) |
245 | 250 | return 1; |
251 | + else if ((ct & TCG_CT_CONST_U32) && (val == (uint32_t) val)) | |
252 | + return 1; | |
246 | 253 | return 0; |
247 | 254 | } |
248 | 255 | |
... | ... | @@ -352,6 +359,7 @@ static int tcg_target_const_match (tcg_target_long val, |
352 | 359 | #define SLD XO31( 27) |
353 | 360 | #define SRD XO31(539) |
354 | 361 | #define SRAD XO31(794) |
362 | +#define SRADI XO31(413<<1) | |
355 | 363 | |
356 | 364 | #define LMW OPCD( 46) |
357 | 365 | #define STMW OPCD( 47) |
... | ... | @@ -874,8 +882,14 @@ static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si) |
874 | 882 | |
875 | 883 | static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si) |
876 | 884 | { |
877 | - tcg_out_movi (s, TCG_TYPE_I64, 0, si); | |
878 | - tcg_out32 (s, ADD | RT (rt) | RA (ra)); | |
885 | + /* XXX: suboptimal */ | |
886 | + if (si == (int16_t) si | |
887 | + || (((uint64_t) si >> 31) == 0) && (si & 0x8000) == 0) | |
888 | + ppc_addi32 (s, rt, ra, si); | |
889 | + else { | |
890 | + tcg_out_movi (s, TCG_TYPE_I64, 0, si); | |
891 | + tcg_out32 (s, ADD | RT (rt) | RA (ra)); | |
892 | + } | |
879 | 893 | } |
880 | 894 | |
881 | 895 | static void tcg_out_addi (TCGContext *s, int reg, tcg_target_long val) |
... | ... | @@ -1102,6 +1116,7 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args, |
1102 | 1116 | tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1])); |
1103 | 1117 | break; |
1104 | 1118 | |
1119 | + case INDEX_op_and_i64: | |
1105 | 1120 | case INDEX_op_and_i32: |
1106 | 1121 | if (const_args[2]) { |
1107 | 1122 | if ((args[2] & 0xffff) == args[2]) |
... | ... | @@ -1110,13 +1125,17 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args, |
1110 | 1125 | tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0]) |
1111 | 1126 | | ((args[2] >> 16) & 0xffff)); |
1112 | 1127 | else { |
1113 | - tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]); | |
1128 | + tcg_out_movi (s, (opc == INDEX_op_and_i32 | |
1129 | + ? TCG_TYPE_I32 | |
1130 | + : TCG_TYPE_I64), | |
1131 | + 0, args[2]); | |
1114 | 1132 | tcg_out32 (s, AND | SAB (args[1], args[0], 0)); |
1115 | 1133 | } |
1116 | 1134 | } |
1117 | 1135 | else |
1118 | 1136 | tcg_out32 (s, AND | SAB (args[1], args[0], args[2])); |
1119 | 1137 | break; |
1138 | + case INDEX_op_or_i64: | |
1120 | 1139 | case INDEX_op_or_i32: |
1121 | 1140 | if (const_args[2]) { |
1122 | 1141 | if (args[2] & 0xffff) { |
... | ... | @@ -1134,6 +1153,7 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args, |
1134 | 1153 | else |
1135 | 1154 | tcg_out32 (s, OR | SAB (args[1], args[0], args[2])); |
1136 | 1155 | break; |
1156 | + case INDEX_op_xor_i64: | |
1137 | 1157 | case INDEX_op_xor_i32: |
1138 | 1158 | if (const_args[2]) { |
1139 | 1159 | if ((args[2] & 0xffff) == args[2]) |
... | ... | @@ -1143,7 +1163,10 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args, |
1143 | 1163 | tcg_out32 (s, XORIS | RS (args[1]) | RA (args[0]) |
1144 | 1164 | | ((args[2] >> 16) & 0xffff)); |
1145 | 1165 | else { |
1146 | - tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]); | |
1166 | + tcg_out_movi (s, (opc == INDEX_op_and_i32 | |
1167 | + ? TCG_TYPE_I32 | |
1168 | + : TCG_TYPE_I64), | |
1169 | + 0, args[2]); | |
1147 | 1170 | tcg_out32 (s, XOR | SAB (args[1], args[0], 0)); |
1148 | 1171 | } |
1149 | 1172 | } |
... | ... | @@ -1234,30 +1257,37 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args, |
1234 | 1257 | break; |
1235 | 1258 | |
1236 | 1259 | case INDEX_op_add_i64: |
1237 | - tcg_out32 (s, ADD | TAB (args[0], args[1], args[2])); | |
1260 | + if (const_args[2]) | |
1261 | + ppc_addi64 (s, args[0], args[1], args[2]); | |
1262 | + else | |
1263 | + tcg_out32 (s, ADD | TAB (args[0], args[1], args[2])); | |
1238 | 1264 | break; |
1239 | 1265 | case INDEX_op_sub_i64: |
1240 | - tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1])); | |
1241 | - break; | |
1242 | - | |
1243 | - case INDEX_op_and_i64: | |
1244 | - tcg_out32 (s, AND | SAB (args[1], args[0], args[2])); | |
1245 | - break; | |
1246 | - case INDEX_op_or_i64: | |
1247 | - tcg_out32 (s, OR | SAB (args[1], args[0], args[2])); | |
1248 | - break; | |
1249 | - case INDEX_op_xor_i64: | |
1250 | - tcg_out32 (s, XOR | SAB (args[1], args[0], args[2])); | |
1266 | + if (const_args[2]) | |
1267 | + ppc_addi64 (s, args[0], args[1], -args[2]); | |
1268 | + else | |
1269 | + tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1])); | |
1251 | 1270 | break; |
1252 | 1271 | |
1253 | 1272 | case INDEX_op_shl_i64: |
1254 | - tcg_out32 (s, SLD | SAB (args[1], args[0], args[2])); | |
1273 | + if (const_args[2]) | |
1274 | + tcg_out_rld (s, RLDICR, args[0], args[1], args[2], 63 - args[2]); | |
1275 | + else | |
1276 | + tcg_out32 (s, SLD | SAB (args[1], args[0], args[2])); | |
1255 | 1277 | break; |
1256 | 1278 | case INDEX_op_shr_i64: |
1257 | - tcg_out32 (s, SRD | SAB (args[1], args[0], args[2])); | |
1279 | + if (const_args[2]) | |
1280 | + tcg_out_rld (s, RLDICL, args[0], args[1], 64 - args[2], args[2]); | |
1281 | + else | |
1282 | + tcg_out32 (s, SRD | SAB (args[1], args[0], args[2])); | |
1258 | 1283 | break; |
1259 | 1284 | case INDEX_op_sar_i64: |
1260 | - tcg_out32 (s, SRAD | SAB (args[1], args[0], args[2])); | |
1285 | + if (const_args[2]) { | |
1286 | + int sh = SH (args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1); | |
1287 | + tcg_out32 (s, SRADI | RA (args[0]) | RS (args[1]) | sh); | |
1288 | + } | |
1289 | + else | |
1290 | + tcg_out32 (s, SRAD | SAB (args[1], args[0], args[2])); | |
1261 | 1291 | break; |
1262 | 1292 | |
1263 | 1293 | case INDEX_op_mul_i64: |
... | ... | @@ -1389,15 +1419,15 @@ static const TCGTargetOpDef ppc_op_defs[] = { |
1389 | 1419 | |
1390 | 1420 | { INDEX_op_neg_i32, { "r", "r" } }, |
1391 | 1421 | |
1392 | - { INDEX_op_add_i64, { "r", "r", "r" } }, | |
1393 | - { INDEX_op_sub_i64, { "r", "r", "r" } }, | |
1394 | - { INDEX_op_and_i64, { "r", "r", "r" } }, | |
1395 | - { INDEX_op_or_i64, { "r", "r", "r" } }, | |
1396 | - { INDEX_op_xor_i64, { "r", "r", "r" } }, | |
1422 | + { INDEX_op_add_i64, { "r", "r", "ri" } }, | |
1423 | + { INDEX_op_sub_i64, { "r", "r", "ri" } }, | |
1424 | + { INDEX_op_and_i64, { "r", "r", "rZ" } }, | |
1425 | + { INDEX_op_or_i64, { "r", "r", "rZ" } }, | |
1426 | + { INDEX_op_xor_i64, { "r", "r", "rZ" } }, | |
1397 | 1427 | |
1398 | - { INDEX_op_shl_i64, { "r", "r", "r" } }, | |
1399 | - { INDEX_op_shr_i64, { "r", "r", "r" } }, | |
1400 | - { INDEX_op_sar_i64, { "r", "r", "r" } }, | |
1428 | + { INDEX_op_shl_i64, { "r", "r", "ri" } }, | |
1429 | + { INDEX_op_shr_i64, { "r", "r", "ri" } }, | |
1430 | + { INDEX_op_sar_i64, { "r", "r", "ri" } }, | |
1401 | 1431 | |
1402 | 1432 | { INDEX_op_mul_i64, { "r", "r", "r" } }, |
1403 | 1433 | { INDEX_op_div_i64, { "r", "r", "r" } }, | ... | ... |