qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 10/25] target-openrisc: Represent MACHI:MACLO as a s


From: Richard Henderson
Subject: [Qemu-devel] [PATCH 10/25] target-openrisc: Represent MACHI:MACLO as a single unit
Date: Mon, 13 Jun 2016 16:58:10 -0700

Significantly simplifies the implementation of the use of MAC.

Reviewed-by: Bastian Koppelmann <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---
 target-openrisc/cpu.h        |   3 +-
 target-openrisc/sys_helper.c |  13 +++++
 target-openrisc/translate.c  | 120 +++++++++++++++++++++++--------------------
 3 files changed, 78 insertions(+), 58 deletions(-)

diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 37338c2..37e0c00 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -277,8 +277,7 @@ typedef struct CPUOpenRISCState {
     target_ulong ppc;         /* Prev PC */
     target_ulong jmp_pc;      /* Jump PC */
 
-    target_ulong machi;       /* Multiply register MACHI */
-    target_ulong maclo;       /* Multiply register MACLO */
+    uint64_t mac;             /* Multiply registers MACHI:MACLO */
 
     target_ulong fpmaddhi;    /* Multiply and add float register FPMADDHI */
     target_ulong fpmaddlo;    /* Multiply and add float register FPMADDLO */
diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c
index 8584ad0..e0d8893 100644
--- a/target-openrisc/sys_helper.c
+++ b/target-openrisc/sys_helper.c
@@ -120,6 +120,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
+    case TO_SPR(5, 1):  /* MACLO */
+        env->mac = deposit64(env->mac, 0, 32, rb);
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        env->mac = deposit64(env->mac, 32, 32, rb);
+        break;
     case TO_SPR(9, 0):  /* PICMR */
         env->picmr |= rb;
         break;
@@ -245,6 +251,13 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
 
+    case TO_SPR(5, 1):  /* MACLO */
+        return (uint32_t)env->mac;
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        return env->mac >> 32;
+        break;
+
     case TO_SPR(9, 0):  /* PICMR */
         return env->picmr;
 
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index f817f99..62129b8 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -59,7 +59,7 @@ static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
 static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
 static TCGv cpu_sr_ov;          /* signed overflow */
 static TCGv_i32 fpcsr;
-static TCGv machi, maclo;
+static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
 static TCGv fpmaddhi, fpmaddlo;
 static TCGv_i32 env_flags;
 #include "exec/gen-icount.h"
@@ -97,12 +97,9 @@ void openrisc_translate_init(void)
     fpcsr = tcg_global_mem_new_i32(cpu_env,
                                    offsetof(CPUOpenRISCState, fpcsr),
                                    "fpcsr");
-    machi = tcg_global_mem_new(cpu_env,
-                               offsetof(CPUOpenRISCState, machi),
-                               "machi");
-    maclo = tcg_global_mem_new(cpu_env,
-                               offsetof(CPUOpenRISCState, maclo),
-                               "maclo");
+    cpu_mac = tcg_global_mem_new_i64(cpu_env,
+                                     offsetof(CPUOpenRISCState, mac),
+                                     "mac");
     fpmaddhi = tcg_global_mem_new(cpu_env,
                                   offsetof(CPUOpenRISCState, fpmaddhi),
                                   "fpmaddhi");
@@ -375,6 +372,58 @@ static void gen_divu(DisasContext *dc, TCGv dest, TCGv 
srca, TCGv srcb)
     gen_ove_cy(dc);
 }
 
+static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t1, srca);
+    tcg_gen_ext_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+
+    /* Note that overflow is only computed during addition stage.  */
+    tcg_gen_xor_i64(t2, cpu_mac, t1);
+    tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_xor_i64(t1, t1, cpu_mac);
+    tcg_gen_andc_i64(t1, t1, t2);
+    tcg_temp_free_i64(t2);
+
+#if TARGET_LONG_BITS == 32
+    tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
+#else
+    tcg_gen_mov_i64(cpu_sr_ov, t1);
+#endif
+    tcg_temp_free_i64(t1);
+
+    gen_ove_ov(dc);
+}
+
+static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t1, srca);
+    tcg_gen_ext_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+
+    /* Note that overflow is only computed during subtraction stage.  */
+    tcg_gen_xor_i64(t2, cpu_mac, t1);
+    tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_xor_i64(t1, t1, cpu_mac);
+    tcg_gen_and_i64(t1, t1, t2);
+    tcg_temp_free_i64(t2);
+
+#if TARGET_LONG_BITS == 32
+    tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
+#else
+    tcg_gen_mov_i64(cpu_sr_ov, t1);
+#endif
+    tcg_temp_free_i64(t1);
+
+    gen_ove_ov(dc);
+}
+
 static void dec_calc(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0, op1, op2;
@@ -596,23 +645,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x13:    /* l.maci */
-        LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I11);
+        LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I16);
         {
-            TCGv_i64 t1 = tcg_temp_new_i64();
-            TCGv_i64 t2 = tcg_temp_new_i64();
-            TCGv_i32 dst = tcg_temp_new_i32();
-            TCGv ttmp = tcg_const_tl(tmp);
-            tcg_gen_mul_tl(dst, cpu_R[ra], ttmp);
-            tcg_gen_ext_i32_i64(t1, dst);
-            tcg_gen_concat_i32_i64(t2, maclo, machi);
-            tcg_gen_add_i64(t2, t2, t1);
-            tcg_gen_extrl_i64_i32(maclo, t2);
-            tcg_gen_shri_i64(t2, t2, 32);
-            tcg_gen_extrl_i64_i32(machi, t2);
-            tcg_temp_free_i32(dst);
-            tcg_temp_free(ttmp);
-            tcg_temp_free_i64(t1);
-            tcg_temp_free_i64(t2);
+            TCGv imm = tcg_const_tl(sign_extend(I16, 16));
+            gen_mac(dc, cpu_R[ra], imm);
+            tcg_temp_free(imm);
         }
         break;
 
@@ -832,40 +869,12 @@ static void dec_mac(DisasContext *dc, uint32_t insn)
     switch (op0) {
     case 0x0001:    /* l.mac */
         LOG_DIS("l.mac r%d, r%d\n", ra, rb);
-        {
-            TCGv_i32 t0 = tcg_temp_new_i32();
-            TCGv_i64 t1 = tcg_temp_new_i64();
-            TCGv_i64 t2 = tcg_temp_new_i64();
-            tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
-            tcg_gen_ext_i32_i64(t1, t0);
-            tcg_gen_concat_i32_i64(t2, maclo, machi);
-            tcg_gen_add_i64(t2, t2, t1);
-            tcg_gen_extrl_i64_i32(maclo, t2);
-            tcg_gen_shri_i64(t2, t2, 32);
-            tcg_gen_extrl_i64_i32(machi, t2);
-            tcg_temp_free_i32(t0);
-            tcg_temp_free_i64(t1);
-            tcg_temp_free_i64(t2);
-        }
+        gen_mac(dc, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0002:    /* l.msb */
         LOG_DIS("l.msb r%d, r%d\n", ra, rb);
-        {
-            TCGv_i32 t0 = tcg_temp_new_i32();
-            TCGv_i64 t1 = tcg_temp_new_i64();
-            TCGv_i64 t2 = tcg_temp_new_i64();
-            tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
-            tcg_gen_ext_i32_i64(t1, t0);
-            tcg_gen_concat_i32_i64(t2, maclo, machi);
-            tcg_gen_sub_i64(t2, t2, t1);
-            tcg_gen_extrl_i64_i32(maclo, t2);
-            tcg_gen_shri_i64(t2, t2, 32);
-            tcg_gen_extrl_i64_i32(machi, t2);
-            tcg_temp_free_i32(t0);
-            tcg_temp_free_i64(t1);
-            tcg_temp_free_i64(t2);
-        }
+        gen_msb(dc, cpu_R[ra], cpu_R[rb]);
         break;
 
     default:
@@ -926,9 +935,8 @@ static void dec_M(DisasContext *dc, uint32_t insn)
 
     case 0x1:    /* l.macrc */
         LOG_DIS("l.macrc  r%d\n", rd);
-        tcg_gen_mov_tl(cpu_R[rd], maclo);
-        tcg_gen_movi_tl(maclo, 0x0);
-        tcg_gen_movi_tl(machi, 0x0);
+        tcg_gen_trunc_i64_tl(cpu_R[rd], cpu_mac);
+        tcg_gen_movi_i64(cpu_mac, 0);
         break;
 
     default:
-- 
2.5.5




reply via email to

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