Patchwork [10/12] target-arm: replace tcg_gen_rori_i32 by tcg_gen_rotri_i32

login
register
mail settings
Submitter Aurelien Jarno
Date Oct. 23, 2009, 3:25 p.m.
Message ID <20091023152546.GA13165@volta.aurel32.net>
Download mbox | patch
Permalink /patch/36786/
State New
Headers show

Comments

Aurelien Jarno - Oct. 23, 2009, 3:25 p.m.
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>
Laurent Desnogues - Oct. 23, 2009, 3:43 p.m.
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
Juha.Riihimaki@nokia.com - Oct. 24, 2009, 6:17 a.m.
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

Patch

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;