qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: Richard Henderson
Subject: [Qemu-devel] [PATCH v2 1/2] target-mips: Use movcond in movci and movcf*
Date: Wed, 2 Sep 2015 15:50:13 -0700

Signed-off-by: Richard Henderson <address@hidden>
---
 target-mips/translate.c | 255 ++++++++++++++++++++++++------------------------
 1 file changed, 127 insertions(+), 128 deletions(-)

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;
-- 
2.4.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]