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" } }, | ... | ... |