Patchwork [02/14] i386: introduce gen_ext_tl

login
register
mail settings
Submitter Paolo Bonzini
Date Oct. 6, 2012, 12:30 p.m.
Message ID <1349526621-13939-3-git-send-email-pbonzini@redhat.com>
Download mbox | patch
Permalink /patch/189699/
State New
Headers show

Comments

Paolo Bonzini - Oct. 6, 2012, 12:30 p.m.
Introduce a function that abstracts extracting an 8, 16, 32 or 64-bit value
with or without sign, generalizing gen_extu and gen_exts.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-i386/translate.c | 146 ++++++++++++------------------------------------
 1 file modificato, 37 inserzioni(+), 109 rimozioni(-)
Blue Swirl - Oct. 7, 2012, 6:53 p.m.
On Sat, Oct 6, 2012 at 12:30 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Introduce a function that abstracts extracting an 8, 16, 32 or 64-bit value
> with or without sign, generalizing gen_extu and gen_exts.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Blue Swirl <blauwirbel@gmail.com>

> ---
>  target-i386/translate.c | 146 ++++++++++++------------------------------------
>  1 file modificato, 37 inserzioni(+), 109 rimozioni(-)
>
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index e2ef410..671303d 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -659,38 +659,45 @@ static inline void gen_op_movl_T0_Dshift(int ot)
>      tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
>  };
>
> -static void gen_extu(int ot, TCGv reg)
> +static inline TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign)
>  {
> -    switch(ot) {
> +    switch(size) {
>      case OT_BYTE:
> -        tcg_gen_ext8u_tl(reg, reg);
> -        break;
> +        if (sign) {
> +            tcg_gen_ext8s_tl(dst, src);
> +        } else {
> +            tcg_gen_ext8u_tl(dst, src);
> +        }
> +        return dst;
>      case OT_WORD:
> -        tcg_gen_ext16u_tl(reg, reg);
> -        break;
> +        if (sign) {
> +            tcg_gen_ext16s_tl(dst, src);
> +        } else {
> +            tcg_gen_ext16u_tl(dst, src);
> +        }
> +        return dst;
> +#ifdef TARGET_X86_64
>      case OT_LONG:
> -        tcg_gen_ext32u_tl(reg, reg);
> -        break;
> +        if (sign) {
> +            tcg_gen_ext32s_tl(dst, src);
> +        } else {
> +            tcg_gen_ext32u_tl(dst, src);
> +        }
> +        return dst;
> +#endif
>      default:
> -        break;
> +        return src;
>      }
>  }
>
> +static void gen_extu(int ot, TCGv reg)
> +{
> +    gen_ext_tl(reg, reg, ot, false);
> +}
> +
>  static void gen_exts(int ot, TCGv reg)
>  {
> -    switch(ot) {
> -    case OT_BYTE:
> -        tcg_gen_ext8s_tl(reg, reg);
> -        break;
> -    case OT_WORD:
> -        tcg_gen_ext16s_tl(reg, reg);
> -        break;
> -    case OT_LONG:
> -        tcg_gen_ext32s_tl(reg, reg);
> -        break;
> -    default:
> -        break;
> -    }
> +    gen_ext_tl(reg, reg, ot, true);
>  }
>
>  static inline void gen_op_jnz_ecx(int size, int label1)
> @@ -956,54 +963,15 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
>          switch(jcc_op) {
>          case JCC_Z:
>          fast_jcc_z:
> -            switch(size) {
> -            case 0:
> -                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xff);
> -                t0 = cpu_tmp0;
> -                break;
> -            case 1:
> -                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffff);
> -                t0 = cpu_tmp0;
> -                break;
> -#ifdef TARGET_X86_64
> -            case 2:
> -                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffffffff);
> -                t0 = cpu_tmp0;
> -                break;
> -#endif
> -            default:
> -                t0 = cpu_cc_dst;
> -                break;
> -            }
> +            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, false);
>              tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1);
>              break;
>          case JCC_S:
>          fast_jcc_s:
> -            switch(size) {
> -            case 0:
> -                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80);
> -                tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0,
> -                                   0, l1);
> -                break;
> -            case 1:
> -                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x8000);
> -                tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0,
> -                                   0, l1);
> -                break;
> -#ifdef TARGET_X86_64
> -            case 2:
> -                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80000000);
> -                tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0,
> -                                   0, l1);
> -                break;
> -#endif
> -            default:
> -                tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, cpu_cc_dst,
> -                                   0, l1);
> -                break;
> -            }
> +            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, true);
> +            tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, t0, 0, l1);
>              break;
> -
> +
>          case JCC_B:
>              cond = inv ? TCG_COND_GEU : TCG_COND_LTU;
>              goto fast_jcc_b;
> @@ -1011,28 +979,8 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
>              cond = inv ? TCG_COND_GTU : TCG_COND_LEU;
>          fast_jcc_b:
>              tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
> -            switch(size) {
> -            case 0:
> -                t0 = cpu_tmp0;
> -                tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xff);
> -                tcg_gen_andi_tl(t0, cpu_cc_src, 0xff);
> -                break;
> -            case 1:
> -                t0 = cpu_tmp0;
> -                tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffff);
> -                tcg_gen_andi_tl(t0, cpu_cc_src, 0xffff);
> -                break;
> -#ifdef TARGET_X86_64
> -            case 2:
> -                t0 = cpu_tmp0;
> -                tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffffffff);
> -                tcg_gen_andi_tl(t0, cpu_cc_src, 0xffffffff);
> -                break;
> -#endif
> -            default:
> -                t0 = cpu_cc_src;
> -                break;
> -            }
> +            gen_extu(size, cpu_tmp4);
> +            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
>              tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
>              break;
>
> @@ -1043,28 +991,8 @@ static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
>              cond = inv ? TCG_COND_GT : TCG_COND_LE;
>          fast_jcc_l:
>              tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
> -            switch(size) {
> -            case 0:
> -                t0 = cpu_tmp0;
> -                tcg_gen_ext8s_tl(cpu_tmp4, cpu_tmp4);
> -                tcg_gen_ext8s_tl(t0, cpu_cc_src);
> -                break;
> -            case 1:
> -                t0 = cpu_tmp0;
> -                tcg_gen_ext16s_tl(cpu_tmp4, cpu_tmp4);
> -                tcg_gen_ext16s_tl(t0, cpu_cc_src);
> -                break;
> -#ifdef TARGET_X86_64
> -            case 2:
> -                t0 = cpu_tmp0;
> -                tcg_gen_ext32s_tl(cpu_tmp4, cpu_tmp4);
> -                tcg_gen_ext32s_tl(t0, cpu_cc_src);
> -                break;
> -#endif
> -            default:
> -                t0 = cpu_cc_src;
> -                break;
> -            }
> +            gen_exts(size, cpu_tmp4);
> +            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
>              tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
>              break;
>
> --
> 1.7.12.1
>
>
>
Richard Henderson - Oct. 9, 2012, 6:58 p.m.
On 10/06/2012 05:30 AM, Paolo Bonzini wrote:
> Introduce a function that abstracts extracting an 8, 16, 32 or 64-bit value
> with or without sign, generalizing gen_extu and gen_exts.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

Patch

diff --git a/target-i386/translate.c b/target-i386/translate.c
index e2ef410..671303d 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -659,38 +659,45 @@  static inline void gen_op_movl_T0_Dshift(int ot)
     tcg_gen_shli_tl(cpu_T[0], cpu_T[0], ot);
 };
 
-static void gen_extu(int ot, TCGv reg)
+static inline TCGv gen_ext_tl(TCGv dst, TCGv src, int size, bool sign)
 {
-    switch(ot) {
+    switch(size) {
     case OT_BYTE:
-        tcg_gen_ext8u_tl(reg, reg);
-        break;
+        if (sign) {
+            tcg_gen_ext8s_tl(dst, src);
+        } else {
+            tcg_gen_ext8u_tl(dst, src);
+        }
+        return dst;
     case OT_WORD:
-        tcg_gen_ext16u_tl(reg, reg);
-        break;
+        if (sign) {
+            tcg_gen_ext16s_tl(dst, src);
+        } else {
+            tcg_gen_ext16u_tl(dst, src);
+        }
+        return dst;
+#ifdef TARGET_X86_64
     case OT_LONG:
-        tcg_gen_ext32u_tl(reg, reg);
-        break;
+        if (sign) {
+            tcg_gen_ext32s_tl(dst, src);
+        } else {
+            tcg_gen_ext32u_tl(dst, src);
+        }
+        return dst;
+#endif
     default:
-        break;
+        return src;
     }
 }
 
+static void gen_extu(int ot, TCGv reg)
+{
+    gen_ext_tl(reg, reg, ot, false);
+}
+
 static void gen_exts(int ot, TCGv reg)
 {
-    switch(ot) {
-    case OT_BYTE:
-        tcg_gen_ext8s_tl(reg, reg);
-        break;
-    case OT_WORD:
-        tcg_gen_ext16s_tl(reg, reg);
-        break;
-    case OT_LONG:
-        tcg_gen_ext32s_tl(reg, reg);
-        break;
-    default:
-        break;
-    }
+    gen_ext_tl(reg, reg, ot, true);
 }
 
 static inline void gen_op_jnz_ecx(int size, int label1)
@@ -956,54 +963,15 @@  static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
         switch(jcc_op) {
         case JCC_Z:
         fast_jcc_z:
-            switch(size) {
-            case 0:
-                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xff);
-                t0 = cpu_tmp0;
-                break;
-            case 1:
-                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffff);
-                t0 = cpu_tmp0;
-                break;
-#ifdef TARGET_X86_64
-            case 2:
-                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0xffffffff);
-                t0 = cpu_tmp0;
-                break;
-#endif
-            default:
-                t0 = cpu_cc_dst;
-                break;
-            }
+            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, false);
             tcg_gen_brcondi_tl(inv ? TCG_COND_NE : TCG_COND_EQ, t0, 0, l1);
             break;
         case JCC_S:
         fast_jcc_s:
-            switch(size) {
-            case 0:
-                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80);
-                tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
-                                   0, l1);
-                break;
-            case 1:
-                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x8000);
-                tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
-                                   0, l1);
-                break;
-#ifdef TARGET_X86_64
-            case 2:
-                tcg_gen_andi_tl(cpu_tmp0, cpu_cc_dst, 0x80000000);
-                tcg_gen_brcondi_tl(inv ? TCG_COND_EQ : TCG_COND_NE, cpu_tmp0, 
-                                   0, l1);
-                break;
-#endif
-            default:
-                tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, cpu_cc_dst, 
-                                   0, l1);
-                break;
-            }
+            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_dst, size, true);
+            tcg_gen_brcondi_tl(inv ? TCG_COND_GE : TCG_COND_LT, t0, 0, l1);
             break;
-            
+
         case JCC_B:
             cond = inv ? TCG_COND_GEU : TCG_COND_LTU;
             goto fast_jcc_b;
@@ -1011,28 +979,8 @@  static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
             cond = inv ? TCG_COND_GTU : TCG_COND_LEU;
         fast_jcc_b:
             tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
-            switch(size) {
-            case 0:
-                t0 = cpu_tmp0;
-                tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xff);
-                tcg_gen_andi_tl(t0, cpu_cc_src, 0xff);
-                break;
-            case 1:
-                t0 = cpu_tmp0;
-                tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffff);
-                tcg_gen_andi_tl(t0, cpu_cc_src, 0xffff);
-                break;
-#ifdef TARGET_X86_64
-            case 2:
-                t0 = cpu_tmp0;
-                tcg_gen_andi_tl(cpu_tmp4, cpu_tmp4, 0xffffffff);
-                tcg_gen_andi_tl(t0, cpu_cc_src, 0xffffffff);
-                break;
-#endif
-            default:
-                t0 = cpu_cc_src;
-                break;
-            }
+            gen_extu(size, cpu_tmp4);
+            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);
             tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
             break;
             
@@ -1043,28 +991,8 @@  static inline void gen_jcc1(DisasContext *s, int cc_op, int b, int l1)
             cond = inv ? TCG_COND_GT : TCG_COND_LE;
         fast_jcc_l:
             tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);
-            switch(size) {
-            case 0:
-                t0 = cpu_tmp0;
-                tcg_gen_ext8s_tl(cpu_tmp4, cpu_tmp4);
-                tcg_gen_ext8s_tl(t0, cpu_cc_src);
-                break;
-            case 1:
-                t0 = cpu_tmp0;
-                tcg_gen_ext16s_tl(cpu_tmp4, cpu_tmp4);
-                tcg_gen_ext16s_tl(t0, cpu_cc_src);
-                break;
-#ifdef TARGET_X86_64
-            case 2:
-                t0 = cpu_tmp0;
-                tcg_gen_ext32s_tl(cpu_tmp4, cpu_tmp4);
-                tcg_gen_ext32s_tl(t0, cpu_cc_src);
-                break;
-#endif
-            default:
-                t0 = cpu_cc_src;
-                break;
-            }
+            gen_exts(size, cpu_tmp4);
+            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);
             tcg_gen_brcond_tl(cond, cpu_tmp4, t0, l1);
             break;