Message ID | 20091023152546.GA13165@volta.aurel32.net |
---|---|
State | New |
Headers | show |
On Fri, Oct 23, 2009 at 5:25 PM, Aurelien Jarno <aurelien@aurel32.net> wrote: > On Wed, Oct 21, 2009 at 12:18:08PM +0200, Juha.Riihimaki@nokia.com wrote: >> Use native rotation if possible instead of a simulated one. > > I have another patch in my local tree that handle more cases: > > commit 04df13497befdb79c778d82d0901d290d164d250 > Author: Aurelien Jarno <aurelien@aurel32.net> > Date: Thu Oct 15 16:45:14 2009 +0200 > > target-arm: use native tcg-ops for ror/bic/vorn > > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> Acked-by: Laurent Desnogues <laurent.desnogues@gmail.com> > diff --git a/target-arm/helpers.h b/target-arm/helpers.h > index f298eff..4d07e0c 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 5ac631d..9b1a014 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 9d13d42..2721a22 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); > @@ -1442,7 +1418,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; > @@ -3899,7 +3875,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); > } > > @@ -4212,14 +4188,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); > @@ -6274,7 +6249,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); > } > @@ -6605,7 +6580,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; > @@ -6993,7 +6968,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 */ > @@ -7419,7 +7394,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; > @@ -8316,7 +8291,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); > @@ -8352,7 +8328,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; > > -- > Aurelien Jarno GPG: 1024D/F1BCDB73 > aurelien@aurel32.net http://www.aurel32.net > > > Laurent
On Oct 23, 2009, at 18:25, ext Aurelien Jarno wrote: > On Wed, Oct 21, 2009 at 12:18:08PM +0200, Juha.Riihimaki@nokia.com > wrote: >> Use native rotation if possible instead of a simulated one. > > I have another patch in my local tree that handle more cases: Great, I'll drop it from my patch series then. Cheers, Juha
diff --git a/target-arm/helpers.h b/target-arm/helpers.h index f298eff..4d07e0c 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 5ac631d..9b1a014 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 9d13d42..2721a22 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); @@ -1442,7 +1418,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; @@ -3899,7 +3875,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); } @@ -4212,14 +4188,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); @@ -6274,7 +6249,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); } @@ -6605,7 +6580,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; @@ -6993,7 +6968,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 */ @@ -7419,7 +7394,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; @@ -8316,7 +8291,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); @@ -8352,7 +8328,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;