diff mbox

[v2,1/2] target-mips: Use movcond in movci and movcf*

Message ID 1441234214-25173-2-git-send-email-rth@twiddle.net
State New
Headers show

Commit Message

Richard Henderson Sept. 2, 2015, 10:50 p.m. UTC
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-mips/translate.c | 255 ++++++++++++++++++++++++------------------------
 1 file changed, 127 insertions(+), 128 deletions(-)

Comments

Leon Alrae Sept. 3, 2015, 5:01 p.m. UTC | #1
On 02/09/2015 23:50, Richard Henderson wrote:
> @@ -8821,102 +8840,126 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
>      tcg_temp_free(t0);
>  }
>  
> -static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
> +static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
>  {
> -    TCGLabel *l1;
>      TCGCond cond;
> -    TCGv_i32 t0;
> +    TCGv t0, ts, zero;
>  
>      if (rd == 0) {
>          /* Treat as NOP. */
>          return;
>      }
>  
> -    if (tf)
> +    if (tf) {
>          cond = TCG_COND_EQ;
> -    else
> -        cond = TCG_COND_NE;
> -
> -    l1 = gen_new_label();
> -    t0 = tcg_temp_new_i32();
> -    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
> -    tcg_gen_brcondi_i32(cond, t0, 0, l1);
> -    tcg_temp_free_i32(t0);
> -    if (rs == 0) {
> -        tcg_gen_movi_tl(cpu_gpr[rd], 0);
>      } else {
> -        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
> +        cond = TCG_COND_NE;
>      }
> -    gen_set_label(l1);
> +
> +    t0 = tcg_temp_new();
> +    tcg_gen_extu_i32_tl(t0, fpu_fcr31);
> +    tcg_gen_andi_tl(t0, t0, 1 << get_fp_bit(cc));
> +
> +    zero = tcg_const_tl(0);
> +    ts = rs ? cpu_gpr[rs] : zero;
> +    tcg_gen_movcond_tl(cond, cpu_gpr[rd], t0, zero, ts, cpu_gpr[rd]);

MOVF and MOVT seem to do the opposite now, ts and cpu_gpr[rd] should be
swapped I think:

tcg_gen_movcond_tl(cond, cpu_gpr[rd], t0, zero, cpu_gpr[rd], ts);

Thanks,
Leon
Richard Henderson Sept. 4, 2015, 2:32 p.m. UTC | #2
On 09/03/2015 10:01 AM, Leon Alrae wrote:
> On 02/09/2015 23:50, Richard Henderson wrote:
>> @@ -8821,102 +8840,126 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
>>       tcg_temp_free(t0);
>>   }
>>
>> -static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
>> +static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
>>   {
>> -    TCGLabel *l1;
>>       TCGCond cond;
>> -    TCGv_i32 t0;
>> +    TCGv t0, ts, zero;
>>
>>       if (rd == 0) {
>>           /* Treat as NOP. */
>>           return;
>>       }
>>
>> -    if (tf)
>> +    if (tf) {
>>           cond = TCG_COND_EQ;
>> -    else
>> -        cond = TCG_COND_NE;
>> -
>> -    l1 = gen_new_label();
>> -    t0 = tcg_temp_new_i32();
>> -    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
>> -    tcg_gen_brcondi_i32(cond, t0, 0, l1);
>> -    tcg_temp_free_i32(t0);
>> -    if (rs == 0) {
>> -        tcg_gen_movi_tl(cpu_gpr[rd], 0);
>>       } else {
>> -        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
>> +        cond = TCG_COND_NE;
>>       }
>> -    gen_set_label(l1);
>> +
>> +    t0 = tcg_temp_new();
>> +    tcg_gen_extu_i32_tl(t0, fpu_fcr31);
>> +    tcg_gen_andi_tl(t0, t0, 1 << get_fp_bit(cc));
>> +
>> +    zero = tcg_const_tl(0);
>> +    ts = rs ? cpu_gpr[rs] : zero;
>> +    tcg_gen_movcond_tl(cond, cpu_gpr[rd], t0, zero, ts, cpu_gpr[rd]);
>
> MOVF and MOVT seem to do the opposite now, ts and cpu_gpr[rd] should be
> swapped I think:
>
> tcg_gen_movcond_tl(cond, cpu_gpr[rd], t0, zero, cpu_gpr[rd], ts);

Whoops.  I guess my test kernel isn't built to use that.
Anyway, yes, either that or swap the setting of cond above, which is probably a 
more natural way to write the condition.


r~
diff mbox

Patch

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 93cb4f2..e8e6f53 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1632,6 +1632,14 @@  static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
 }
 
+static void gen_load_fpr32_tl(DisasContext *ctx, TCGv t, int reg)
+{
+    if (ctx->hflags & MIPS_HFLAG_FRE) {
+        generate_exception(ctx, EXCP_RI);
+    }
+    tcg_gen_trunc_i64_tl(t, fpu_f64[reg]);
+}
+
 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
 {
     TCGv_i64 t64;
@@ -1644,6 +1652,17 @@  static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
     tcg_temp_free_i64(t64);
 }
 
+static void gen_store_fpr32_tl(DisasContext *ctx, TCGv t, int reg)
+{
+    TCGv_i64 t64 = tcg_temp_new_i64();
+    if (ctx->hflags & MIPS_HFLAG_FRE) {
+        generate_exception(ctx, EXCP_RI);
+    }
+    tcg_gen_extu_tl_i64(t64, t);
+    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
+    tcg_temp_free_i64(t64);
+}
+
 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
 {
     if (ctx->hflags & MIPS_HFLAG_F64) {
@@ -8821,102 +8840,126 @@  static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
     tcg_temp_free(t0);
 }
 
-static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
+static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
 {
-    TCGLabel *l1;
     TCGCond cond;
-    TCGv_i32 t0;
+    TCGv t0, ts, zero;
 
     if (rd == 0) {
         /* Treat as NOP. */
         return;
     }
 
-    if (tf)
+    if (tf) {
         cond = TCG_COND_EQ;
-    else
-        cond = TCG_COND_NE;
-
-    l1 = gen_new_label();
-    t0 = tcg_temp_new_i32();
-    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
-    tcg_gen_brcondi_i32(cond, t0, 0, l1);
-    tcg_temp_free_i32(t0);
-    if (rs == 0) {
-        tcg_gen_movi_tl(cpu_gpr[rd], 0);
     } else {
-        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
+        cond = TCG_COND_NE;
     }
-    gen_set_label(l1);
+
+    t0 = tcg_temp_new();
+    tcg_gen_extu_i32_tl(t0, fpu_fcr31);
+    tcg_gen_andi_tl(t0, t0, 1 << get_fp_bit(cc));
+
+    zero = tcg_const_tl(0);
+    ts = rs ? cpu_gpr[rs] : zero;
+    tcg_gen_movcond_tl(cond, cpu_gpr[rd], t0, zero, ts, cpu_gpr[rd]);
+    tcg_temp_free(zero);
+    tcg_temp_free(t0);
 }
 
-static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
-                               int tf)
+static void gen_mov_s_cond(DisasContext *ctx, int fs, int fd,
+                           TCGv cc, TCGCond cond)
 {
-    int cond;
-    TCGv_i32 t0 = tcg_temp_new_i32();
-    TCGLabel *l1 = gen_new_label();
+    TCGv td = tcg_temp_new();
+    TCGv ts = tcg_temp_new();
+    TCGv zero = tcg_const_tl(0);
+
+    gen_load_fpr32_tl(ctx, ts, fs);
+    gen_load_fpr32_tl(ctx, td, fd);
+    tcg_gen_movcond_tl(cond, td, cc, zero, ts, td);
+    gen_store_fpr32_tl(ctx, td, fd);
+
+    tcg_temp_free(ts);
+    tcg_temp_free(td);
+    tcg_temp_free(zero);
+}
 
-    if (tf)
-        cond = TCG_COND_EQ;
-    else
-        cond = TCG_COND_NE;
+static void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc, int tf)
+{
+    TCGCond cond = tf ? TCG_COND_EQ : TCG_COND_NE;
+    TCGv_i32 tc = tcg_temp_new_i32();
+    TCGv_i32 td = tcg_temp_new_i32();
+    TCGv_i32 ts = tcg_temp_new_i32();
+    TCGv_i32 zero = tcg_const_i32(0);
+
+    tcg_gen_andi_i32(tc, fpu_fcr31, 1 << get_fp_bit(cc));
+    gen_load_fpr32(ctx, ts, fs);
+    gen_load_fpr32(ctx, td, fd);
+    tcg_gen_movcond_i32(cond, td, tc, zero, ts, td);
+    gen_store_fpr32(ctx, td, fd);
+
+    tcg_temp_free_i32(tc);
+    tcg_temp_free_i32(ts);
+    tcg_temp_free_i32(td);
+    tcg_temp_free_i32(zero);
+}
 
-    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
-    tcg_gen_brcondi_i32(cond, t0, 0, l1);
-    gen_load_fpr32(ctx, t0, fs);
-    gen_store_fpr32(ctx, t0, fd);
-    gen_set_label(l1);
-    tcg_temp_free_i32(t0);
+static void gen_mov_d_cond(DisasContext *ctx, int fs, int fd,
+                           TCGv cc, TCGCond cond)
+{
+    TCGv_i64 t0 = tcg_temp_new_i64();
+    TCGv_i64 td = tcg_temp_new_i64();
+    TCGv_i64 ts = tcg_temp_new_i64();
+    TCGv_i64 zero = tcg_const_i64(0);
+
+    tcg_gen_extu_tl_i64(t0, cc);
+    gen_load_fpr64(ctx, ts, fs);
+    gen_load_fpr64(ctx, td, fs);
+    tcg_gen_movcond_i64(cond, td, t0, zero, ts, td);
+    gen_store_fpr64(ctx, td, fd);
+
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(ts);
+    tcg_temp_free_i64(td);
+    tcg_temp_free_i64(zero);
 }
 
-static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
+static void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc, int tf)
 {
-    int cond;
-    TCGv_i32 t0 = tcg_temp_new_i32();
-    TCGv_i64 fp0;
-    TCGLabel *l1 = gen_new_label();
+    TCGCond cond = tf ? TCG_COND_EQ : TCG_COND_NE;
+    TCGv t0 = tcg_temp_new();
 
-    if (tf)
-        cond = TCG_COND_EQ;
-    else
-        cond = TCG_COND_NE;
+    tcg_gen_extu_i32_tl(t0, fpu_fcr31);
+    tcg_gen_andi_tl(t0, t0, 1 << get_fp_bit(cc));
+    gen_mov_d_cond(ctx, fs, fd, t0, cond);
 
-    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
-    tcg_gen_brcondi_i32(cond, t0, 0, l1);
-    tcg_temp_free_i32(t0);
-    fp0 = tcg_temp_new_i64();
-    gen_load_fpr64(ctx, fp0, fs);
-    gen_store_fpr64(ctx, fp0, fd);
-    tcg_temp_free_i64(fp0);
-    gen_set_label(l1);
+    tcg_temp_free(t0);
 }
 
-static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
-                                int cc, int tf)
+static void gen_movcf_ps(DisasContext *ctx, int fs, int fd, int cc, int tf)
 {
-    int cond;
+    TCGCond cond = tf ? TCG_COND_EQ : TCG_COND_NE;
     TCGv_i32 t0 = tcg_temp_new_i32();
-    TCGLabel *l1 = gen_new_label();
-    TCGLabel *l2 = gen_new_label();
-
-    if (tf)
-        cond = TCG_COND_EQ;
-    else
-        cond = TCG_COND_NE;
+    TCGv_i32 ts = tcg_temp_new_i32();
+    TCGv_i32 td = tcg_temp_new_i32();
+    TCGv_i32 zero = tcg_const_i32(0);
 
     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
-    tcg_gen_brcondi_i32(cond, t0, 0, l1);
-    gen_load_fpr32(ctx, t0, fs);
-    gen_store_fpr32(ctx, t0, fd);
-    gen_set_label(l1);
+    gen_load_fpr32(ctx, ts, fs);
+    gen_load_fpr32(ctx, td, fd);
+    tcg_gen_movcond_i32(cond, td, t0, zero, ts, td);
+    gen_store_fpr32(ctx, td, fd);
 
     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
-    tcg_gen_brcondi_i32(cond, t0, 0, l2);
-    gen_load_fpr32h(ctx, t0, fs);
-    gen_store_fpr32h(ctx, t0, fd);
+    gen_load_fpr32h(ctx, ts, fs);
+    gen_load_fpr32h(ctx, td, fs);
+    tcg_gen_movcond_i32(cond, td, t0, zero, ts, td);
+    gen_store_fpr32h(ctx, td, fd);
+
     tcg_temp_free_i32(t0);
-    gen_set_label(l2);
+    tcg_temp_free_i32(ts);
+    tcg_temp_free_i32(td);
+    tcg_temp_free_i32(zero);
 }
 
 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
@@ -9261,35 +9304,20 @@  static void gen_farith (DisasContext *ctx, enum fopcode op1,
         break;
     case OPC_MOVZ_S:
         check_insn_opc_removed(ctx, ISA_MIPS32R6);
-        {
-            TCGLabel *l1 = gen_new_label();
-            TCGv_i32 fp0;
-
-            if (ft != 0) {
-                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
-            }
-            fp0 = tcg_temp_new_i32();
+        if (ft != 0) {
+            gen_mov_s_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_EQ);
+        } else {
+            TCGv_i32 fp0 = tcg_temp_new_i32();
             gen_load_fpr32(ctx, fp0, fs);
             gen_store_fpr32(ctx, fp0, fd);
             tcg_temp_free_i32(fp0);
-            gen_set_label(l1);
         }
         opn = "movz.s";
         break;
     case OPC_MOVN_S:
         check_insn_opc_removed(ctx, ISA_MIPS32R6);
-        {
-            TCGLabel *l1 = gen_new_label();
-            TCGv_i32 fp0;
-
-            if (ft != 0) {
-                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
-                fp0 = tcg_temp_new_i32();
-                gen_load_fpr32(ctx, fp0, fs);
-                gen_store_fpr32(ctx, fp0, fd);
-                tcg_temp_free_i32(fp0);
-                gen_set_label(l1);
-            }
+        if (ft != 0) {
+            gen_mov_s_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_NE);
         }
         opn = "movn.s";
         break;
@@ -9806,35 +9834,20 @@  static void gen_farith (DisasContext *ctx, enum fopcode op1,
         break;
     case OPC_MOVZ_D:
         check_insn_opc_removed(ctx, ISA_MIPS32R6);
-        {
-            TCGLabel *l1 = gen_new_label();
-            TCGv_i64 fp0;
-
-            if (ft != 0) {
-                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
-            }
-            fp0 = tcg_temp_new_i64();
+        if (ft != 0) {
+            gen_mov_d_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_EQ);
+        } else {
+            TCGv_i64 fp0 = tcg_temp_new_i64();
             gen_load_fpr64(ctx, fp0, fs);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
-            gen_set_label(l1);
         }
         opn = "movz.d";
         break;
     case OPC_MOVN_D:
         check_insn_opc_removed(ctx, ISA_MIPS32R6);
-        {
-            TCGLabel *l1 = gen_new_label();
-            TCGv_i64 fp0;
-
-            if (ft != 0) {
-                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
-                fp0 = tcg_temp_new_i64();
-                gen_load_fpr64(ctx, fp0, fs);
-                gen_store_fpr64(ctx, fp0, fd);
-                tcg_temp_free_i64(fp0);
-                gen_set_label(l1);
-            }
+        if (ft != 0) {
+            gen_mov_d_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_NE);
         }
         opn = "movn.d";
         break;
@@ -10244,34 +10257,20 @@  static void gen_farith (DisasContext *ctx, enum fopcode op1,
         break;
     case OPC_MOVZ_PS:
         check_ps(ctx);
-        {
-            TCGLabel *l1 = gen_new_label();
-            TCGv_i64 fp0;
-
-            if (ft != 0)
-                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
-            fp0 = tcg_temp_new_i64();
+        if (ft != 0) {
+            gen_mov_d_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_EQ);
+        } else {
+            TCGv_i64 fp0 = tcg_temp_new_i64();
             gen_load_fpr64(ctx, fp0, fs);
             gen_store_fpr64(ctx, fp0, fd);
             tcg_temp_free_i64(fp0);
-            gen_set_label(l1);
         }
         opn = "movz.ps";
         break;
     case OPC_MOVN_PS:
         check_ps(ctx);
-        {
-            TCGLabel *l1 = gen_new_label();
-            TCGv_i64 fp0;
-
-            if (ft != 0) {
-                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
-                fp0 = tcg_temp_new_i64();
-                gen_load_fpr64(ctx, fp0, fs);
-                gen_store_fpr64(ctx, fp0, fd);
-                tcg_temp_free_i64(fp0);
-                gen_set_label(l1);
-            }
+        if (ft != 0) {
+            gen_mov_d_cond(ctx, fs, fd, cpu_gpr[ft], TCG_COND_NE);
         }
         opn = "movn.ps";
         break;