diff --git a/target-arm/helpers.h b/target-arm/helpers.h index f298efff4..4d07e0cea 100644 --- a/target-arm/helpers.h +++ b/target-arm/helpers.h @@ -151,7 +151,6 @@ DEF_HELPER_2(sbc_cc, i32, i32, i32) DEF_HELPER_2(shl, i32, i32, i32) DEF_HELPER_2(shr, i32, i32, i32) DEF_HELPER_2(sar, i32, i32, i32) -DEF_HELPER_2(ror, i32, i32, i32) DEF_HELPER_2(shl_cc, i32, i32, i32) DEF_HELPER_2(shr_cc, i32, i32, i32) DEF_HELPER_2(sar_cc, i32, i32, i32) diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 5ac631df0..9b1a0143d 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -379,14 +379,6 @@ uint32_t HELPER(sar)(uint32_t x, uint32_t i) return (int32_t)x >> shift; } -uint32_t HELPER(ror)(uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift == 0) - return x; - return (x >> shift) | (x << (32 - shift)); -} - uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i) { int shift = i & 0xff; diff --git a/target-arm/translate.c b/target-arm/translate.c index ace6c454f..57845662a 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -405,34 +405,9 @@ static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1) dead_tmp(tmp); } -/* T0 &= ~T1. Clobbers T1. */ -/* FIXME: Implement bic natively. */ -static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1) -{ - TCGv tmp = new_tmp(); - tcg_gen_not_i32(tmp, t1); - tcg_gen_and_i32(dest, t0, tmp); - dead_tmp(tmp); -} - /* FIXME: Implement this natively. */ #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1) -/* FIXME: Implement this natively. */ -static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i) -{ - TCGv tmp; - - if (i == 0) - return; - - tmp = new_tmp(); - tcg_gen_shri_i32(tmp, t1, i); - tcg_gen_shli_i32(t1, t1, 32 - i); - tcg_gen_or_i32(t0, t1, tmp); - dead_tmp(tmp); -} - static void shifter_out_im(TCGv var, int shift) { TCGv tmp = new_tmp(); @@ -484,7 +459,7 @@ static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) if (shift != 0) { if (flags) shifter_out_im(var, shift - 1); - tcg_gen_rori_i32(var, var, shift); break; + tcg_gen_rotri_i32(var, var, shift); break; } else { TCGv tmp = load_cpu_field(CF); if (flags) @@ -512,7 +487,8 @@ static inline void gen_arm_shift_reg(TCGv var, int shiftop, case 0: gen_helper_shl(var, var, shift); break; case 1: gen_helper_shr(var, var, shift); break; case 2: gen_helper_sar(var, var, shift); break; - case 3: gen_helper_ror(var, var, shift); break; + case 3: tcg_gen_andi_i32(shift, shift, 0x1f); + tcg_gen_rotr_i32(var, var, shift); break; } } dead_tmp(shift); @@ -1453,7 +1429,7 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) case ARM_IWMMXT_wCSSF: tmp = iwmmxt_load_creg(wrd); tmp2 = load_reg(s, rd); - tcg_gen_bic_i32(tmp, tmp, tmp2); + tcg_gen_andc_i32(tmp, tmp, tmp2); dead_tmp(tmp2); iwmmxt_store_creg(wrd, tmp); break; @@ -3931,7 +3907,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c) { tcg_gen_and_i32(t, t, c); - tcg_gen_bic_i32(f, f, c); + tcg_gen_andc_i32(f, f, c); tcg_gen_or_i32(dest, t, f); } @@ -4244,14 +4220,13 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) tcg_gen_and_i32(tmp, tmp, tmp2); break; case 1: /* BIC */ - tcg_gen_bic_i32(tmp, tmp, tmp2); + tcg_gen_andc_i32(tmp, tmp, tmp2); break; case 2: /* VORR */ tcg_gen_or_i32(tmp, tmp, tmp2); break; case 3: /* VORN */ - tcg_gen_not_i32(tmp2, tmp2); - tcg_gen_or_i32(tmp, tmp, tmp2); + tcg_gen_orc_i32(tmp, tmp, tmp2); break; case 4: /* VEOR */ tcg_gen_xor_i32(tmp, tmp, tmp2); @@ -6304,7 +6279,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) } break; case 0x0e: - tcg_gen_bic_i32(tmp, tmp, tmp2); + tcg_gen_andc_i32(tmp, tmp, tmp2); if (logic_cc) { gen_logic_CC(tmp); } @@ -6635,7 +6610,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) /* ??? In many cases it's not neccessary to do a rotate, a shift is sufficient. */ if (shift != 0) - tcg_gen_rori_i32(tmp, tmp, shift * 8); + tcg_gen_rotri_i32(tmp, tmp, shift * 8); op1 = (insn >> 20) & 7; switch (op1) { case 0: gen_sxtb16(tmp); break; @@ -7023,7 +6998,7 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCG logic_cc = conds; break; case 1: /* bic */ - tcg_gen_bic_i32(t0, t0, t1); + tcg_gen_andc_i32(t0, t0, t1); logic_cc = conds; break; case 2: /* orr */ @@ -7449,7 +7424,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) /* ??? In many cases it's not neccessary to do a rotate, a shift is sufficient. */ if (shift != 0) - tcg_gen_rori_i32(tmp, tmp, shift * 8); + tcg_gen_rotri_i32(tmp, tmp, shift * 8); op = (insn >> 20) & 7; switch (op) { case 0: gen_sxth(tmp); break; @@ -8346,7 +8321,8 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) break; case 0x7: /* ror */ if (s->condexec_mask) { - gen_helper_ror(tmp2, tmp2, tmp); + tcg_gen_andi_i32(tmp, tmp, 0x1f); + tcg_gen_rotr_i32(tmp2, tmp2, tmp); } else { gen_helper_ror_cc(tmp2, tmp2, tmp); gen_logic_CC(tmp2); @@ -8382,7 +8358,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) gen_logic_CC(tmp); break; case 0xe: /* bic */ - tcg_gen_bic_i32(tmp, tmp, tmp2); + tcg_gen_andc_i32(tmp, tmp, tmp2); if (!s->condexec_mask) gen_logic_CC(tmp); break;