Commit 390efc54fb87e91ac9aeb47a7bc23806452b30cb

Authored by pbrook
1 parent 44cd42ee

Add TCG native negation op.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4426 c046a42c-6fe2-441c-8c8c-71466251a162
target-arm/translate.c
@@ -457,12 +457,6 @@ static inline void tcg_gen_not_i32(TCGv t0, TCGv t1) @@ -457,12 +457,6 @@ static inline void tcg_gen_not_i32(TCGv t0, TCGv t1)
457 tcg_gen_xori_i32(t0, t1, ~0); 457 tcg_gen_xori_i32(t0, t1, ~0);
458 } 458 }
459 459
460 -/* FIXME: Implement this natively. */  
461 -static inline void tcg_gen_neg_i64(TCGv dest, TCGv src)  
462 -{  
463 - tcg_gen_sub_i64(dest, tcg_const_i64(0), src);  
464 -}  
465 -  
466 /* T0 &= ~T1. Clobbers T1. */ 460 /* T0 &= ~T1. Clobbers T1. */
467 /* FIXME: Implement bic natively. */ 461 /* FIXME: Implement bic natively. */
468 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1) 462 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
@@ -8111,7 +8105,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -8111,7 +8105,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
8111 break; 8105 break;
8112 case 0x9: /* neg */ 8106 case 0x9: /* neg */
8113 if (s->condexec_mask) 8107 if (s->condexec_mask)
8114 - gen_op_subl_T0_T1(); 8108 + tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8115 else 8109 else
8116 gen_op_subl_T0_T1_cc(); 8110 gen_op_subl_T0_T1_cc();
8117 break; 8111 break;
target-cris/translate.c
@@ -318,7 +318,7 @@ static void t_gen_lz_i32(TCGv d, TCGv x) @@ -318,7 +318,7 @@ static void t_gen_lz_i32(TCGv d, TCGv x)
318 318
319 /* y = -(x >> 16) */ 319 /* y = -(x >> 16) */
320 tcg_gen_shri_i32(y, x, 16); 320 tcg_gen_shri_i32(y, x, 16);
321 - tcg_gen_sub_i32(y, tcg_const_i32(0), y); 321 + tcg_gen_neg_i32(y, y);
322 322
323 /* m = (y >> 16) & 16 */ 323 /* m = (y >> 16) & 16 */
324 tcg_gen_sari_i32(m, y, 16); 324 tcg_gen_sari_i32(m, y, 16);
@@ -753,9 +753,9 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -753,9 +753,9 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
753 t_gen_add_flag(cpu_T[0], 8); /* R_FLAG. */ 753 t_gen_add_flag(cpu_T[0], 8); /* R_FLAG. */
754 break; 754 break;
755 case CC_OP_SUB: 755 case CC_OP_SUB:
756 - tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]); 756 + tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
757 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 757 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
758 - tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]); 758 + tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
759 /* CRIS flag evaluation needs ~src. */ 759 /* CRIS flag evaluation needs ~src. */
760 tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1); 760 tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
761 761
@@ -784,9 +784,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -784,9 +784,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
784 t_gen_asr(cpu_T[0], cpu_T[0], cpu_T[1]); 784 t_gen_asr(cpu_T[0], cpu_T[0], cpu_T[1]);
785 break; 785 break;
786 case CC_OP_NEG: 786 case CC_OP_NEG:
787 - /* Hopefully the TCG backend recognizes this pattern  
788 - and makes a real neg out of it. */  
789 - tcg_gen_sub_tl(cpu_T[0], tcg_const_tl(0), cpu_T[1]); 787 + tcg_gen_neg_tl(cpu_T[0], cpu_T[1]);
790 /* Extended arithmetics. */ 788 /* Extended arithmetics. */
791 t_gen_subx_carry(cpu_T[0]); 789 t_gen_subx_carry(cpu_T[0]);
792 break; 790 break;
@@ -829,10 +827,10 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -829,10 +827,10 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
829 } 827 }
830 break; 828 break;
831 case CC_OP_CMP: 829 case CC_OP_CMP:
832 - tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]); 830 + tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
833 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 831 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
834 /* CRIS flag evaluation needs ~src. */ 832 /* CRIS flag evaluation needs ~src. */
835 - tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]); 833 + tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
836 /* CRIS flag evaluation needs ~src. */ 834 /* CRIS flag evaluation needs ~src. */
837 tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1); 835 tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
838 836
@@ -1642,7 +1640,7 @@ static unsigned int dec_abs_r(DisasContext *dc) @@ -1642,7 +1640,7 @@ static unsigned int dec_abs_r(DisasContext *dc)
1642 /* TODO: consider a branch free approach. */ 1640 /* TODO: consider a branch free approach. */
1643 l1 = gen_new_label(); 1641 l1 = gen_new_label();
1644 tcg_gen_brcond_tl(TCG_COND_GE, cpu_T[1], tcg_const_tl(0), l1); 1642 tcg_gen_brcond_tl(TCG_COND_GE, cpu_T[1], tcg_const_tl(0), l1);
1645 - tcg_gen_sub_tl(cpu_T[1], tcg_const_tl(0), cpu_T[1]); 1643 + tcg_gen_neg_tl(cpu_T[1], cpu_T[1]);
1646 gen_set_label(l1); 1644 gen_set_label(l1);
1647 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); 1645 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1648 return 2; 1646 return 2;
tcg/README
@@ -203,6 +203,10 @@ t0=t1+t2 @@ -203,6 +203,10 @@ t0=t1+t2
203 203
204 t0=t1-t2 204 t0=t1-t2
205 205
  206 +* neg_i32/i64 t0, t1
  207 +
  208 +t0=-t1 (two's complement)
  209 +
206 * mul_i32/i64 t0, t1, t2 210 * mul_i32/i64 t0, t1, t2
207 211
208 t0=t1*t2 212 t0=t1*t2
tcg/tcg-op.h
@@ -1208,6 +1208,24 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg) @@ -1208,6 +1208,24 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
1208 1208
1209 #endif 1209 #endif
1210 1210
  1211 +static inline void tcg_gen_neg_i32(TCGv ret, TCGv arg)
  1212 +{
  1213 +#ifdef TCG_TARGET_HAS_neg_i32
  1214 + tcg_gen_op2(INDEX_op_neg_i32, ret, arg);
  1215 +#else
  1216 + tcg_gen_sub_i32(ret, tcg_const_i32(0), arg);
  1217 +#endif
  1218 +}
  1219 +
  1220 +static inline void tcg_gen_neg_i64(TCGv ret, TCGv arg)
  1221 +{
  1222 +#ifdef TCG_TARGET_HAS_neg_i64
  1223 + tcg_gen_op2(INDEX_op_neg_i64, ret, arg);
  1224 +#else
  1225 + tcg_gen_sub_i64(ret, tcg_const_i64(0), arg);
  1226 +#endif
  1227 +}
  1228 +
1211 1229
1212 static inline void tcg_gen_discard_i32(TCGv arg) 1230 static inline void tcg_gen_discard_i32(TCGv arg)
1213 { 1231 {
@@ -1441,6 +1459,7 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index) @@ -1441,6 +1459,7 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
1441 #define tcg_gen_add_tl tcg_gen_add_i64 1459 #define tcg_gen_add_tl tcg_gen_add_i64
1442 #define tcg_gen_addi_tl tcg_gen_addi_i64 1460 #define tcg_gen_addi_tl tcg_gen_addi_i64
1443 #define tcg_gen_sub_tl tcg_gen_sub_i64 1461 #define tcg_gen_sub_tl tcg_gen_sub_i64
  1462 +#define tcg_gen_neg_tl tcg_gen_neg_i64
1444 #define tcg_gen_subi_tl tcg_gen_subi_i64 1463 #define tcg_gen_subi_tl tcg_gen_subi_i64
1445 #define tcg_gen_and_tl tcg_gen_and_i64 1464 #define tcg_gen_and_tl tcg_gen_and_i64
1446 #define tcg_gen_andi_tl tcg_gen_andi_i64 1465 #define tcg_gen_andi_tl tcg_gen_andi_i64
@@ -1483,6 +1502,7 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index) @@ -1483,6 +1502,7 @@ static inline void tcg_gen_qemu_st64(TCGv arg, TCGv addr, int mem_index)
1483 #define tcg_gen_add_tl tcg_gen_add_i32 1502 #define tcg_gen_add_tl tcg_gen_add_i32
1484 #define tcg_gen_addi_tl tcg_gen_addi_i32 1503 #define tcg_gen_addi_tl tcg_gen_addi_i32
1485 #define tcg_gen_sub_tl tcg_gen_sub_i32 1504 #define tcg_gen_sub_tl tcg_gen_sub_i32
  1505 +#define tcg_gen_neg_tl tcg_gen_neg_i32
1486 #define tcg_gen_subi_tl tcg_gen_subi_i32 1506 #define tcg_gen_subi_tl tcg_gen_subi_i32
1487 #define tcg_gen_and_tl tcg_gen_and_i32 1507 #define tcg_gen_and_tl tcg_gen_and_i32
1488 #define tcg_gen_andi_tl tcg_gen_andi_i32 1508 #define tcg_gen_andi_tl tcg_gen_andi_i32
tcg/tcg-opc.h
@@ -148,6 +148,12 @@ DEF2(ext32s_i64, 1, 1, 0, 0) @@ -148,6 +148,12 @@ DEF2(ext32s_i64, 1, 1, 0, 0)
148 DEF2(bswap_i64, 1, 1, 0, 0) 148 DEF2(bswap_i64, 1, 1, 0, 0)
149 #endif 149 #endif
150 #endif 150 #endif
  151 +#ifdef TCG_TARGET_HAS_neg_i32
  152 +DEF2(neg_i32, 1, 1, 0, 0)
  153 +#endif
  154 +#ifdef TCG_TARGET_HAS_neg_i64
  155 +DEF2(neg_i64, 1, 1, 0, 0)
  156 +#endif
151 157
152 /* QEMU specific */ 158 /* QEMU specific */
153 DEF2(exit_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) 159 DEF2(exit_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
tcg/x86_64/tcg-target.c
@@ -1092,6 +1092,13 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, @@ -1092,6 +1092,13 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
1092 tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT | P_REXW, 0, args[0], 0); 1092 tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT | P_REXW, 0, args[0], 0);
1093 break; 1093 break;
1094 1094
  1095 + case INDEX_op_neg_i32:
  1096 + tcg_out_modrm(s, 0xf7, 3, args[0]);
  1097 + break;
  1098 + case INDEX_op_neg_i64:
  1099 + tcg_out_modrm(s, 0xf7 | P_REXW, 3, args[0]);
  1100 + break;
  1101 +
1095 case INDEX_op_qemu_ld8u: 1102 case INDEX_op_qemu_ld8u:
1096 tcg_out_qemu_ld(s, args, 0); 1103 tcg_out_qemu_ld(s, args, 0);
1097 break; 1104 break;
@@ -1247,6 +1254,9 @@ static const TCGTargetOpDef x86_64_op_defs[] = { @@ -1247,6 +1254,9 @@ static const TCGTargetOpDef x86_64_op_defs[] = {
1247 { INDEX_op_bswap_i32, { "r", "0" } }, 1254 { INDEX_op_bswap_i32, { "r", "0" } },
1248 { INDEX_op_bswap_i64, { "r", "0" } }, 1255 { INDEX_op_bswap_i64, { "r", "0" } },
1249 1256
  1257 + { INDEX_op_neg_i32, { "r", "0" } },
  1258 + { INDEX_op_neg_i64, { "r", "0" } },
  1259 +
1250 { INDEX_op_qemu_ld8u, { "r", "L" } }, 1260 { INDEX_op_qemu_ld8u, { "r", "L" } },
1251 { INDEX_op_qemu_ld8s, { "r", "L" } }, 1261 { INDEX_op_qemu_ld8s, { "r", "L" } },
1252 { INDEX_op_qemu_ld16u, { "r", "L" } }, 1262 { INDEX_op_qemu_ld16u, { "r", "L" } },
tcg/x86_64/tcg-target.h
@@ -57,6 +57,8 @@ enum { @@ -57,6 +57,8 @@ enum {
57 /* optional instructions */ 57 /* optional instructions */
58 #define TCG_TARGET_HAS_bswap_i32 58 #define TCG_TARGET_HAS_bswap_i32
59 #define TCG_TARGET_HAS_bswap_i64 59 #define TCG_TARGET_HAS_bswap_i64
  60 +#define TCG_TARGET_HAS_neg_i32
  61 +#define TCG_TARGET_HAS_neg_i64
60 62
61 /* Note: must be synced with dyngen-exec.h */ 63 /* Note: must be synced with dyngen-exec.h */
62 #define TCG_AREG0 TCG_REG_R14 64 #define TCG_AREG0 TCG_REG_R14