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 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 460 /* T0 &= ~T1. Clobbers T1. */
467 461 /* FIXME: Implement bic natively. */
468 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 8105 break;
8112 8106 case 0x9: /* neg */
8113 8107 if (s->condexec_mask)
8114   - gen_op_subl_T0_T1();
  8108 + tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
8115 8109 else
8116 8110 gen_op_subl_T0_T1_cc();
8117 8111 break;
... ...
target-cris/translate.c
... ... @@ -318,7 +318,7 @@ static void t_gen_lz_i32(TCGv d, TCGv x)
318 318  
319 319 /* y = -(x >> 16) */
320 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 323 /* m = (y >> 16) & 16 */
324 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 753 t_gen_add_flag(cpu_T[0], 8); /* R_FLAG. */
754 754 break;
755 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 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 759 /* CRIS flag evaluation needs ~src. */
760 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 784 t_gen_asr(cpu_T[0], cpu_T[0], cpu_T[1]);
785 785 break;
786 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 788 /* Extended arithmetics. */
791 789 t_gen_subx_carry(cpu_T[0]);
792 790 break;
... ... @@ -829,10 +827,10 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
829 827 }
830 828 break;
831 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 831 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
834 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 834 /* CRIS flag evaluation needs ~src. */
837 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 1640 /* TODO: consider a branch free approach. */
1643 1641 l1 = gen_new_label();
1644 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 1644 gen_set_label(l1);
1647 1645 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1648 1646 return 2;
... ...
tcg/README
... ... @@ -203,6 +203,10 @@ t0=t1+t2
203 203  
204 204 t0=t1-t2
205 205  
  206 +* neg_i32/i64 t0, t1
  207 +
  208 +t0=-t1 (two's complement)
  209 +
206 210 * mul_i32/i64 t0, t1, t2
207 211  
208 212 t0=t1*t2
... ...
tcg/tcg-op.h
... ... @@ -1208,6 +1208,24 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
1208 1208  
1209 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 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 1459 #define tcg_gen_add_tl tcg_gen_add_i64
1442 1460 #define tcg_gen_addi_tl tcg_gen_addi_i64
1443 1461 #define tcg_gen_sub_tl tcg_gen_sub_i64
  1462 +#define tcg_gen_neg_tl tcg_gen_neg_i64
1444 1463 #define tcg_gen_subi_tl tcg_gen_subi_i64
1445 1464 #define tcg_gen_and_tl tcg_gen_and_i64
1446 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 1502 #define tcg_gen_add_tl tcg_gen_add_i32
1484 1503 #define tcg_gen_addi_tl tcg_gen_addi_i32
1485 1504 #define tcg_gen_sub_tl tcg_gen_sub_i32
  1505 +#define tcg_gen_neg_tl tcg_gen_neg_i32
1486 1506 #define tcg_gen_subi_tl tcg_gen_subi_i32
1487 1507 #define tcg_gen_and_tl tcg_gen_and_i32
1488 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 148 DEF2(bswap_i64, 1, 1, 0, 0)
149 149 #endif
150 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 158 /* QEMU specific */
153 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 1092 tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT | P_REXW, 0, args[0], 0);
1093 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 1102 case INDEX_op_qemu_ld8u:
1096 1103 tcg_out_qemu_ld(s, args, 0);
1097 1104 break;
... ... @@ -1247,6 +1254,9 @@ static const TCGTargetOpDef x86_64_op_defs[] = {
1247 1254 { INDEX_op_bswap_i32, { "r", "0" } },
1248 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 1260 { INDEX_op_qemu_ld8u, { "r", "L" } },
1251 1261 { INDEX_op_qemu_ld8s, { "r", "L" } },
1252 1262 { INDEX_op_qemu_ld16u, { "r", "L" } },
... ...
tcg/x86_64/tcg-target.h
... ... @@ -57,6 +57,8 @@ enum {
57 57 /* optional instructions */
58 58 #define TCG_TARGET_HAS_bswap_i32
59 59 #define TCG_TARGET_HAS_bswap_i64
  60 +#define TCG_TARGET_HAS_neg_i32
  61 +#define TCG_TARGET_HAS_neg_i64
60 62  
61 63 /* Note: must be synced with dyngen-exec.h */
62 64 #define TCG_AREG0 TCG_REG_R14
... ...