Commit fe6f943f3bfba8d15ae2f063fad47997af5fb644

Authored by malc
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,6 +22,8 @@
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
24 24
  25 +#define TCG_CT_CONST_U32 0x100
  26 +
25 static uint8_t *tb_ret_addr; 27 static uint8_t *tb_ret_addr;
26 28
27 #define FAST_PATH 29 #define FAST_PATH
@@ -226,6 +228,9 @@ static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str) @@ -226,6 +228,9 @@ static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
226 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4); 228 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
227 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5); 229 tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
228 break; 230 break;
  231 + case 'Z':
  232 + ct->ct |= TCG_CT_CONST_U32;
  233 + break;
229 default: 234 default:
230 return -1; 235 return -1;
231 } 236 }
@@ -243,6 +248,8 @@ static int tcg_target_const_match (tcg_target_long val, @@ -243,6 +248,8 @@ static int tcg_target_const_match (tcg_target_long val,
243 ct = arg_ct->ct; 248 ct = arg_ct->ct;
244 if (ct & TCG_CT_CONST) 249 if (ct & TCG_CT_CONST)
245 return 1; 250 return 1;
  251 + else if ((ct & TCG_CT_CONST_U32) && (val == (uint32_t) val))
  252 + return 1;
246 return 0; 253 return 0;
247 } 254 }
248 255
@@ -352,6 +359,7 @@ static int tcg_target_const_match (tcg_target_long val, @@ -352,6 +359,7 @@ static int tcg_target_const_match (tcg_target_long val,
352 #define SLD XO31( 27) 359 #define SLD XO31( 27)
353 #define SRD XO31(539) 360 #define SRD XO31(539)
354 #define SRAD XO31(794) 361 #define SRAD XO31(794)
  362 +#define SRADI XO31(413<<1)
355 363
356 #define LMW OPCD( 46) 364 #define LMW OPCD( 46)
357 #define STMW OPCD( 47) 365 #define STMW OPCD( 47)
@@ -874,8 +882,14 @@ static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si) @@ -874,8 +882,14 @@ static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si)
874 882
875 static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si) 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 static void tcg_out_addi (TCGContext *s, int reg, tcg_target_long val) 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,6 +1116,7 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
1102 tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1])); 1116 tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
1103 break; 1117 break;
1104 1118
  1119 + case INDEX_op_and_i64:
1105 case INDEX_op_and_i32: 1120 case INDEX_op_and_i32:
1106 if (const_args[2]) { 1121 if (const_args[2]) {
1107 if ((args[2] & 0xffff) == args[2]) 1122 if ((args[2] & 0xffff) == args[2])
@@ -1110,13 +1125,17 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args, @@ -1110,13 +1125,17 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
1110 tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0]) 1125 tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
1111 | ((args[2] >> 16) & 0xffff)); 1126 | ((args[2] >> 16) & 0xffff));
1112 else { 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 tcg_out32 (s, AND | SAB (args[1], args[0], 0)); 1132 tcg_out32 (s, AND | SAB (args[1], args[0], 0));
1115 } 1133 }
1116 } 1134 }
1117 else 1135 else
1118 tcg_out32 (s, AND | SAB (args[1], args[0], args[2])); 1136 tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
1119 break; 1137 break;
  1138 + case INDEX_op_or_i64:
1120 case INDEX_op_or_i32: 1139 case INDEX_op_or_i32:
1121 if (const_args[2]) { 1140 if (const_args[2]) {
1122 if (args[2] & 0xffff) { 1141 if (args[2] & 0xffff) {
@@ -1134,6 +1153,7 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args, @@ -1134,6 +1153,7 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
1134 else 1153 else
1135 tcg_out32 (s, OR | SAB (args[1], args[0], args[2])); 1154 tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
1136 break; 1155 break;
  1156 + case INDEX_op_xor_i64:
1137 case INDEX_op_xor_i32: 1157 case INDEX_op_xor_i32:
1138 if (const_args[2]) { 1158 if (const_args[2]) {
1139 if ((args[2] & 0xffff) == args[2]) 1159 if ((args[2] & 0xffff) == args[2])
@@ -1143,7 +1163,10 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args, @@ -1143,7 +1163,10 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
1143 tcg_out32 (s, XORIS | RS (args[1]) | RA (args[0]) 1163 tcg_out32 (s, XORIS | RS (args[1]) | RA (args[0])
1144 | ((args[2] >> 16) & 0xffff)); 1164 | ((args[2] >> 16) & 0xffff));
1145 else { 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 tcg_out32 (s, XOR | SAB (args[1], args[0], 0)); 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,30 +1257,37 @@ static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
1234 break; 1257 break;
1235 1258
1236 case INDEX_op_add_i64: 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 break; 1264 break;
1239 case INDEX_op_sub_i64: 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 break; 1270 break;
1252 1271
1253 case INDEX_op_shl_i64: 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 break; 1277 break;
1256 case INDEX_op_shr_i64: 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 break; 1283 break;
1259 case INDEX_op_sar_i64: 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 break; 1291 break;
1262 1292
1263 case INDEX_op_mul_i64: 1293 case INDEX_op_mul_i64:
@@ -1389,15 +1419,15 @@ static const TCGTargetOpDef ppc_op_defs[] = { @@ -1389,15 +1419,15 @@ static const TCGTargetOpDef ppc_op_defs[] = {
1389 1419
1390 { INDEX_op_neg_i32, { "r", "r" } }, 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 { INDEX_op_mul_i64, { "r", "r", "r" } }, 1432 { INDEX_op_mul_i64, { "r", "r", "r" } },
1403 { INDEX_op_div_i64, { "r", "r", "r" } }, 1433 { INDEX_op_div_i64, { "r", "r", "r" } },