qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/7] target-mips: DSP ASE fixes and cleanup
@ 2012-11-16 11:04 Aurelien Jarno
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 1/7] target-mips: fix DSP loads with rd = 0 Aurelien Jarno
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Aurelien Jarno @ 2012-11-16 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

This patch series contains some fixes and cleanup following the merge
of the DSP ASE patches.

Aurelien Jarno (7):
  target-mips: fix DSP loads with rd = 0
  target-mips: generate a reserved instruction exception on CPU without DSP
  target-mips: add unions to access DSP elements
  target-mips: use DSP unions for binary DSP operators
  target-mips: use DSP unions for unary DSP operators
  target-mips: use DSP unions for reduction add instructions
  target-mips: implement DSP (d)append sub-class with TCG

 target-mips/dsp_helper.c |  623 ++++++++++++-------------------------
 target-mips/helper.h     |   13 -
 target-mips/translate.c  |  771 ++++++++++++++++++++++++----------------------
 3 files changed, 601 insertions(+), 806 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 1/7] target-mips: fix DSP loads with rd = 0
  2012-11-16 11:04 [Qemu-devel] [PATCH 0/7] target-mips: DSP ASE fixes and cleanup Aurelien Jarno
@ 2012-11-16 11:04 ` Aurelien Jarno
  2012-11-21  6:28   ` Johnson, Eric
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 2/7] target-mips: generate a reserved instruction exception on CPU without DSP Aurelien Jarno
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Aurelien Jarno @ 2012-11-16 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

When rd is 0, which still need to do the actually load to possibly
generate a TLB exception.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/translate.c |    5 -----
 1 file changed, 5 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 01b48fa..c3e00c5 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12631,11 +12631,6 @@ static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
     const char *opn = "ldx";
     TCGv t0;
 
-    if (rd == 0) {
-        MIPS_DEBUG("NOP");
-        return;
-    }
-
     check_dsp(ctx);
     t0 = tcg_temp_new();
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 2/7] target-mips: generate a reserved instruction exception on CPU without DSP
  2012-11-16 11:04 [Qemu-devel] [PATCH 0/7] target-mips: DSP ASE fixes and cleanup Aurelien Jarno
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 1/7] target-mips: fix DSP loads with rd = 0 Aurelien Jarno
@ 2012-11-16 11:04 ` Aurelien Jarno
  2012-11-16 22:02   ` Richard Henderson
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 3/7] target-mips: add unions to access DSP elements Aurelien Jarno
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Aurelien Jarno @ 2012-11-16 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

On CPU without DSP ASE support, a reserved instruction exception (instead of
a DSP ASE sate disabled) should be generated.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/translate.c |  637 ++++++++++++++++++++++++-----------------------
 1 file changed, 324 insertions(+), 313 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index c3e00c5..910dd16 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1390,17 +1390,25 @@ static inline void check_cp1_registers(DisasContext *ctx, int regs)
    This is enabled by CP0 Status register MX(24) bit.
  */
 
-static inline void check_dsp(DisasContext *ctx)
+static inline void check_dsp(CPUMIPSState *env, DisasContext *ctx)
 {
     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
-        generate_exception(ctx, EXCP_DSPDIS);
+        if (env->insn_flags & ASE_DSP) {
+            generate_exception(ctx, EXCP_DSPDIS);
+        } else {
+            generate_exception(ctx, EXCP_RI);
+        }
     }
 }
 
-static inline void check_dspr2(DisasContext *ctx)
+static inline void check_dspr2(CPUMIPSState *env, DisasContext *ctx)
 {
     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
-        generate_exception(ctx, EXCP_DSPDIS);
+        if (env->insn_flags & ASE_DSPR2) {
+            generate_exception(ctx, EXCP_DSPDIS);
+        } else {
+            generate_exception(ctx, EXCP_RI);
+        }
     }
 }
 
@@ -2571,7 +2579,7 @@ static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
 }
 
 /* Arithmetic on HI/LO registers */
-static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
+static void gen_HILO (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int reg)
 {
     const char *opn = "hilo";
     unsigned int acc;
@@ -2589,7 +2597,7 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
     }
 
     if (acc != 0) {
-        check_dsp(ctx);
+        check_dsp(env, ctx);
     }
 
     switch (opc) {
@@ -2650,8 +2658,8 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
     MIPS_DEBUG("%s %s", opn, regnames[reg]);
 }
 
-static void gen_muldiv (DisasContext *ctx, uint32_t opc,
-                        int rs, int rt)
+static void gen_muldiv (CPUMIPSState *env, DisasContext *ctx,
+                        uint32_t opc, int rs, int rt)
 {
     const char *opn = "mul/div";
     TCGv t0, t1;
@@ -2708,7 +2716,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
             TCGv_i64 t3 = tcg_temp_new_i64();
             acc = ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
-                check_dsp(ctx);
+                check_dsp(env, ctx);
             }
 
             tcg_gen_ext_tl_i64(t2, t0);
@@ -2730,7 +2738,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
             TCGv_i64 t3 = tcg_temp_new_i64();
             acc = ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
-                check_dsp(ctx);
+                check_dsp(env, ctx);
             }
 
             tcg_gen_ext32u_tl(t0, t0);
@@ -2794,7 +2802,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
             TCGv_i64 t3 = tcg_temp_new_i64();
             acc = ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
-                check_dsp(ctx);
+                check_dsp(env, ctx);
             }
 
             tcg_gen_ext_tl_i64(t2, t0);
@@ -2818,7 +2826,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
             TCGv_i64 t3 = tcg_temp_new_i64();
             acc = ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
-                check_dsp(ctx);
+                check_dsp(env, ctx);
             }
 
             tcg_gen_ext32u_tl(t0, t0);
@@ -2844,7 +2852,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
             TCGv_i64 t3 = tcg_temp_new_i64();
             acc = ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
-                check_dsp(ctx);
+                check_dsp(env, ctx);
             }
 
             tcg_gen_ext_tl_i64(t2, t0);
@@ -2868,7 +2876,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
             TCGv_i64 t3 = tcg_temp_new_i64();
             acc = ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
-                check_dsp(ctx);
+                check_dsp(env, ctx);
             }
 
             tcg_gen_ext32u_tl(t0, t0);
@@ -10134,7 +10142,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
             gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
             break;
         case RR_MFHI:
-            gen_HILO(ctx, OPC_MFHI, rx);
+            gen_HILO(env, ctx, OPC_MFHI, rx);
             break;
         case RR_CNVT:
             switch (cnvt_op) {
@@ -10166,7 +10174,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
             }
             break;
         case RR_MFLO:
-            gen_HILO(ctx, OPC_MFLO, rx);
+            gen_HILO(env, ctx, OPC_MFLO, rx);
             break;
 #if defined (TARGET_MIPS64)
         case RR_DSRA:
@@ -10187,33 +10195,33 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
             break;
 #endif
         case RR_MULT:
-            gen_muldiv(ctx, OPC_MULT, rx, ry);
+            gen_muldiv(env, ctx, OPC_MULT, rx, ry);
             break;
         case RR_MULTU:
-            gen_muldiv(ctx, OPC_MULTU, rx, ry);
+            gen_muldiv(env, ctx, OPC_MULTU, rx, ry);
             break;
         case RR_DIV:
-            gen_muldiv(ctx, OPC_DIV, rx, ry);
+            gen_muldiv(env, ctx, OPC_DIV, rx, ry);
             break;
         case RR_DIVU:
-            gen_muldiv(ctx, OPC_DIVU, rx, ry);
+            gen_muldiv(env, ctx, OPC_DIVU, rx, ry);
             break;
 #if defined (TARGET_MIPS64)
         case RR_DMULT:
             check_mips_64(ctx);
-            gen_muldiv(ctx, OPC_DMULT, rx, ry);
+            gen_muldiv(env, ctx, OPC_DMULT, rx, ry);
             break;
         case RR_DMULTU:
             check_mips_64(ctx);
-            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
+            gen_muldiv(env, ctx, OPC_DMULTU, rx, ry);
             break;
         case RR_DDIV:
             check_mips_64(ctx);
-            gen_muldiv(ctx, OPC_DDIV, rx, ry);
+            gen_muldiv(env, ctx, OPC_DDIV, rx, ry);
             break;
         case RR_DDIVU:
             check_mips_64(ctx);
-            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
+            gen_muldiv(env, ctx, OPC_DDIVU, rx, ry);
             break;
 #endif
         default:
@@ -10895,11 +10903,11 @@ static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_bran
         break;
     case MFHI16 + 0:
     case MFHI16 + 1:
-        gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
+        gen_HILO(env, ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
         break;
     case MFLO16 + 0:
     case MFLO16 + 1:
-        gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
+        gen_HILO(env, ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
         break;
     case BREAK16:
         generate_exception(ctx, EXCP_BREAK);
@@ -11120,7 +11128,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
             mips32_op = OPC_MSUBU;
         do_muldiv:
             check_insn(env, ctx, ISA_MIPS32);
-            gen_muldiv(ctx, mips32_op, rs, rt);
+            gen_muldiv(env, ctx, mips32_op, rs, rt);
             break;
         default:
             goto pool32axf_invalid;
@@ -11259,16 +11267,16 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
     case 0x35:
         switch (minor) {
         case MFHI32:
-            gen_HILO(ctx, OPC_MFHI, rs);
+            gen_HILO(env, ctx, OPC_MFHI, rs);
             break;
         case MFLO32:
-            gen_HILO(ctx, OPC_MFLO, rs);
+            gen_HILO(env, ctx, OPC_MFLO, rs);
             break;
         case MTHI32:
-            gen_HILO(ctx, OPC_MTHI, rs);
+            gen_HILO(env, ctx, OPC_MTHI, rs);
             break;
         case MTLO32:
-            gen_HILO(ctx, OPC_MTLO, rs);
+            gen_HILO(env, ctx, OPC_MTLO, rs);
             break;
         default:
             goto pool32axf_invalid;
@@ -12631,7 +12639,7 @@ static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
     const char *opn = "ldx";
     TCGv t0;
 
-    check_dsp(ctx);
+    check_dsp(env, ctx);
     t0 = tcg_temp_new();
 
     if (base == 0) {
@@ -12672,7 +12680,8 @@ static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
     tcg_temp_free(t0);
 }
 
-static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
+static void gen_mipsdsp_arith(CPUMIPSState *env, DisasContext *ctx,
+                              uint32_t op1, uint32_t op2,
                               int ret, int v1, int v2)
 {
     const char *opn = "mipsdsp arith";
@@ -12694,7 +12703,7 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
     switch (op1) {
     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
     case OPC_MULT_G_2E:
-        check_dspr2(ctx);
+        check_dspr2(env, ctx);
         switch (op2) {
         case OPC_ADDUH_QB:
             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
@@ -12737,58 +12746,58 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
     case OPC_ABSQ_S_PH_DSP:
         switch (op2) {
         case OPC_ABSQ_S_QB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
             break;
         case OPC_ABSQ_S_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
             break;
         case OPC_ABSQ_S_W:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
             break;
         case OPC_PRECEQ_W_PHL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
             break;
         case OPC_PRECEQ_W_PHR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
             break;
         case OPC_PRECEQU_PH_QBL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQU_PH_QBR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQU_PH_QBLA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQU_PH_QBRA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEU_PH_QBL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEU_PH_QBR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEU_PH_QBLA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEU_PH_QBRA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
             break;
         }
@@ -12796,75 +12805,75 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
     case OPC_ADDU_QB_DSP:
         switch (op2) {
         case OPC_ADDQ_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDQ_S_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDQ_S_W:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDU_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDU_S_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDU_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDU_S_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBQ_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBQ_S_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBQ_S_W:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBU_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBU_S_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBU_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBU_S_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDSC:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDWC:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MODSUB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_RADDU_W_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
             break;
         }
@@ -12872,15 +12881,15 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
     case OPC_CMPU_EQ_QB_DSP:
         switch (op2) {
         case OPC_PRECR_QB_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_PRECRQ_QB_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_PRECR_SRA_PH_W:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             {
                 TCGv_i32 sa_t = tcg_const_i32(v2);
                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
@@ -12889,7 +12898,7 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
                 break;
             }
         case OPC_PRECR_SRA_R_PH_W:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             {
                 TCGv_i32 sa_t = tcg_const_i32(v2);
                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
@@ -12898,15 +12907,15 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
                 break;
             }
         case OPC_PRECRQ_PH_W:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_PRECRQ_RS_PH_W:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_PRECRQU_S_QB_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         }
@@ -12915,71 +12924,71 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
     case OPC_ABSQ_S_QH_DSP:
         switch (op2) {
         case OPC_PRECEQ_L_PWL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
             break;
         case OPC_PRECEQ_L_PWR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
             break;
         case OPC_PRECEQ_PW_QHL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQ_PW_QHR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQ_PW_QHLA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQ_PW_QHRA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQU_QH_OBL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQU_QH_OBR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQU_QH_OBLA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEQU_QH_OBRA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEU_QH_OBL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEU_QH_OBR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEU_QH_OBLA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
             break;
         case OPC_PRECEU_QH_OBRA:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
             break;
         case OPC_ABSQ_S_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
             break;
         case OPC_ABSQ_S_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
             break;
         case OPC_ABSQ_S_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
             break;
         }
@@ -12987,87 +12996,87 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
     case OPC_ADDU_OB_DSP:
         switch (op2) {
         case OPC_RADDU_L_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
             break;
         case OPC_SUBQ_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBQ_S_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBQ_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBQ_S_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBU_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBU_S_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBU_QH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBU_S_QH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_SUBUH_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_SUBUH_R_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_ADDQ_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDQ_S_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDQ_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDQ_S_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDU_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDU_S_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDU_QH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDU_S_QH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_ADDUH_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_ADDUH_R_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
             break;
         }
@@ -13075,11 +13084,11 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
     case OPC_CMPU_EQ_OB_DSP:
         switch (op2) {
         case OPC_PRECR_OB_QH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_PRECR_SRA_QH_PW:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             {
                 TCGv_i32 ret_t = tcg_const_i32(ret);
                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
@@ -13087,7 +13096,7 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
                 break;
             }
         case OPC_PRECR_SRA_R_QH_PW:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             {
                 TCGv_i32 sa_v = tcg_const_i32(ret);
                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
@@ -13095,23 +13104,23 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
                 break;
             }
         case OPC_PRECRQ_OB_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_PRECRQ_PW_L:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_PRECRQ_QH_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_PRECRQ_RS_QH_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_PRECRQU_S_OB_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         }
@@ -13126,8 +13135,8 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
     MIPS_DEBUG("%s", opn);
 }
 
-static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
-                              int ret, int v1, int v2)
+static void gen_mipsdsp_shift(CPUMIPSState *env, DisasContext *ctx,
+                              uint32_t opc, int ret, int v1, int v2)
 {
     uint32_t op2;
     const char *opn = "mipsdsp shift";
@@ -13155,91 +13164,91 @@ static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
             op2 = MASK_SHLL_QB(ctx->opcode);
             switch (op2) {
             case OPC_SHLL_QB:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
                 break;
             case OPC_SHLLV_QB:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
                 break;
             case OPC_SHLL_PH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
                 break;
             case OPC_SHLLV_PH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
                 break;
             case OPC_SHLL_S_PH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
                 break;
             case OPC_SHLLV_S_PH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
                 break;
             case OPC_SHLL_S_W:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
                 break;
             case OPC_SHLLV_S_W:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
                 break;
             case OPC_SHRL_QB:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
                 break;
             case OPC_SHRLV_QB:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
                 break;
             case OPC_SHRL_PH:
-                check_dspr2(ctx);
+                check_dspr2(env, ctx);
                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
                 break;
             case OPC_SHRLV_PH:
-                check_dspr2(ctx);
+                check_dspr2(env, ctx);
                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
                 break;
             case OPC_SHRA_QB:
-                check_dspr2(ctx);
+                check_dspr2(env, ctx);
                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
                 break;
             case OPC_SHRA_R_QB:
-                check_dspr2(ctx);
+                check_dspr2(env, ctx);
                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
                 break;
             case OPC_SHRAV_QB:
-                check_dspr2(ctx);
+                check_dspr2(env, ctx);
                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
                 break;
             case OPC_SHRAV_R_QB:
-                check_dspr2(ctx);
+                check_dspr2(env, ctx);
                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
                 break;
             case OPC_SHRA_PH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
                 break;
             case OPC_SHRA_R_PH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
                 break;
             case OPC_SHRAV_PH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
                 break;
             case OPC_SHRAV_R_PH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
                 break;
             case OPC_SHRA_R_W:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
                 break;
             case OPC_SHRAV_R_W:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
                 break;
             default:            /* Invalid */
@@ -13254,107 +13263,107 @@ static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
         op2 = MASK_SHLL_OB(ctx->opcode);
         switch (op2) {
         case OPC_SHLL_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
             break;
         case OPC_SHLLV_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
             break;
         case OPC_SHLL_S_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
             break;
         case OPC_SHLLV_S_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
             break;
         case OPC_SHLL_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
             break;
         case OPC_SHLLV_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
             break;
         case OPC_SHLL_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
             break;
         case OPC_SHLLV_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
             break;
         case OPC_SHLL_S_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
             break;
         case OPC_SHLLV_S_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
             break;
         case OPC_SHRA_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
             break;
         case OPC_SHRAV_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
             break;
         case OPC_SHRA_R_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
             break;
         case OPC_SHRAV_R_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
             break;
         case OPC_SHRA_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
             break;
         case OPC_SHRAV_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
             break;
         case OPC_SHRA_R_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
             break;
         case OPC_SHRAV_R_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
             break;
         case OPC_SHRA_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
             break;
         case OPC_SHRAV_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
             break;
         case OPC_SHRA_R_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
             break;
         case OPC_SHRAV_R_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
             break;
         case OPC_SHRL_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
             break;
         case OPC_SHRLV_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
             break;
         case OPC_SHRL_QH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
             break;
         case OPC_SHRLV_QH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
             break;
         default:            /* Invalid */
@@ -13373,7 +13382,8 @@ static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
     MIPS_DEBUG("%s", opn);
 }
 
-static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
+static void gen_mipsdsp_multiply(CPUMIPSState *env, DisasContext *ctx,
+                                 uint32_t op1, uint32_t op2,
                                  int ret, int v1, int v2, int check_ret)
 {
     const char *opn = "mipsdsp multiply";
@@ -13417,91 +13427,91 @@ static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
     case OPC_DPA_W_PH_DSP:
         switch (op2) {
         case OPC_DPAU_H_QBL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPAU_H_QBR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPSU_H_QBL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPSU_H_QBR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPA_W_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPAX_W_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPAQ_S_W_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPAQX_S_W_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPAQX_SA_W_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPS_W_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPSX_W_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPSQ_S_W_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPSQX_S_W_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPSQX_SA_W_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_MULSAQ_S_W_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPAQ_SA_L_W:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_DPSQ_SA_L_W:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_MAQ_S_W_PHL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_MAQ_S_W_PHR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_MAQ_SA_W_PHL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_MAQ_SA_W_PHR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
             break;
         case OPC_MULSA_W_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
             break;
         }
@@ -13514,107 +13524,107 @@ static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
 
             switch (op2) {
             case OPC_DMADD:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DMADDU:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DMSUB:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DMSUBU:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPA_W_QH:
-                check_dspr2(ctx);
+                check_dspr2(env, ctx);
                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPAQ_S_W_QH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPAQ_SA_L_PW:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPAU_H_OBL:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPAU_H_OBR:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPS_W_QH:
-                check_dspr2(ctx);
+                check_dspr2(env, ctx);
                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPSQ_S_W_QH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPSQ_SA_L_PW:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPSU_H_OBL:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_DPSU_H_OBR:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_S_L_PWL:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_S_L_PWR:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_S_W_QHLL:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_SA_W_QHLL:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_S_W_QHLR:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_SA_W_QHLR:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_S_W_QHRL:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_SA_W_QHRL:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_S_W_QHRR:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MAQ_SA_W_QHRR:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MULSAQ_S_L_PW:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
                 break;
             case OPC_MULSAQ_S_W_QH:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
                 break;
             }
@@ -13624,27 +13634,27 @@ static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
     case OPC_ADDU_QB_DSP:
         switch (op2) {
         case OPC_MULEU_S_PH_QBL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MULEU_S_PH_QBR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MULQ_RS_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MULEQ_S_W_PHL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MULEQ_S_W_PHR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MULQ_S_PH:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         }
@@ -13653,23 +13663,23 @@ static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
     case OPC_ADDU_OB_DSP:
         switch (op2) {
         case OPC_MULEQ_S_PW_QHL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MULEQ_S_PW_QHR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MULEU_S_QH_OBL:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MULEU_S_QH_OBR:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_MULQ_RS_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         }
@@ -13709,11 +13719,11 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
     case OPC_ABSQ_S_PH_DSP:
         switch (op2) {
         case OPC_BITREV:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_bitrev(cpu_gpr[ret], val_t);
             break;
         case OPC_REPL_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             {
                 target_long result;
                 imm = (ctx->opcode >> 16) & 0xFF;
@@ -13726,7 +13736,7 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
             }
             break;
         case OPC_REPLV_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
@@ -13735,7 +13745,7 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
             break;
         case OPC_REPL_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             {
                 imm = (ctx->opcode >> 16) & 0x03FF;
                 tcg_gen_movi_tl(cpu_gpr[ret], \
@@ -13744,7 +13754,7 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
             }
             break;
         case OPC_REPLV_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
@@ -13756,7 +13766,7 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
     case OPC_ABSQ_S_QH_DSP:
         switch (op2) {
         case OPC_REPL_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             {
                 target_long temp;
 
@@ -13768,7 +13778,7 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
                 break;
             }
         case OPC_REPL_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             {
                 target_long temp;
 
@@ -13780,7 +13790,7 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
                 break;
             }
         case OPC_REPL_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             {
                 target_long temp;
 
@@ -13795,7 +13805,7 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
                 break;
             }
         case OPC_REPLV_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
@@ -13805,13 +13815,13 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
             break;
         case OPC_REPLV_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
             break;
         case OPC_REPLV_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
@@ -13829,7 +13839,7 @@ static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
     MIPS_DEBUG("%s", opn);
 }
 
-static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
+static void gen_mipsdsp_add_cmp_pick(CPUMIPSState *env, DisasContext *ctx,
                                      uint32_t op1, uint32_t op2,
                                      int ret, int v1, int v2, int check_ret)
 {
@@ -13877,31 +13887,31 @@ static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
     case OPC_CMPU_EQ_QB_DSP:
         switch (op2) {
         case OPC_CMPU_EQ_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMPU_LT_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMPU_LE_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMPGU_EQ_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_CMPGU_LT_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_CMPGU_LE_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_CMPGDU_EQ_QB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
             tcg_gen_mov_tl(cpu_gpr[ret], t1);
             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
@@ -13909,7 +13919,7 @@ static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
             break;
         case OPC_CMPGDU_LT_QB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
             tcg_gen_mov_tl(cpu_gpr[ret], t1);
             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
@@ -13917,7 +13927,7 @@ static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
             break;
         case OPC_CMPGDU_LE_QB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
             tcg_gen_mov_tl(cpu_gpr[ret], t1);
             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
@@ -13925,27 +13935,27 @@ static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
             break;
         case OPC_CMP_EQ_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMP_LT_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMP_LE_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
             break;
         case OPC_PICK_QB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_PICK_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_PACKRL_PH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
             break;
         }
@@ -13954,79 +13964,79 @@ static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
     case OPC_CMPU_EQ_OB_DSP:
         switch (op2) {
         case OPC_CMP_EQ_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMP_LT_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMP_LE_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMP_EQ_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMP_LT_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMP_LE_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMPGDU_EQ_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_CMPGDU_LT_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_CMPGDU_LE_OB:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_CMPGU_EQ_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_CMPGU_LT_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_CMPGU_LE_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_CMPU_EQ_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMPU_LT_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
             break;
         case OPC_CMPU_LE_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
             break;
         case OPC_PACKRL_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
             break;
         case OPC_PICK_OB:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_PICK_PW:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         case OPC_PICK_QH:
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
             break;
         }
@@ -14067,7 +14077,8 @@ static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
     MIPS_DEBUG("%s", opn);
 }
 
-static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
+static void gen_mipsdsp_accinsn(CPUMIPSState *env, DisasContext *ctx,
+                                uint32_t op1, uint32_t op2,
                                 int ret, int v1, int v2, int check_ret)
 
 {
@@ -14094,7 +14105,7 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
 
     switch (op1) {
     case OPC_EXTR_W_DSP:
-        check_dsp(ctx);
+        check_dsp(env, ctx);
         switch (op2) {
         case OPC_EXTR_W:
             tcg_gen_movi_tl(t0, v2);
@@ -14178,7 +14189,7 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
         break;
 #ifdef TARGET_MIPS64
     case OPC_DEXTR_W_DSP:
-        check_dsp(ctx);
+        check_dsp(env, ctx);
         switch (op2) {
         case OPC_DMTHLIP:
             tcg_gen_movi_tl(t0, ret);
@@ -14403,7 +14414,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
                 op1 = MASK_MUL_VR54XX(ctx->opcode);
                 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
             } else
-                gen_muldiv(ctx, op1, rs, rt);
+                gen_muldiv(env, ctx, op1, rs, rt);
             break;
         case OPC_JR ... OPC_JALR:
             gen_compute_branch(ctx, op1, 4, rs, rd, sa);
@@ -14415,11 +14426,11 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             break;
         case OPC_MFHI:          /* Move from HI/LO */
         case OPC_MFLO:
-            gen_HILO(ctx, op1, rd);
+            gen_HILO(env, ctx, op1, rd);
             break;
         case OPC_MTHI:
         case OPC_MTLO:          /* Move to HI/LO */
-            gen_HILO(ctx, op1, rs);
+            gen_HILO(env, ctx, op1, rs);
             break;
         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
 #ifdef MIPS_STRICT_STANDARD
@@ -14539,7 +14550,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
         case OPC_DMULT ... OPC_DDIVU:
             check_insn(env, ctx, ISA_MIPS3);
             check_mips_64(ctx);
-            gen_muldiv(ctx, op1, rs, rt);
+            gen_muldiv(env, ctx, op1, rs, rt);
             break;
 #endif
         default:            /* Invalid */
@@ -14554,7 +14565,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
         case OPC_MSUB ... OPC_MSUBU:
             check_insn(env, ctx, ISA_MIPS32);
-            gen_muldiv(ctx, op1, rs, rt);
+            gen_muldiv(env, ctx, op1, rs, rt);
             break;
         case OPC_MUL:
             gen_arith(env, ctx, op1, rd, rs, rt);
@@ -14669,13 +14680,13 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
                 case OPC_SUBQH_R_PH:
                 case OPC_SUBQH_W:
                 case OPC_SUBQH_R_W:
-                    gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
+                    gen_mipsdsp_arith(env, ctx, op1, op2, rd, rs, rt);
                     break;
                 case OPC_MUL_PH:
                 case OPC_MUL_S_PH:
                 case OPC_MULQ_S_W:
                 case OPC_MULQ_RS_W:
-                    gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
+                    gen_mipsdsp_multiply(env, ctx, op1, op2, rd, rs, rt, 1);
                     break;
                 default:
                     MIPS_INVAL("MASK ADDUH.QB");
@@ -14721,7 +14732,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_PRECEU_PH_QBR:
             case OPC_PRECEU_PH_QBLA:
             case OPC_PRECEU_PH_QBRA:
-                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
+                gen_mipsdsp_arith(env, ctx, op1, op2, rd, rs, rt);
                 break;
             case OPC_BITREV:
             case OPC_REPL_QB:
@@ -14757,7 +14768,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_ADDWC:
             case OPC_MODSUB:
             case OPC_RADDU_W_QB:
-                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
+                gen_mipsdsp_arith(env, ctx, op1, op2, rd, rs, rt);
                 break;
             case OPC_MULEU_S_PH_QBL:
             case OPC_MULEU_S_PH_QBR:
@@ -14765,7 +14776,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_MULEQ_S_W_PHL:
             case OPC_MULEQ_S_W_PHR:
             case OPC_MULQ_S_PH:
-                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
+                gen_mipsdsp_multiply(env, ctx, op1, op2, rd, rs, rt, 1);
                 break;
             default:            /* Invalid */
                 MIPS_INVAL("MASK ADDU.QB");
@@ -14779,14 +14790,14 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             switch (op2) {
             case OPC_PRECR_SRA_PH_W:
             case OPC_PRECR_SRA_R_PH_W:
-                gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
+                gen_mipsdsp_arith(env, ctx, op1, op2, rt, rs, rd);
                 break;
             case OPC_PRECR_QB_PH:
             case OPC_PRECRQ_QB_PH:
             case OPC_PRECRQ_PH_W:
             case OPC_PRECRQ_RS_PH_W:
             case OPC_PRECRQU_S_QB_PH:
-                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
+                gen_mipsdsp_arith(env, ctx, op1, op2, rd, rs, rt);
                 break;
             case OPC_CMPU_EQ_QB:
             case OPC_CMPU_LT_QB:
@@ -14794,7 +14805,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_CMP_EQ_PH:
             case OPC_CMP_LT_PH:
             case OPC_CMP_LE_PH:
-                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
+                gen_mipsdsp_add_cmp_pick(env, ctx, op1, op2, rd, rs, rt, 0);
                 break;
             case OPC_CMPGU_EQ_QB:
             case OPC_CMPGU_LT_QB:
@@ -14805,7 +14816,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_PICK_QB:
             case OPC_PICK_PH:
             case OPC_PACKRL_PH:
-                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
+                gen_mipsdsp_add_cmp_pick(env, ctx, op1, op2, rd, rs, rt, 1);
                 break;
             default:            /* Invalid */
                 MIPS_INVAL("MASK CMPU.EQ.QB");
@@ -14814,7 +14825,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             }
             break;
         case OPC_SHLL_QB_DSP:
-            gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
+            gen_mipsdsp_shift(env, ctx, op1, rd, rs, rt);
             break;
         case OPC_DPA_W_PH_DSP:
             op2 = MASK_DPA_W_PH(ctx->opcode);
@@ -14841,7 +14852,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_MAQ_SA_W_PHL:
             case OPC_MAQ_SA_W_PHR:
             case OPC_MULSA_W_PH:
-                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
+                gen_mipsdsp_multiply(env, ctx, op1, op2, rd, rs, rt, 0);
                 break;
             default:            /* Invalid */
                 MIPS_INVAL("MASK DPAW.PH");
@@ -14853,7 +14864,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             op2 = MASK_INSV(ctx->opcode);
             switch (op2) {
             case OPC_INSV:
-                check_dsp(ctx);
+                check_dsp(env, ctx);
                 {
                     TCGv t0, t1;
 
@@ -14881,9 +14892,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             }
             break;
         case OPC_APPEND_DSP:
-            check_dspr2(ctx);
+            check_dspr2(env, ctx);
             op2 = MASK_APPEND(ctx->opcode);
-            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
+            gen_mipsdsp_add_cmp_pick(env, ctx, op1, op2, rt, rs, rd, 1);
             break;
         case OPC_EXTR_W_DSP:
             op2 = MASK_EXTR_W(ctx->opcode);
@@ -14900,16 +14911,16 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_EXTPV:
             case OPC_EXTPDP:
             case OPC_EXTPDPV:
-                gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
+                gen_mipsdsp_accinsn(env, ctx, op1, op2, rt, rs, rd, 1);
                 break;
             case OPC_RDDSP:
-                gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
+                gen_mipsdsp_accinsn(env, ctx, op1, op2, rd, rs, rt, 1);
                 break;
             case OPC_SHILO:
             case OPC_SHILOV:
             case OPC_MTHLIP:
             case OPC_WRDSP:
-                gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
+                gen_mipsdsp_accinsn(env, ctx, op1, op2, rd, rs, rt, 0);
                 break;
             default:            /* Invalid */
                 MIPS_INVAL("MASK EXTR.W");
@@ -14956,7 +14967,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_ABSQ_S_OB:
             case OPC_ABSQ_S_PW:
             case OPC_ABSQ_S_QH:
-                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
+                gen_mipsdsp_arith(env, ctx, op1, op2, rd, rs, rt);
                 break;
             case OPC_REPL_OB:
             case OPC_REPL_PW:
@@ -14996,14 +15007,14 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_ADDU_S_QH:
             case OPC_ADDUH_OB:
             case OPC_ADDUH_R_OB:
-                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
+                gen_mipsdsp_arith(env, ctx, op1, op2, rd, rs, rt);
                 break;
             case OPC_MULEQ_S_PW_QHL:
             case OPC_MULEQ_S_PW_QHR:
             case OPC_MULEU_S_QH_OBL:
             case OPC_MULEU_S_QH_OBR:
             case OPC_MULQ_RS_QH:
-                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
+                gen_mipsdsp_multiply(env, ctx, op1, op2, rd, rs, rt, 1);
                 break;
             default:            /* Invalid */
                 MIPS_INVAL("MASK ADDU.OB");
@@ -15017,7 +15028,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_PRECR_SRA_QH_PW:
             case OPC_PRECR_SRA_R_QH_PW:
                 /* Return value is rt. */
-                gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
+                gen_mipsdsp_arith(env, ctx, op1, op2, rt, rs, rd);
                 break;
             case OPC_PRECR_OB_QH:
             case OPC_PRECRQ_OB_QH:
@@ -15025,7 +15036,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_PRECRQ_QH_PW:
             case OPC_PRECRQ_RS_QH_PW:
             case OPC_PRECRQU_S_OB_QH:
-                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
+                gen_mipsdsp_arith(env, ctx, op1, op2, rd, rs, rt);
                 break;
             case OPC_CMPU_EQ_OB:
             case OPC_CMPU_LT_OB:
@@ -15036,7 +15047,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_CMP_EQ_PW:
             case OPC_CMP_LT_PW:
             case OPC_CMP_LE_PW:
-                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
+                gen_mipsdsp_add_cmp_pick(env, ctx, op1, op2, rd, rs, rt, 0);
                 break;
             case OPC_CMPGDU_EQ_OB:
             case OPC_CMPGDU_LT_OB:
@@ -15048,7 +15059,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_PICK_OB:
             case OPC_PICK_PW:
             case OPC_PICK_QH:
-                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
+                gen_mipsdsp_add_cmp_pick(env, ctx, op1, op2, rd, rs, rt, 1);
                 break;
             default:            /* Invalid */
                 MIPS_INVAL("MASK CMPU_EQ.OB");
@@ -15082,12 +15093,12 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_DEXTRV_W:
             case OPC_DEXTRV_R_W:
             case OPC_DEXTRV_RS_W:
-                gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
+                gen_mipsdsp_accinsn(env, ctx, op1, op2, rt, rs, rd, 1);
                 break;
             case OPC_DMTHLIP:
             case OPC_DSHILO:
             case OPC_DSHILOV:
-                gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
+                gen_mipsdsp_accinsn(env, ctx, op1, op2, rd, rs, rt, 0);
                 break;
             default:            /* Invalid */
                 MIPS_INVAL("MASK EXTR.W");
@@ -15110,7 +15121,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_DPAQ_SA_L_PW:
             case OPC_DPSQ_SA_L_PW:
             case OPC_MULSAQ_S_L_PW:
-                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
+                gen_mipsdsp_multiply(env, ctx, op1, op2, rd, rs, rt, 0);
                 break;
             case OPC_MAQ_S_W_QHLL:
             case OPC_MAQ_S_W_QHLR:
@@ -15126,7 +15137,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             case OPC_DMADDU:
             case OPC_DMSUB:
             case OPC_DMSUBU:
-                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
+                gen_mipsdsp_multiply(env, ctx, op1, op2, rd, rs, rt, 0);
                 break;
             default:            /* Invalid */
                 MIPS_INVAL("MASK DPAQ.W.QH");
@@ -15145,7 +15156,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
                         MIPS_DEBUG("NOP");
                         break;
                     }
-                    check_dsp(ctx);
+                    check_dsp(env, ctx);
 
                     t0 = tcg_temp_new();
                     t1 = tcg_temp_new();
@@ -15163,7 +15174,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             }
             break;
         case OPC_SHLL_OB_DSP:
-            gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
+            gen_mipsdsp_shift(env, ctx, op1, rd, rs, rt);
             break;
 #endif
         default:            /* Invalid */
@@ -15192,7 +15203,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
 #if defined(TARGET_MIPS64)
         case OPC_BPOSGE64:
 #endif
-            check_dsp(ctx);
+            check_dsp(env, ctx);
             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
             *is_branch = 1;
             break;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 3/7] target-mips: add unions to access DSP elements
  2012-11-16 11:04 [Qemu-devel] [PATCH 0/7] target-mips: DSP ASE fixes and cleanup Aurelien Jarno
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 1/7] target-mips: fix DSP loads with rd = 0 Aurelien Jarno
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 2/7] target-mips: generate a reserved instruction exception on CPU without DSP Aurelien Jarno
@ 2012-11-16 11:04 ` Aurelien Jarno
  2012-11-21  6:54   ` Johnson, Eric
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 4/7] target-mips: use DSP unions for binary DSP operators Aurelien Jarno
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Aurelien Jarno @ 2012-11-16 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Instead of playing with bit shifting, add two unions (one for 32-bit
values, one for 64-bit ones) to access all the DSP elements with the
correct type.

This make the code easier to read and less error prone, and allow GCC
to vectorize the code in some cases.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/dsp_helper.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index e7949c2..8015d8d 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -20,6 +20,28 @@
 #include "cpu.h"
 #include "helper.h"
 
+/* As the byte ordering doesn't matter, i.e. all columns are treated
+   identically, these unions can be used directly.  */
+typedef union {
+    uint8_t  ub[4];
+    int8_t   sb[4];
+    uint16_t uh[2];
+    int16_t  sh[2];
+    uint32_t uw[1];
+    int32_t  sw[1];
+} DSP32Value;
+
+typedef union {
+    uint8_t  ub[8];
+    int8_t   sb[8];
+    uint16_t uh[4];
+    int16_t  sh[4];
+    uint32_t uw[2];
+    int32_t  sw[2];
+    uint64_t ul[1];
+    int64_t  sl[1];
+} DSP64Value;
+
 /*** MIPS DSP internal functions begin ***/
 #define MIPSDSP_ABS(x) (((x) >= 0) ? x : -x)
 #define MIPSDSP_OVERFLOW(a, b, c, d) (!(!((a ^ b ^ -1) & (a ^ c) & d)))
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 4/7] target-mips: use DSP unions for binary DSP operators
  2012-11-16 11:04 [Qemu-devel] [PATCH 0/7] target-mips: DSP ASE fixes and cleanup Aurelien Jarno
                   ` (2 preceding siblings ...)
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 3/7] target-mips: add unions to access DSP elements Aurelien Jarno
@ 2012-11-16 11:04 ` Aurelien Jarno
  2012-11-16 22:04   ` Richard Henderson
  2012-12-05  4:58   ` Johnson, Eric
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 5/7] target-mips: use DSP unions for unary " Aurelien Jarno
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 17+ messages in thread
From: Aurelien Jarno @ 2012-11-16 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

This allow to reduce the number of macros.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/dsp_helper.c |  384 ++++++++++++++--------------------------------
 1 file changed, 116 insertions(+), 268 deletions(-)

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 8015d8d..931ca70 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -1107,7 +1107,6 @@ static inline int32_t mipsdsp_cmpu_lt(uint32_t a, uint32_t b)
         b = num & MIPSDSP_LO;               \
     } while (0)
 
-#define MIPSDSP_RETURN32(a)             ((target_long)(int32_t)a)
 #define MIPSDSP_RETURN32_8(a, b, c, d)  ((target_long)(int32_t) \
                                          (((uint32_t)a << 24) | \
                                          (((uint32_t)b << 16) | \
@@ -1140,119 +1139,127 @@ static inline int32_t mipsdsp_cmpu_lt(uint32_t a, uint32_t b)
 #endif
 
 /** DSP Arithmetic Sub-class insns **/
-#define ARITH_PH(name, func)                                      \
-target_ulong helper_##name##_ph(target_ulong rs, target_ulong rt) \
-{                                                                 \
-    uint16_t  rsh, rsl, rth, rtl, temph, templ;                   \
-                                                                  \
-    MIPSDSP_SPLIT32_16(rs, rsh, rsl);                             \
-    MIPSDSP_SPLIT32_16(rt, rth, rtl);                             \
-                                                                  \
-    temph = mipsdsp_##func(rsh, rth);                             \
-    templ = mipsdsp_##func(rsl, rtl);                             \
-                                                                  \
-    return MIPSDSP_RETURN32_16(temph, templ);                     \
-}
-
-#define ARITH_PH_ENV(name, func)                                  \
-target_ulong helper_##name##_ph(target_ulong rs, target_ulong rt, \
-                                CPUMIPSState *env)                \
-{                                                                 \
-    uint16_t  rsh, rsl, rth, rtl, temph, templ;                   \
-                                                                  \
-    MIPSDSP_SPLIT32_16(rs, rsh, rsl);                             \
-    MIPSDSP_SPLIT32_16(rt, rth, rtl);                             \
-                                                                  \
-    temph = mipsdsp_##func(rsh, rth, env);                        \
-    templ = mipsdsp_##func(rsl, rtl, env);                        \
-                                                                  \
-    return MIPSDSP_RETURN32_16(temph, templ);                     \
-}
-
-
-ARITH_PH_ENV(addq, add_i16);
-ARITH_PH_ENV(addq_s, sat_add_i16);
-ARITH_PH_ENV(addu, add_u16);
-ARITH_PH_ENV(addu_s, sat_add_u16);
-
-ARITH_PH(addqh, rshift1_add_q16);
-ARITH_PH(addqh_r, rrshift1_add_q16);
-
-ARITH_PH_ENV(subq, sub_i16);
-ARITH_PH_ENV(subq_s, sat16_sub);
-ARITH_PH_ENV(subu, sub_u16_u16);
-ARITH_PH_ENV(subu_s, satu16_sub_u16_u16);
-
-ARITH_PH(subqh, rshift1_sub_q16);
-ARITH_PH(subqh_r, rrshift1_sub_q16);
-
-#undef ARITH_PH
-#undef ARITH_PH_ENV
+#define MIPSDSP32_BINOP(name, func, element)                               \
+target_ulong helper_##name(target_ulong rs, target_ulong rt)               \
+{                                                                          \
+    DSP32Value ds, dt;                                                     \
+    unsigned int i, n;                                                     \
+                                                                           \
+    n = sizeof(DSP32Value) / sizeof(ds.element[0]);                        \
+    ds.sw[0] = rs;                                                         \
+    dt.sw[0] = rt;                                                         \
+                                                                           \
+    for (i = 0 ; i < n ; i++) {                                            \
+        ds.element[i] = mipsdsp_##func(ds.element[i], dt.element[i]);      \
+    }                                                                      \
+                                                                           \
+    return (int32_t)ds.sw[0];                                              \
+}
+MIPSDSP32_BINOP(addqh_ph, rshift1_add_q16, sh);
+MIPSDSP32_BINOP(addqh_r_ph, rrshift1_add_q16, sh);
+MIPSDSP32_BINOP(addqh_r_w, rrshift1_add_q32, sw);
+MIPSDSP32_BINOP(addqh_w, rshift1_add_q32, sw);
+MIPSDSP32_BINOP(adduh_qb, rshift1_add_u8, ub);
+MIPSDSP32_BINOP(adduh_r_qb, rrshift1_add_u8, ub);
+MIPSDSP32_BINOP(subqh_ph, rshift1_sub_q16, sh);
+MIPSDSP32_BINOP(subqh_r_ph, rrshift1_sub_q16, sh);
+MIPSDSP32_BINOP(subqh_r_w, rrshift1_sub_q32, sw);
+MIPSDSP32_BINOP(subqh_w, rshift1_sub_q32, sw);
+#undef MIPSDSP32_BINOP
+
+#define MIPSDSP32_BINOP_ENV(name, func, element)                           \
+target_ulong helper_##name(target_ulong rs, target_ulong rt,               \
+                           CPUMIPSState *env)                              \
+{                                                                          \
+    DSP32Value ds, dt;                                                     \
+    unsigned int i, n;                                                     \
+                                                                           \
+    n = sizeof(DSP32Value) / sizeof(ds.element[0]);                        \
+    ds.sw[0] = rs;                                                         \
+    dt.sw[0] = rt;                                                         \
+                                                                           \
+    for (i = 0 ; i < n ; i++) {                                            \
+        ds.element[i] = mipsdsp_##func(ds.element[i], dt.element[i], env); \
+    }                                                                      \
+                                                                           \
+    return (int32_t)ds.sw[0];                                              \
+}
+MIPSDSP32_BINOP_ENV(addq_ph, add_i16, sh)
+MIPSDSP32_BINOP_ENV(addq_s_ph, sat_add_i16, sh)
+MIPSDSP32_BINOP_ENV(addq_s_w, sat_add_i32, sw);
+MIPSDSP32_BINOP_ENV(addu_ph, add_u16, sh)
+MIPSDSP32_BINOP_ENV(addu_qb, add_u8, ub);
+MIPSDSP32_BINOP_ENV(addu_s_ph, sat_add_u16, sh)
+MIPSDSP32_BINOP_ENV(addu_s_qb, sat_add_u8, ub);
+MIPSDSP32_BINOP_ENV(subq_ph, sub_i16, sh);
+MIPSDSP32_BINOP_ENV(subq_s_ph, sat16_sub, sh);
+MIPSDSP32_BINOP_ENV(subq_s_w, sat32_sub, sw);
+MIPSDSP32_BINOP_ENV(subu_ph, sub_u16_u16, sh);
+MIPSDSP32_BINOP_ENV(subu_qb, sub_u8, ub);
+MIPSDSP32_BINOP_ENV(subu_s_ph, satu16_sub_u16_u16, sh);
+MIPSDSP32_BINOP_ENV(subu_s_qb, satu8_sub, ub);
+#undef MIPSDSP32_BINOP_ENV
 
 #ifdef TARGET_MIPS64
-#define ARITH_QH_ENV(name, func) \
-target_ulong helper_##name##_qh(target_ulong rs, target_ulong rt, \
-                                CPUMIPSState *env)           \
-{                                                            \
-    uint16_t rs3, rs2, rs1, rs0;                             \
-    uint16_t rt3, rt2, rt1, rt0;                             \
-    uint16_t tempD, tempC, tempB, tempA;                     \
-                                                             \
-    MIPSDSP_SPLIT64_16(rs, rs3, rs2, rs1, rs0);              \
-    MIPSDSP_SPLIT64_16(rt, rt3, rt2, rt1, rt0);              \
-                                                             \
-    tempD = mipsdsp_##func(rs3, rt3, env);                   \
-    tempC = mipsdsp_##func(rs2, rt2, env);                   \
-    tempB = mipsdsp_##func(rs1, rt1, env);                   \
-    tempA = mipsdsp_##func(rs0, rt0, env);                   \
-                                                             \
-    return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);  \
-}
-
-ARITH_QH_ENV(addq, add_i16);
-ARITH_QH_ENV(addq_s, sat_add_i16);
-ARITH_QH_ENV(addu, add_u16);
-ARITH_QH_ENV(addu_s, sat_add_u16);
-
-ARITH_QH_ENV(subq, sub_i16);
-ARITH_QH_ENV(subq_s, sat16_sub);
-ARITH_QH_ENV(subu, sub_u16_u16);
-ARITH_QH_ENV(subu_s, satu16_sub_u16_u16);
-
-#undef ARITH_QH_ENV
+#define MIPSDSP64_BINOP(name, func, element)                               \
+target_ulong helper_##name(target_ulong rs, target_ulong rt)               \
+{                                                                          \
+    DSP64Value ds, dt;                                                     \
+    unsigned int i, n;                                                     \
+                                                                           \
+    n = sizeof(DSP64Value) / sizeof(ds.element[0]);                        \
+    ds.sl[0] = rs;                                                         \
+    dt.sl[0] = rt;                                                         \
+                                                                           \
+    for (i = 0 ; i < n ; i++) {                                            \
+        ds.element[i] = mipsdsp_##func(ds.element[i], dt.element[i]);      \
+    }                                                                      \
+                                                                           \
+    return ds.sl[0];                                                       \
+}
+MIPSDSP64_BINOP(adduh_ob, rshift1_add_u8, ub);
+MIPSDSP64_BINOP(adduh_r_ob, rrshift1_add_u8, ub);
+MIPSDSP64_BINOP(subuh_ob, rshift1_sub_u8, ub);
+MIPSDSP64_BINOP(subuh_r_ob, rrshift1_sub_u8, ub);
+#undef MIPSDSP64_BINOP
+
+#define MIPSDSP64_BINOP_ENV(name, func, element)                           \
+target_ulong helper_##name(target_ulong rs, target_ulong rt,               \
+                           CPUMIPSState *env)                              \
+{                                                                          \
+    DSP64Value ds, dt;                                                     \
+    unsigned int i, n;                                                     \
+                                                                           \
+    n = sizeof(DSP64Value) / sizeof(ds.element[0]);                        \
+    ds.sl[0] = rs;                                                         \
+    dt.sl[0] = rt;                                                         \
+                                                                           \
+    for (i = 0 ; i < n ; i++) {                                            \
+        ds.element[i] = mipsdsp_##func(ds.element[i], dt.element[i], env); \
+    }                                                                      \
+                                                                           \
+    return ds.sl[0];                                                       \
+}
+MIPSDSP64_BINOP_ENV(addq_pw, add_i32, sw);
+MIPSDSP64_BINOP_ENV(addq_qh, add_i16, sh);
+MIPSDSP64_BINOP_ENV(addq_s_pw, sat_add_i32, sw);
+MIPSDSP64_BINOP_ENV(addq_s_qh, sat_add_i16, sh);
+MIPSDSP64_BINOP_ENV(addu_ob, add_u8, uh);
+MIPSDSP64_BINOP_ENV(addu_qh, add_u16, uh);
+MIPSDSP64_BINOP_ENV(addu_s_ob, sat_add_u8, uh);
+MIPSDSP64_BINOP_ENV(addu_s_qh, sat_add_u16, uh);
+MIPSDSP64_BINOP_ENV(subq_pw, sub32, sw);
+MIPSDSP64_BINOP_ENV(subq_qh, sub_i16, sh);
+MIPSDSP64_BINOP_ENV(subq_s_pw, sat32_sub, sw);
+MIPSDSP64_BINOP_ENV(subq_s_qh, sat16_sub, sh);
+MIPSDSP64_BINOP_ENV(subu_ob, sub_u8, uh);
+MIPSDSP64_BINOP_ENV(subu_qh, sub_u16_u16, uh);
+MIPSDSP64_BINOP_ENV(subu_s_ob, satu8_sub, uh);
+MIPSDSP64_BINOP_ENV(subu_s_qh, satu16_sub_u16_u16, uh);
+#undef MIPSDSP64_BINOP_ENV
 
 #endif
 
-#define ARITH_W(name, func) \
-target_ulong helper_##name##_w(target_ulong rs, target_ulong rt) \
-{                                                                \
-    uint32_t rd;                                                 \
-    rd = mipsdsp_##func(rs, rt);                                 \
-    return MIPSDSP_RETURN32(rd);                                 \
-}
-
-#define ARITH_W_ENV(name, func) \
-target_ulong helper_##name##_w(target_ulong rs, target_ulong rt, \
-                               CPUMIPSState *env)                \
-{                                                                \
-    uint32_t rd;                                                 \
-    rd = mipsdsp_##func(rs, rt, env);                            \
-    return MIPSDSP_RETURN32(rd);                                 \
-}
-
-ARITH_W_ENV(addq_s, sat_add_i32);
-
-ARITH_W(addqh, rshift1_add_q32);
-ARITH_W(addqh_r, rrshift1_add_q32);
-
-ARITH_W_ENV(subq_s, sat32_sub);
-
-ARITH_W(subqh, rshift1_sub_q32);
-ARITH_W(subqh_r, rrshift1_sub_q32);
-
-#undef ARITH_W
-#undef ARITH_W_ENV
-
 target_ulong helper_absq_s_w(target_ulong rt, CPUMIPSState *env)
 {
     uint32_t rd;
@@ -1263,164 +1270,6 @@ target_ulong helper_absq_s_w(target_ulong rt, CPUMIPSState *env)
 }
 
 
-#if defined(TARGET_MIPS64)
-
-#define ARITH_PW_ENV(name, func) \
-target_ulong helper_##name##_pw(target_ulong rs, target_ulong rt, \
-                                CPUMIPSState *env)                \
-{                                                                 \
-    uint32_t rs1, rs0;                                            \
-    uint32_t rt1, rt0;                                            \
-    uint32_t tempB, tempA;                                        \
-                                                                  \
-    MIPSDSP_SPLIT64_32(rs, rs1, rs0);                             \
-    MIPSDSP_SPLIT64_32(rt, rt1, rt0);                             \
-                                                                  \
-    tempB = mipsdsp_##func(rs1, rt1, env);                        \
-    tempA = mipsdsp_##func(rs0, rt0, env);                        \
-                                                                  \
-    return MIPSDSP_RETURN64_32(tempB, tempA);                     \
-}
-
-ARITH_PW_ENV(addq, add_i32);
-ARITH_PW_ENV(addq_s, sat_add_i32);
-ARITH_PW_ENV(subq, sub32);
-ARITH_PW_ENV(subq_s, sat32_sub);
-
-#undef ARITH_PW_ENV
-
-#endif
-
-#define ARITH_QB(name, func) \
-target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt) \
-{                                                                 \
-    uint8_t  rs0, rs1, rs2, rs3;                                  \
-    uint8_t  rt0, rt1, rt2, rt3;                                  \
-    uint8_t  temp0, temp1, temp2, temp3;                          \
-                                                                  \
-    MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);                    \
-    MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);                    \
-                                                                  \
-    temp0 = mipsdsp_##func(rs0, rt0);                             \
-    temp1 = mipsdsp_##func(rs1, rt1);                             \
-    temp2 = mipsdsp_##func(rs2, rt2);                             \
-    temp3 = mipsdsp_##func(rs3, rt3);                             \
-                                                                  \
-    return MIPSDSP_RETURN32_8(temp3, temp2, temp1, temp0);        \
-}
-
-#define ARITH_QB_ENV(name, func) \
-target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt, \
-                                CPUMIPSState *env)          \
-{                                                           \
-    uint8_t  rs0, rs1, rs2, rs3;                            \
-    uint8_t  rt0, rt1, rt2, rt3;                            \
-    uint8_t  temp0, temp1, temp2, temp3;                    \
-                                                            \
-    MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);              \
-    MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);              \
-                                                            \
-    temp0 = mipsdsp_##func(rs0, rt0, env);                  \
-    temp1 = mipsdsp_##func(rs1, rt1, env);                  \
-    temp2 = mipsdsp_##func(rs2, rt2, env);                  \
-    temp3 = mipsdsp_##func(rs3, rt3, env);                  \
-                                                            \
-    return MIPSDSP_RETURN32_8(temp3, temp2, temp1, temp0);  \
-}
-
-ARITH_QB(adduh, rshift1_add_u8);
-ARITH_QB(adduh_r, rrshift1_add_u8);
-
-ARITH_QB_ENV(addu, add_u8);
-ARITH_QB_ENV(addu_s, sat_add_u8);
-
-#undef ADDU_QB
-#undef ADDU_QB_ENV
-
-#if defined(TARGET_MIPS64)
-#define ARITH_OB(name, func) \
-target_ulong helper_##name##_ob(target_ulong rs, target_ulong rt) \
-{                                                                 \
-    int i;                                                        \
-    uint8_t rs_t[8], rt_t[8];                                     \
-    uint8_t temp[8];                                              \
-    uint64_t result;                                              \
-                                                                  \
-    result = 0;                                                   \
-                                                                  \
-    for (i = 0; i < 8; i++) {                                     \
-        rs_t[i] = (rs >> (8 * i)) & MIPSDSP_Q0;                   \
-        rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;                   \
-        temp[i] = mipsdsp_##func(rs_t[i], rt_t[i]);               \
-        result |= (uint64_t)temp[i] << (8 * i);                   \
-    }                                                             \
-                                                                  \
-    return result;                                                \
-}
-
-#define ARITH_OB_ENV(name, func) \
-target_ulong helper_##name##_ob(target_ulong rs, target_ulong rt, \
-                                CPUMIPSState *env)                \
-{                                                                 \
-    int i;                                                        \
-    uint8_t rs_t[8], rt_t[8];                                     \
-    uint8_t temp[8];                                              \
-    uint64_t result;                                              \
-                                                                  \
-    result = 0;                                                   \
-                                                                  \
-    for (i = 0; i < 8; i++) {                                     \
-        rs_t[i] = (rs >> (8 * i)) & MIPSDSP_Q0;                   \
-        rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;                   \
-        temp[i] = mipsdsp_##func(rs_t[i], rt_t[i], env);          \
-        result |= (uint64_t)temp[i] << (8 * i);                   \
-    }                                                             \
-                                                                  \
-    return result;                                                \
-}
-
-ARITH_OB_ENV(addu, add_u8);
-ARITH_OB_ENV(addu_s, sat_add_u8);
-
-ARITH_OB(adduh, rshift1_add_u8);
-ARITH_OB(adduh_r, rrshift1_add_u8);
-
-ARITH_OB_ENV(subu, sub_u8);
-ARITH_OB_ENV(subu_s, satu8_sub);
-
-ARITH_OB(subuh, rshift1_sub_u8);
-ARITH_OB(subuh_r, rrshift1_sub_u8);
-
-#undef ARITH_OB
-#undef ARITH_OB_ENV
-
-#endif
-
-#define SUBU_QB(name, func) \
-target_ulong helper_##name##_qb(target_ulong rs,               \
-                                target_ulong rt,               \
-                                CPUMIPSState *env)             \
-{                                                              \
-    uint8_t rs3, rs2, rs1, rs0;                                \
-    uint8_t rt3, rt2, rt1, rt0;                                \
-    uint8_t tempD, tempC, tempB, tempA;                        \
-                                                               \
-    MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);                 \
-    MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);                 \
-                                                               \
-    tempD = mipsdsp_##func(rs3, rt3, env);                     \
-    tempC = mipsdsp_##func(rs2, rt2, env);                     \
-    tempB = mipsdsp_##func(rs1, rt1, env);                     \
-    tempA = mipsdsp_##func(rs0, rt0, env);                     \
-                                                               \
-    return MIPSDSP_RETURN32_8(tempD, tempC, tempB, tempA);     \
-}
-
-SUBU_QB(subu, sub_u8);
-SUBU_QB(subu_s, satu8_sub);
-
-#undef SUBU_QB
-
 #define SUBUH_QB(name, var) \
 target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt) \
 {                                                                 \
@@ -4043,7 +3892,6 @@ target_ulong helper_rddsp(target_ulong masknum, CPUMIPSState *env)
 #undef MIPSDSP_SPLIT32_8
 #undef MIPSDSP_SPLIT32_16
 
-#undef MIPSDSP_RETURN32
 #undef MIPSDSP_RETURN32_8
 #undef MIPSDSP_RETURN32_16
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 5/7] target-mips: use DSP unions for unary DSP operators
  2012-11-16 11:04 [Qemu-devel] [PATCH 0/7] target-mips: DSP ASE fixes and cleanup Aurelien Jarno
                   ` (3 preceding siblings ...)
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 4/7] target-mips: use DSP unions for binary DSP operators Aurelien Jarno
@ 2012-11-16 11:04 ` Aurelien Jarno
  2012-12-05  4:58   ` Johnson, Eric
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 6/7] target-mips: use DSP unions for reduction add instructions Aurelien Jarno
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 7/7] target-mips: implement DSP (d)append sub-class with TCG Aurelien Jarno
  6 siblings, 1 reply; 17+ messages in thread
From: Aurelien Jarno @ 2012-11-16 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

This allow to reduce the number of macros.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/dsp_helper.c |  124 ++++++++++++++++------------------------------
 1 file changed, 42 insertions(+), 82 deletions(-)

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 931ca70..3bd2d35 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -1139,6 +1139,48 @@ static inline int32_t mipsdsp_cmpu_lt(uint32_t a, uint32_t b)
 #endif
 
 /** DSP Arithmetic Sub-class insns **/
+#define MIPSDSP32_UNOP_ENV(name, func, element)                            \
+target_ulong helper_##name(target_ulong rt, CPUMIPSState *env)             \
+{                                                                          \
+    DSP32Value dt;                                                         \
+    unsigned int i, n;                                                     \
+                                                                           \
+    n = sizeof(DSP32Value) / sizeof(dt.element[0]);                        \
+    dt.sw[0] = rt;                                                         \
+                                                                           \
+    for (i = 0 ; i < n ; i++) {                                            \
+        dt.element[i] = mipsdsp_##func(dt.element[i], env);                \
+    }                                                                      \
+                                                                           \
+    return (int32_t)dt.sw[0];                                              \
+}
+MIPSDSP32_UNOP_ENV(absq_s_ph, sat_abs16, sh)
+MIPSDSP32_UNOP_ENV(absq_s_qb, sat_abs8, sb)
+MIPSDSP32_UNOP_ENV(absq_s_w, sat_abs32, sw)
+#undef MIPSDSP32_UNOP_ENV
+
+#if defined(TARGET_MIPS64)
+#define MIPSDSP64_UNOP_ENV(name, func, element)                            \
+target_ulong helper_##name(target_ulong rt, CPUMIPSState *env)             \
+{                                                                          \
+    DSP64Value dt;                                                         \
+    unsigned int i, n;                                                     \
+                                                                           \
+    n = sizeof(DSP64Value) / sizeof(dt.element[0]);                        \
+    dt.sl[0] = rt;                                                         \
+                                                                           \
+    for (i = 0 ; i < n ; i++) {                                            \
+        dt.element[i] = mipsdsp_##func(dt.element[i], env);                \
+    }                                                                      \
+                                                                           \
+    return dt.sl[0];                                                       \
+}
+MIPSDSP64_UNOP_ENV(absq_s_ob, sat_abs8, sb)
+MIPSDSP64_UNOP_ENV(absq_s_qh, sat_abs16, sh)
+MIPSDSP64_UNOP_ENV(absq_s_pw, sat_abs32, sw)
+#undef MIPSDSP64_UNOP_ENV
+#endif
+
 #define MIPSDSP32_BINOP(name, func, element)                               \
 target_ulong helper_##name(target_ulong rs, target_ulong rt)               \
 {                                                                          \
@@ -1260,16 +1302,6 @@ MIPSDSP64_BINOP_ENV(subu_s_qh, satu16_sub_u16_u16, uh);
 
 #endif
 
-target_ulong helper_absq_s_w(target_ulong rt, CPUMIPSState *env)
-{
-    uint32_t rd;
-
-    rd = mipsdsp_sat_abs32(rt, env);
-
-    return (target_ulong)rd;
-}
-
-
 #define SUBUH_QB(name, var) \
 target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt) \
 {                                                                 \
@@ -1377,78 +1409,6 @@ target_ulong helper_raddu_l_ob(target_ulong rs)
 }
 #endif
 
-target_ulong helper_absq_s_qb(target_ulong rt, CPUMIPSState *env)
-{
-    uint8_t tempD, tempC, tempB, tempA;
-
-    MIPSDSP_SPLIT32_8(rt, tempD, tempC, tempB, tempA);
-
-    tempD = mipsdsp_sat_abs8(tempD, env);
-    tempC = mipsdsp_sat_abs8(tempC, env);
-    tempB = mipsdsp_sat_abs8(tempB, env);
-    tempA = mipsdsp_sat_abs8(tempA, env);
-
-    return MIPSDSP_RETURN32_8(tempD, tempC, tempB, tempA);
-}
-
-target_ulong helper_absq_s_ph(target_ulong rt, CPUMIPSState *env)
-{
-    uint16_t tempB, tempA;
-
-    MIPSDSP_SPLIT32_16(rt, tempB, tempA);
-
-    tempB = mipsdsp_sat_abs16 (tempB, env);
-    tempA = mipsdsp_sat_abs16 (tempA, env);
-
-    return MIPSDSP_RETURN32_16(tempB, tempA);
-}
-
-#if defined(TARGET_MIPS64)
-target_ulong helper_absq_s_ob(target_ulong rt, CPUMIPSState *env)
-{
-    int i;
-    int8_t temp[8];
-    uint64_t result;
-
-    for (i = 0; i < 8; i++) {
-        temp[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
-        temp[i] = mipsdsp_sat_abs8(temp[i], env);
-    }
-
-    for (i = 0; i < 8; i++) {
-        result = (uint64_t)(uint8_t)temp[i] << (8 * i);
-    }
-
-    return result;
-}
-
-target_ulong helper_absq_s_qh(target_ulong rt, CPUMIPSState *env)
-{
-    int16_t tempD, tempC, tempB, tempA;
-
-    MIPSDSP_SPLIT64_16(rt, tempD, tempC, tempB, tempA);
-
-    tempD = mipsdsp_sat_abs16(tempD, env);
-    tempC = mipsdsp_sat_abs16(tempC, env);
-    tempB = mipsdsp_sat_abs16(tempB, env);
-    tempA = mipsdsp_sat_abs16(tempA, env);
-
-    return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);
-}
-
-target_ulong helper_absq_s_pw(target_ulong rt, CPUMIPSState *env)
-{
-    int32_t tempB, tempA;
-
-    MIPSDSP_SPLIT64_32(rt, tempB, tempA);
-
-    tempB = mipsdsp_sat_abs32(tempB, env);
-    tempA = mipsdsp_sat_abs32(tempA, env);
-
-    return MIPSDSP_RETURN64_32(tempB, tempA);
-}
-#endif
-
 #define PRECR_QB_PH(name, a, b)\
 target_ulong helper_##name##_qb_ph(target_ulong rs, target_ulong rt) \
 {                                                                    \
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 6/7] target-mips: use DSP unions for reduction add instructions
  2012-11-16 11:04 [Qemu-devel] [PATCH 0/7] target-mips: DSP ASE fixes and cleanup Aurelien Jarno
                   ` (4 preceding siblings ...)
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 5/7] target-mips: use DSP unions for unary " Aurelien Jarno
@ 2012-11-16 11:04 ` Aurelien Jarno
  2012-12-05  4:58   ` Johnson, Eric
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 7/7] target-mips: implement DSP (d)append sub-class with TCG Aurelien Jarno
  6 siblings, 1 reply; 17+ messages in thread
From: Aurelien Jarno @ 2012-11-16 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/dsp_helper.c |   32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 3bd2d35..474c249 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -1381,31 +1381,29 @@ target_ulong helper_modsub(target_ulong rs, target_ulong rt)
 
 target_ulong helper_raddu_w_qb(target_ulong rs)
 {
-    uint8_t  rs3, rs2, rs1, rs0;
-    uint16_t temp;
-
-    MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);
-
-    temp = (uint16_t)rs3 + (uint16_t)rs2 + (uint16_t)rs1 + (uint16_t)rs0;
+    target_ulong ret = 0;
+    DSP32Value ds;
+    unsigned int i;
 
-    return (target_ulong)temp;
+    ds.uw[0] = rs;
+    for (i = 0 ; i < 4 ; i++) {
+        ret += ds.ub[i];
+    }
+    return ret;
 }
 
 #if defined(TARGET_MIPS64)
 target_ulong helper_raddu_l_ob(target_ulong rs)
 {
-    int i;
-    uint16_t rs_t[8];
-    uint64_t temp;
-
-    temp = 0;
+    target_ulong ret = 0;
+    DSP64Value ds;
+    unsigned int i;
 
-    for (i = 0; i < 8; i++) {
-        rs_t[i] = (rs >> (8 * i)) & MIPSDSP_Q0;
-        temp += (uint64_t)rs_t[i];
+    ds.ul[0] = rs;
+    for (i = 0 ; i < 8 ; i++) {
+        ret += ds.ub[i];
     }
-
-    return temp;
+    return ret;
 }
 #endif
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 7/7] target-mips: implement DSP (d)append sub-class with TCG
  2012-11-16 11:04 [Qemu-devel] [PATCH 0/7] target-mips: DSP ASE fixes and cleanup Aurelien Jarno
                   ` (5 preceding siblings ...)
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 6/7] target-mips: use DSP unions for reduction add instructions Aurelien Jarno
@ 2012-11-16 11:04 ` Aurelien Jarno
  2012-12-05  4:58   ` Johnson, Eric
  6 siblings, 1 reply; 17+ messages in thread
From: Aurelien Jarno @ 2012-11-16 11:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

DSP instruction from the (d)append sub-class can be implemented with
TCG. Use a different function for these instructions are they are quite
different from compare-pick sub-class.

Fix BALIGN instruction for negative value, where the value should be
zero-extended before being shift to the right.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 target-mips/dsp_helper.c |   67 -----------------------
 target-mips/helper.h     |   13 -----
 target-mips/translate.c  |  133 ++++++++++++++++++++++++++++++----------------
 3 files changed, 87 insertions(+), 126 deletions(-)

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 474c249..22bbfa1 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -3140,73 +3140,6 @@ PICK_INSN(pick_pw, 2, MIPSDSP_LLO, 32, 0);
 #endif
 #undef PICK_INSN
 
-#define APPEND_INSN(name, ret_32) \
-target_ulong helper_##name(target_ulong rt, target_ulong rs, uint32_t sa) \
-{                                                                         \
-    target_ulong temp;                                                    \
-                                                                          \
-    if (ret_32) {                                                         \
-        temp = ((rt & MIPSDSP_LLO) << sa) |                               \
-               ((rs & MIPSDSP_LLO) & ((0x01 << sa) - 1));                 \
-        temp = (target_long)(int32_t)(temp & MIPSDSP_LLO);                \
-    } else {                                                              \
-        temp = (rt << sa) | (rs & ((0x01 << sa) - 1));                    \
-    }                                                                     \
-                                                                          \
-    return temp;                                                          \
-}
-
-APPEND_INSN(append, 1);
-#ifdef TARGET_MIPS64
-APPEND_INSN(dappend, 0);
-#endif
-#undef APPEND_INSN
-
-#define PREPEND_INSN(name, or_val, ret_32)                    \
-target_ulong helper_##name(target_ulong rs, target_ulong rt,  \
-                           uint32_t sa)                       \
-{                                                             \
-    sa |= or_val;                                             \
-                                                              \
-    if (1) {                                                  \
-        return (target_long)(int32_t)(uint32_t)               \
-            (((rs & MIPSDSP_LLO) << (32 - sa)) |              \
-             ((rt & MIPSDSP_LLO) >> sa));                     \
-    } else {                                                  \
-        return (rs << (64 - sa)) | (rt >> sa);                \
-    }                                                         \
-}
-
-PREPEND_INSN(prepend, 0, 1);
-#ifdef TARGET_MIPS64
-PREPEND_INSN(prependw, 0, 0);
-PREPEND_INSN(prependd, 0x20, 0);
-#endif
-#undef PREPEND_INSN
-
-#define BALIGN_INSN(name, filter, ret32) \
-target_ulong helper_##name(target_ulong rs, target_ulong rt, uint32_t bp) \
-{                                                                         \
-    bp = bp & 0x03;                                                       \
-                                                                          \
-    if ((bp & 1) == 0) {                                                  \
-        return rt;                                                        \
-    } else {                                                              \
-        if (ret32) {                                                      \
-            return (target_long)(int32_t)((rt << (8 * bp)) |              \
-                                          (rs >> (8 * (4 - bp))));        \
-        } else {                                                          \
-            return (rt << (8 * bp)) | (rs >> (8 * (8 - bp)));             \
-        }                                                                 \
-    }                                                                     \
-}
-
-BALIGN_INSN(balign, 0x03, 1);
-#if defined(TARGET_MIPS64)
-BALIGN_INSN(dbalign, 0x07, 0);
-#endif
-#undef BALIGN_INSN
-
 target_ulong helper_packrl_ph(target_ulong rs, target_ulong rt)
 {
     uint32_t rsl, rth;
diff --git a/target-mips/helper.h b/target-mips/helper.h
index acf9ebd..4373ac5 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -654,19 +654,6 @@ DEF_HELPER_FLAGS_3(pick_ob, 0, tl, tl, tl, env)
 DEF_HELPER_FLAGS_3(pick_qh, 0, tl, tl, tl, env)
 DEF_HELPER_FLAGS_3(pick_pw, 0, tl, tl, tl, env)
 #endif
-DEF_HELPER_FLAGS_3(append, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_3(dappend, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
-#endif
-DEF_HELPER_FLAGS_3(prepend, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_3(prependd, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
-DEF_HELPER_FLAGS_3(prependw, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
-#endif
-DEF_HELPER_FLAGS_3(balign, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
-#if defined(TARGET_MIPS64)
-DEF_HELPER_FLAGS_3(dbalign, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
-#endif
 DEF_HELPER_FLAGS_2(packrl_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 #if defined(TARGET_MIPS64)
 DEF_HELPER_FLAGS_2(packrl_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 910dd16..624d5a5 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -336,7 +336,7 @@ enum {
     /* DSP Bit/Manipulation Sub-class */
     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
     OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
-    /* MIPS DSP Compare-Pick Sub-class */
+    /* MIPS DSP Append Sub-class */
     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
     OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
@@ -543,7 +543,7 @@ enum {
 
 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 enum {
-    /* MIPS DSP Compare-Pick Sub-class */
+    /* MIPS DSP Append Sub-class */
     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
@@ -667,7 +667,7 @@ enum {
 
 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 enum {
-    /* DSP Compare-Pick Sub-class */
+    /* DSP Append Sub-class */
     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
@@ -13844,7 +13844,6 @@ static void gen_mipsdsp_add_cmp_pick(CPUMIPSState *env, DisasContext *ctx,
                                      int ret, int v1, int v2, int check_ret)
 {
     const char *opn = "mipsdsp add compare pick";
-    TCGv_i32 t0;
     TCGv t1;
     TCGv v1_t;
     TCGv v2_t;
@@ -13855,7 +13854,6 @@ static void gen_mipsdsp_add_cmp_pick(CPUMIPSState *env, DisasContext *ctx,
         return;
     }
 
-    t0 = tcg_temp_new_i32();
     t1 = tcg_temp_new();
     v1_t = tcg_temp_new();
     v2_t = tcg_temp_new();
@@ -13864,26 +13862,6 @@ static void gen_mipsdsp_add_cmp_pick(CPUMIPSState *env, DisasContext *ctx,
     gen_load_gpr(v2_t, v2);
 
     switch (op1) {
-    case OPC_APPEND_DSP:
-        switch (op2) {
-        case OPC_APPEND:
-            tcg_gen_movi_i32(t0, v2);
-            gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
-            break;
-        case OPC_PREPEND:
-            tcg_gen_movi_i32(t0, v2);
-            gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
-            break;
-        case OPC_BALIGN:
-            tcg_gen_movi_i32(t0, v2);
-            gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
-            break;
-        default:            /* Invid */
-            MIPS_INVAL("MASK APPEND");
-            generate_exception(ctx, EXCP_RI);
-            break;
-        }
-        break;
     case OPC_CMPU_EQ_QB_DSP:
         switch (op2) {
         case OPC_CMPU_EQ_QB:
@@ -14041,23 +14019,95 @@ static void gen_mipsdsp_add_cmp_pick(CPUMIPSState *env, DisasContext *ctx,
             break;
         }
         break;
+#endif
+    }
+
+    tcg_temp_free(t1);
+    tcg_temp_free(v1_t);
+    tcg_temp_free(v2_t);
+
+    (void)opn; /* avoid a compiler warning */
+    MIPS_DEBUG("%s", opn);
+}
+
+static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
+                               uint32_t op1, int rt, int rs, int sa)
+{
+    const char *opn = "mipsdsp append/dappend";
+    TCGv t0;
+
+    check_dspr2(env, ctx);
+
+    if (rt == 0) {
+        /* Treat as NOP. */
+        MIPS_DEBUG("NOP");
+        return;
+    }
+
+    t0 = tcg_temp_new();
+    gen_load_gpr(t0, rs);
+
+    switch (op1) {
+    case OPC_APPEND_DSP:
+        switch (MASK_APPEND(ctx->opcode)) {
+        case OPC_APPEND:
+            if (sa != 0) {
+                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
+            }
+            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
+            break;
+        case OPC_PREPEND:
+            if (sa != 0) {
+                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
+                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
+                tcg_gen_shli_tl(t0, t0, 32 - sa);
+                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
+            }
+            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
+            break;
+        case OPC_BALIGN:
+            sa &= 3;
+            if (sa != 0 && sa != 2) {
+                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
+                tcg_gen_ext32u_tl(t0, t0);
+                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
+                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
+            }
+            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
+            break;
+        default:            /* Invalid */
+            MIPS_INVAL("MASK APPEND");
+            generate_exception(ctx, EXCP_RI);
+            break;
+        }
+        break;
+#ifdef TARGET_MIPS64
     case OPC_DAPPEND_DSP:
-        switch (op2) {
+        switch (MASK_DAPPEND(ctx->opcode)) {
         case OPC_DAPPEND:
-            tcg_gen_movi_i32(t0, v2);
-            gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
+            if (sa != 0) {
+                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
+            }
             break;
         case OPC_PREPENDD:
-            tcg_gen_movi_i32(t0, v2);
-            gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
+            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
+            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
+            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
             break;
         case OPC_PREPENDW:
-            tcg_gen_movi_i32(t0, v2);
-            gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
+            if (sa != 0) {
+                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
+                tcg_gen_shli_tl(t0, t0, 64 - sa);
+                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
+            }
             break;
         case OPC_DBALIGN:
-            tcg_gen_movi_i32(t0, v2);
-            gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
+            sa &= 7;
+            if (sa != 0 && sa != 2 && sa != 4) {
+                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
+                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
+                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
+            }
             break;
         default:            /* Invalid */
             MIPS_INVAL("MASK DAPPEND");
@@ -14067,12 +14117,7 @@ static void gen_mipsdsp_add_cmp_pick(CPUMIPSState *env, DisasContext *ctx,
         break;
 #endif
     }
-
-    tcg_temp_free_i32(t0);
-    tcg_temp_free(t1);
-    tcg_temp_free(v1_t);
-    tcg_temp_free(v2_t);
-
+    tcg_temp_free(t0);
     (void)opn; /* avoid a compiler warning */
     MIPS_DEBUG("%s", opn);
 }
@@ -14892,9 +14937,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             }
             break;
         case OPC_APPEND_DSP:
-            check_dspr2(env, ctx);
-            op2 = MASK_APPEND(ctx->opcode);
-            gen_mipsdsp_add_cmp_pick(env, ctx, op1, op2, rt, rs, rd, 1);
+            gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
             break;
         case OPC_EXTR_W_DSP:
             op2 = MASK_EXTR_W(ctx->opcode);
@@ -15068,9 +15111,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
             }
             break;
         case OPC_DAPPEND_DSP:
-            check_dspr2(ctx);
-            op2 = MASK_DAPPEND(ctx->opcode);
-            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
+            gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
             break;
         case OPC_DEXTR_W_DSP:
             op2 = MASK_DEXTR_W(ctx->opcode);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] target-mips: generate a reserved instruction exception on CPU without DSP
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 2/7] target-mips: generate a reserved instruction exception on CPU without DSP Aurelien Jarno
@ 2012-11-16 22:02   ` Richard Henderson
  2012-11-21  6:51     ` Johnson, Eric
  0 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2012-11-16 22:02 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 11/16/2012 03:04 AM, Aurelien Jarno wrote:
> +static inline void check_dsp(CPUMIPSState *env, DisasContext *ctx)
>  {
>      if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
> -        generate_exception(ctx, EXCP_DSPDIS);
> +        if (env->insn_flags & ASE_DSP) {
> +            generate_exception(ctx, EXCP_DSPDIS);
> +        } else {
> +            generate_exception(ctx, EXCP_RI);
> +        }

Perhaps it would make more sense to copy env->insn_flags into
a new field in DisasContext at the start of translation, rather
than modify 300 instances to pass around a second pointer?


r~

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 4/7] target-mips: use DSP unions for binary DSP operators
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 4/7] target-mips: use DSP unions for binary DSP operators Aurelien Jarno
@ 2012-11-16 22:04   ` Richard Henderson
  2012-12-05  4:58   ` Johnson, Eric
  1 sibling, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2012-11-16 22:04 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: qemu-devel

On 11/16/2012 03:04 AM, Aurelien Jarno wrote:
> +    return (int32_t)ds.sw[0];                                              \

Why the extra cast?  You know what type .sw is...


r~

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 1/7] target-mips: fix DSP loads with rd = 0
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 1/7] target-mips: fix DSP loads with rd = 0 Aurelien Jarno
@ 2012-11-21  6:28   ` Johnson, Eric
  0 siblings, 0 replies; 17+ messages in thread
From: Johnson, Eric @ 2012-11-21  6:28 UTC (permalink / raw)
  To: Aurelien Jarno, qemu-devel@nongnu.org

> -----Original Message-----
> From: qemu-devel-bounces+ericj=mips.com@nongnu.org [mailto:qemu-devel-
> bounces+ericj=mips.com@nongnu.org] On Behalf Of Aurelien Jarno
> Sent: Friday, November 16, 2012 3:04 AM
> To: qemu-devel@nongnu.org
> Cc: Aurelien Jarno
> Subject: [Qemu-devel] [PATCH 1/7] target-mips: fix DSP loads with rd = 0
> 
> When rd is 0, which still need to do the actually load to possibly
> generate a TLB exception.
> 
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-mips/translate.c |    5 -----
>  1 file changed, 5 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 01b48fa..c3e00c5 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -12631,11 +12631,6 @@ static void gen_mipsdsp_ld(CPUMIPSState *env,
> DisasContext *ctx, uint32_t opc,
>      const char *opn = "ldx";
>      TCGv t0;
> 
> -    if (rd == 0) {
> -        MIPS_DEBUG("NOP");
> -        return;
> -    }
> -
>      check_dsp(ctx);
>      t0 = tcg_temp_new();
> 
> --
> 1.7.10.4
> 

Reviewed-by: Eric Johnson <ericj@mips.com>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] target-mips: generate a reserved instruction exception on CPU without DSP
  2012-11-16 22:02   ` Richard Henderson
@ 2012-11-21  6:51     ` Johnson, Eric
  0 siblings, 0 replies; 17+ messages in thread
From: Johnson, Eric @ 2012-11-21  6:51 UTC (permalink / raw)
  To: Richard Henderson, Aurelien Jarno; +Cc: qemu-devel@nongnu.org

> -----Original Message-----
> From: qemu-devel-bounces+ericj=mips.com@nongnu.org [mailto:qemu-devel-
> bounces+ericj=mips.com@nongnu.org] On Behalf Of Richard Henderson
> Sent: Friday, November 16, 2012 2:03 PM
> To: Aurelien Jarno
> Cc: qemu-devel@nongnu.org
> Subject: Re: [Qemu-devel] [PATCH 2/7] target-mips: generate a reserved
> instruction exception on CPU without DSP
> 
> On 11/16/2012 03:04 AM, Aurelien Jarno wrote:
> > +static inline void check_dsp(CPUMIPSState *env, DisasContext *ctx)
> >  {
> >      if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
> > -        generate_exception(ctx, EXCP_DSPDIS);
> > +        if (env->insn_flags & ASE_DSP) {
> > +            generate_exception(ctx, EXCP_DSPDIS);
> > +        } else {
> > +            generate_exception(ctx, EXCP_RI);
> > +        }
> 
> Perhaps it would make more sense to copy env->insn_flags into
> a new field in DisasContext at the start of translation, rather
> than modify 300 instances to pass around a second pointer?
> 
> 
> r~

I agree copying insn_flags to a new field is probably a cleaner way to go.

Also minor complaints from checkpatch.pl:
$ upstream/scripts/checkpatch.pl 'patches/dsp-ase-aurelien/Qemu-devel PATCH 27 target-mips generate a reservedinstruction exception on CPU without DSP.txt'
WARNING: line over 80 characters
#54: FILE: target-mips/translate.c:2582:
+static void gen_HILO (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int reg)

WARNING: space prohibited between function name and open parenthesis '('
#54: FILE: target-mips/translate.c:2582:
+static void gen_HILO (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int reg)

WARNING: space prohibited between function name and open parenthesis '('
#73: FILE: target-mips/translate.c:2661:
+static void gen_muldiv (CPUMIPSState *env, DisasContext *ctx,

total: 0 errors, 3 warnings, 1825 lines checked

patches/dsp-ase-aurelien/Qemu-devel PATCH 27 target-mips generate a reservedinstruction exception on CPU without DSP.txt has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

-Eric

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 3/7] target-mips: add unions to access DSP elements
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 3/7] target-mips: add unions to access DSP elements Aurelien Jarno
@ 2012-11-21  6:54   ` Johnson, Eric
  0 siblings, 0 replies; 17+ messages in thread
From: Johnson, Eric @ 2012-11-21  6:54 UTC (permalink / raw)
  To: Aurelien Jarno, qemu-devel@nongnu.org

> -----Original Message-----
> From: qemu-devel-bounces+ericj=mips.com@nongnu.org [mailto:qemu-devel-
> bounces+ericj=mips.com@nongnu.org] On Behalf Of Aurelien Jarno
> Sent: Friday, November 16, 2012 3:04 AM
> To: qemu-devel@nongnu.org
> Cc: Aurelien Jarno
> Subject: [Qemu-devel] [PATCH 3/7] target-mips: add unions to access DSP
> elements
> 
> Instead of playing with bit shifting, add two unions (one for 32-bit
> values, one for 64-bit ones) to access all the DSP elements with the
> correct type.
> 
> This make the code easier to read and less error prone, and allow GCC
> to vectorize the code in some cases.
> 
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-mips/dsp_helper.c |   22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index e7949c2..8015d8d 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -20,6 +20,28 @@
>  #include "cpu.h"
>  #include "helper.h"
> 
> +/* As the byte ordering doesn't matter, i.e. all columns are treated
> +   identically, these unions can be used directly.  */
> +typedef union {
> +    uint8_t  ub[4];
> +    int8_t   sb[4];
> +    uint16_t uh[2];
> +    int16_t  sh[2];
> +    uint32_t uw[1];
> +    int32_t  sw[1];
> +} DSP32Value;
> +
> +typedef union {
> +    uint8_t  ub[8];
> +    int8_t   sb[8];
> +    uint16_t uh[4];
> +    int16_t  sh[4];
> +    uint32_t uw[2];
> +    int32_t  sw[2];
> +    uint64_t ul[1];
> +    int64_t  sl[1];
> +} DSP64Value;
> +
>  /*** MIPS DSP internal functions begin ***/
>  #define MIPSDSP_ABS(x) (((x) >= 0) ? x : -x)
>  #define MIPSDSP_OVERFLOW(a, b, c, d) (!(!((a ^ b ^ -1) & (a ^ c) & d)))
> --
> 1.7.10.4
> 

Reviewed-by: Eric Johnson <ericj@mips.com>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 4/7] target-mips: use DSP unions for binary DSP operators
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 4/7] target-mips: use DSP unions for binary DSP operators Aurelien Jarno
  2012-11-16 22:04   ` Richard Henderson
@ 2012-12-05  4:58   ` Johnson, Eric
  1 sibling, 0 replies; 17+ messages in thread
From: Johnson, Eric @ 2012-12-05  4:58 UTC (permalink / raw)
  To: Aurelien Jarno, qemu-devel@nongnu.org

> -----Original Message-----
> From: qemu-devel-bounces+ericj=mips.com@nongnu.org [mailto:qemu-devel-
> bounces+ericj=mips.com@nongnu.org] On Behalf Of Aurelien Jarno
> Sent: Friday, November 16, 2012 3:04 AM
> To: qemu-devel@nongnu.org
> Cc: Aurelien Jarno
> Subject: [Qemu-devel] [PATCH 4/7] target-mips: use DSP unions for binary
> DSP operators
> 
> This allow to reduce the number of macros.
> 
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-mips/dsp_helper.c |  384 ++++++++++++++---------------------------
> -----
>  1 file changed, 116 insertions(+), 268 deletions(-)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index 8015d8d..931ca70 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -1107,7 +1107,6 @@ static inline int32_t mipsdsp_cmpu_lt(uint32_t a,
> uint32_t b)
>          b = num & MIPSDSP_LO;               \
>      } while (0)
> 
> -#define MIPSDSP_RETURN32(a)             ((target_long)(int32_t)a)
>  #define MIPSDSP_RETURN32_8(a, b, c, d)  ((target_long)(int32_t) \
>                                           (((uint32_t)a << 24) | \
>                                           (((uint32_t)b << 16) | \
> @@ -1140,119 +1139,127 @@ static inline int32_t mipsdsp_cmpu_lt(uint32_t
> a, uint32_t b)
>  #endif
> 
>  /** DSP Arithmetic Sub-class insns **/
> -#define ARITH_PH(name, func)                                      \
> -target_ulong helper_##name##_ph(target_ulong rs, target_ulong rt) \
> -{                                                                 \
> -    uint16_t  rsh, rsl, rth, rtl, temph, templ;                   \
> -                                                                  \
> -    MIPSDSP_SPLIT32_16(rs, rsh, rsl);                             \
> -    MIPSDSP_SPLIT32_16(rt, rth, rtl);                             \
> -                                                                  \
> -    temph = mipsdsp_##func(rsh, rth);                             \
> -    templ = mipsdsp_##func(rsl, rtl);                             \
> -                                                                  \
> -    return MIPSDSP_RETURN32_16(temph, templ);                     \
> -}
> -
> -#define ARITH_PH_ENV(name, func)                                  \
> -target_ulong helper_##name##_ph(target_ulong rs, target_ulong rt, \
> -                                CPUMIPSState *env)                \
> -{                                                                 \
> -    uint16_t  rsh, rsl, rth, rtl, temph, templ;                   \
> -                                                                  \
> -    MIPSDSP_SPLIT32_16(rs, rsh, rsl);                             \
> -    MIPSDSP_SPLIT32_16(rt, rth, rtl);                             \
> -                                                                  \
> -    temph = mipsdsp_##func(rsh, rth, env);                        \
> -    templ = mipsdsp_##func(rsl, rtl, env);                        \
> -                                                                  \
> -    return MIPSDSP_RETURN32_16(temph, templ);                     \
> -}
> -
> -
> -ARITH_PH_ENV(addq, add_i16);
> -ARITH_PH_ENV(addq_s, sat_add_i16);
> -ARITH_PH_ENV(addu, add_u16);
> -ARITH_PH_ENV(addu_s, sat_add_u16);
> -
> -ARITH_PH(addqh, rshift1_add_q16);
> -ARITH_PH(addqh_r, rrshift1_add_q16);
> -
> -ARITH_PH_ENV(subq, sub_i16);
> -ARITH_PH_ENV(subq_s, sat16_sub);
> -ARITH_PH_ENV(subu, sub_u16_u16);
> -ARITH_PH_ENV(subu_s, satu16_sub_u16_u16);
> -
> -ARITH_PH(subqh, rshift1_sub_q16);
> -ARITH_PH(subqh_r, rrshift1_sub_q16);
> -
> -#undef ARITH_PH
> -#undef ARITH_PH_ENV
> +#define MIPSDSP32_BINOP(name, func, element)
> \
> +target_ulong helper_##name(target_ulong rs, target_ulong rt)
> \
> +{
> \
> +    DSP32Value ds, dt;
> \
> +    unsigned int i, n;
> \
> +
> \
> +    n = sizeof(DSP32Value) / sizeof(ds.element[0]);
> \
> +    ds.sw[0] = rs;
> \
> +    dt.sw[0] = rt;
> \
> +
> \
> +    for (i = 0 ; i < n ; i++) {
> \
> +        ds.element[i] = mipsdsp_##func(ds.element[i], dt.element[i]);
> \
> +    }
> \
> +
> \
> +    return (int32_t)ds.sw[0];
> \
> +}
> +MIPSDSP32_BINOP(addqh_ph, rshift1_add_q16, sh);
> +MIPSDSP32_BINOP(addqh_r_ph, rrshift1_add_q16, sh);
> +MIPSDSP32_BINOP(addqh_r_w, rrshift1_add_q32, sw);
> +MIPSDSP32_BINOP(addqh_w, rshift1_add_q32, sw);
> +MIPSDSP32_BINOP(adduh_qb, rshift1_add_u8, ub);
> +MIPSDSP32_BINOP(adduh_r_qb, rrshift1_add_u8, ub);
> +MIPSDSP32_BINOP(subqh_ph, rshift1_sub_q16, sh);
> +MIPSDSP32_BINOP(subqh_r_ph, rrshift1_sub_q16, sh);
> +MIPSDSP32_BINOP(subqh_r_w, rrshift1_sub_q32, sw);
> +MIPSDSP32_BINOP(subqh_w, rshift1_sub_q32, sw);
> +#undef MIPSDSP32_BINOP
> +
> +#define MIPSDSP32_BINOP_ENV(name, func, element)
> \
> +target_ulong helper_##name(target_ulong rs, target_ulong rt,
> \
> +                           CPUMIPSState *env)
> \
> +{
> \
> +    DSP32Value ds, dt;
> \
> +    unsigned int i, n;
> \
> +
> \
> +    n = sizeof(DSP32Value) / sizeof(ds.element[0]);
> \
> +    ds.sw[0] = rs;
> \
> +    dt.sw[0] = rt;
> \
> +
> \
> +    for (i = 0 ; i < n ; i++) {
> \
> +        ds.element[i] = mipsdsp_##func(ds.element[i], dt.element[i],
> env); \
> +    }
> \
> +
> \
> +    return (int32_t)ds.sw[0];
> \
> +}
> +MIPSDSP32_BINOP_ENV(addq_ph, add_i16, sh)
> +MIPSDSP32_BINOP_ENV(addq_s_ph, sat_add_i16, sh)
> +MIPSDSP32_BINOP_ENV(addq_s_w, sat_add_i32, sw);
> +MIPSDSP32_BINOP_ENV(addu_ph, add_u16, sh)
> +MIPSDSP32_BINOP_ENV(addu_qb, add_u8, ub);
> +MIPSDSP32_BINOP_ENV(addu_s_ph, sat_add_u16, sh)
> +MIPSDSP32_BINOP_ENV(addu_s_qb, sat_add_u8, ub);
> +MIPSDSP32_BINOP_ENV(subq_ph, sub_i16, sh);
> +MIPSDSP32_BINOP_ENV(subq_s_ph, sat16_sub, sh);
> +MIPSDSP32_BINOP_ENV(subq_s_w, sat32_sub, sw);
> +MIPSDSP32_BINOP_ENV(subu_ph, sub_u16_u16, sh);
> +MIPSDSP32_BINOP_ENV(subu_qb, sub_u8, ub);
> +MIPSDSP32_BINOP_ENV(subu_s_ph, satu16_sub_u16_u16, sh);
> +MIPSDSP32_BINOP_ENV(subu_s_qb, satu8_sub, ub);
> +#undef MIPSDSP32_BINOP_ENV
> 
>  #ifdef TARGET_MIPS64
> -#define ARITH_QH_ENV(name, func) \
> -target_ulong helper_##name##_qh(target_ulong rs, target_ulong rt, \
> -                                CPUMIPSState *env)           \
> -{                                                            \
> -    uint16_t rs3, rs2, rs1, rs0;                             \
> -    uint16_t rt3, rt2, rt1, rt0;                             \
> -    uint16_t tempD, tempC, tempB, tempA;                     \
> -                                                             \
> -    MIPSDSP_SPLIT64_16(rs, rs3, rs2, rs1, rs0);              \
> -    MIPSDSP_SPLIT64_16(rt, rt3, rt2, rt1, rt0);              \
> -                                                             \
> -    tempD = mipsdsp_##func(rs3, rt3, env);                   \
> -    tempC = mipsdsp_##func(rs2, rt2, env);                   \
> -    tempB = mipsdsp_##func(rs1, rt1, env);                   \
> -    tempA = mipsdsp_##func(rs0, rt0, env);                   \
> -                                                             \
> -    return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);  \
> -}
> -
> -ARITH_QH_ENV(addq, add_i16);
> -ARITH_QH_ENV(addq_s, sat_add_i16);
> -ARITH_QH_ENV(addu, add_u16);
> -ARITH_QH_ENV(addu_s, sat_add_u16);
> -
> -ARITH_QH_ENV(subq, sub_i16);
> -ARITH_QH_ENV(subq_s, sat16_sub);
> -ARITH_QH_ENV(subu, sub_u16_u16);
> -ARITH_QH_ENV(subu_s, satu16_sub_u16_u16);
> -
> -#undef ARITH_QH_ENV
> +#define MIPSDSP64_BINOP(name, func, element)
> \
> +target_ulong helper_##name(target_ulong rs, target_ulong rt)
> \
> +{
> \
> +    DSP64Value ds, dt;
> \
> +    unsigned int i, n;
> \
> +
> \
> +    n = sizeof(DSP64Value) / sizeof(ds.element[0]);
> \
> +    ds.sl[0] = rs;
> \
> +    dt.sl[0] = rt;
> \
> +
> \
> +    for (i = 0 ; i < n ; i++) {
> \
> +        ds.element[i] = mipsdsp_##func(ds.element[i], dt.element[i]);
> \
> +    }
> \
> +
> \
> +    return ds.sl[0];
> \
> +}
> +MIPSDSP64_BINOP(adduh_ob, rshift1_add_u8, ub);
> +MIPSDSP64_BINOP(adduh_r_ob, rrshift1_add_u8, ub);
> +MIPSDSP64_BINOP(subuh_ob, rshift1_sub_u8, ub);
> +MIPSDSP64_BINOP(subuh_r_ob, rrshift1_sub_u8, ub);
> +#undef MIPSDSP64_BINOP
> +
> +#define MIPSDSP64_BINOP_ENV(name, func, element)
> \
> +target_ulong helper_##name(target_ulong rs, target_ulong rt,
> \
> +                           CPUMIPSState *env)
> \
> +{
> \
> +    DSP64Value ds, dt;
> \
> +    unsigned int i, n;
> \
> +
> \
> +    n = sizeof(DSP64Value) / sizeof(ds.element[0]);
> \
> +    ds.sl[0] = rs;
> \
> +    dt.sl[0] = rt;
> \
> +
> \
> +    for (i = 0 ; i < n ; i++) {
> \
> +        ds.element[i] = mipsdsp_##func(ds.element[i], dt.element[i],
> env); \
> +    }
> \
> +
> \
> +    return ds.sl[0];
> \
> +}
> +MIPSDSP64_BINOP_ENV(addq_pw, add_i32, sw);
> +MIPSDSP64_BINOP_ENV(addq_qh, add_i16, sh);
> +MIPSDSP64_BINOP_ENV(addq_s_pw, sat_add_i32, sw);
> +MIPSDSP64_BINOP_ENV(addq_s_qh, sat_add_i16, sh);
> +MIPSDSP64_BINOP_ENV(addu_ob, add_u8, uh);
> +MIPSDSP64_BINOP_ENV(addu_qh, add_u16, uh);
> +MIPSDSP64_BINOP_ENV(addu_s_ob, sat_add_u8, uh);
> +MIPSDSP64_BINOP_ENV(addu_s_qh, sat_add_u16, uh);
> +MIPSDSP64_BINOP_ENV(subq_pw, sub32, sw);
> +MIPSDSP64_BINOP_ENV(subq_qh, sub_i16, sh);
> +MIPSDSP64_BINOP_ENV(subq_s_pw, sat32_sub, sw);
> +MIPSDSP64_BINOP_ENV(subq_s_qh, sat16_sub, sh);
> +MIPSDSP64_BINOP_ENV(subu_ob, sub_u8, uh);
> +MIPSDSP64_BINOP_ENV(subu_qh, sub_u16_u16, uh);
> +MIPSDSP64_BINOP_ENV(subu_s_ob, satu8_sub, uh);
> +MIPSDSP64_BINOP_ENV(subu_s_qh, satu16_sub_u16_u16, uh);
> +#undef MIPSDSP64_BINOP_ENV
> 
>  #endif
> 
> -#define ARITH_W(name, func) \
> -target_ulong helper_##name##_w(target_ulong rs, target_ulong rt) \
> -{                                                                \
> -    uint32_t rd;                                                 \
> -    rd = mipsdsp_##func(rs, rt);                                 \
> -    return MIPSDSP_RETURN32(rd);                                 \
> -}
> -
> -#define ARITH_W_ENV(name, func) \
> -target_ulong helper_##name##_w(target_ulong rs, target_ulong rt, \
> -                               CPUMIPSState *env)                \
> -{                                                                \
> -    uint32_t rd;                                                 \
> -    rd = mipsdsp_##func(rs, rt, env);                            \
> -    return MIPSDSP_RETURN32(rd);                                 \
> -}
> -
> -ARITH_W_ENV(addq_s, sat_add_i32);
> -
> -ARITH_W(addqh, rshift1_add_q32);
> -ARITH_W(addqh_r, rrshift1_add_q32);
> -
> -ARITH_W_ENV(subq_s, sat32_sub);
> -
> -ARITH_W(subqh, rshift1_sub_q32);
> -ARITH_W(subqh_r, rrshift1_sub_q32);
> -
> -#undef ARITH_W
> -#undef ARITH_W_ENV
> -
>  target_ulong helper_absq_s_w(target_ulong rt, CPUMIPSState *env)
>  {
>      uint32_t rd;
> @@ -1263,164 +1270,6 @@ target_ulong helper_absq_s_w(target_ulong rt,
> CPUMIPSState *env)
>  }
> 
> 
> -#if defined(TARGET_MIPS64)
> -
> -#define ARITH_PW_ENV(name, func) \
> -target_ulong helper_##name##_pw(target_ulong rs, target_ulong rt, \
> -                                CPUMIPSState *env)                \
> -{                                                                 \
> -    uint32_t rs1, rs0;                                            \
> -    uint32_t rt1, rt0;                                            \
> -    uint32_t tempB, tempA;                                        \
> -                                                                  \
> -    MIPSDSP_SPLIT64_32(rs, rs1, rs0);                             \
> -    MIPSDSP_SPLIT64_32(rt, rt1, rt0);                             \
> -                                                                  \
> -    tempB = mipsdsp_##func(rs1, rt1, env);                        \
> -    tempA = mipsdsp_##func(rs0, rt0, env);                        \
> -                                                                  \
> -    return MIPSDSP_RETURN64_32(tempB, tempA);                     \
> -}
> -
> -ARITH_PW_ENV(addq, add_i32);
> -ARITH_PW_ENV(addq_s, sat_add_i32);
> -ARITH_PW_ENV(subq, sub32);
> -ARITH_PW_ENV(subq_s, sat32_sub);
> -
> -#undef ARITH_PW_ENV
> -
> -#endif
> -
> -#define ARITH_QB(name, func) \
> -target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt) \
> -{                                                                 \
> -    uint8_t  rs0, rs1, rs2, rs3;                                  \
> -    uint8_t  rt0, rt1, rt2, rt3;                                  \
> -    uint8_t  temp0, temp1, temp2, temp3;                          \
> -                                                                  \
> -    MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);                    \
> -    MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);                    \
> -                                                                  \
> -    temp0 = mipsdsp_##func(rs0, rt0);                             \
> -    temp1 = mipsdsp_##func(rs1, rt1);                             \
> -    temp2 = mipsdsp_##func(rs2, rt2);                             \
> -    temp3 = mipsdsp_##func(rs3, rt3);                             \
> -                                                                  \
> -    return MIPSDSP_RETURN32_8(temp3, temp2, temp1, temp0);        \
> -}
> -
> -#define ARITH_QB_ENV(name, func) \
> -target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt, \
> -                                CPUMIPSState *env)          \
> -{                                                           \
> -    uint8_t  rs0, rs1, rs2, rs3;                            \
> -    uint8_t  rt0, rt1, rt2, rt3;                            \
> -    uint8_t  temp0, temp1, temp2, temp3;                    \
> -                                                            \
> -    MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);              \
> -    MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);              \
> -                                                            \
> -    temp0 = mipsdsp_##func(rs0, rt0, env);                  \
> -    temp1 = mipsdsp_##func(rs1, rt1, env);                  \
> -    temp2 = mipsdsp_##func(rs2, rt2, env);                  \
> -    temp3 = mipsdsp_##func(rs3, rt3, env);                  \
> -                                                            \
> -    return MIPSDSP_RETURN32_8(temp3, temp2, temp1, temp0);  \
> -}
> -
> -ARITH_QB(adduh, rshift1_add_u8);
> -ARITH_QB(adduh_r, rrshift1_add_u8);
> -
> -ARITH_QB_ENV(addu, add_u8);
> -ARITH_QB_ENV(addu_s, sat_add_u8);
> -
> -#undef ADDU_QB
> -#undef ADDU_QB_ENV
> -
> -#if defined(TARGET_MIPS64)
> -#define ARITH_OB(name, func) \
> -target_ulong helper_##name##_ob(target_ulong rs, target_ulong rt) \
> -{                                                                 \
> -    int i;                                                        \
> -    uint8_t rs_t[8], rt_t[8];                                     \
> -    uint8_t temp[8];                                              \
> -    uint64_t result;                                              \
> -                                                                  \
> -    result = 0;                                                   \
> -                                                                  \
> -    for (i = 0; i < 8; i++) {                                     \
> -        rs_t[i] = (rs >> (8 * i)) & MIPSDSP_Q0;                   \
> -        rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;                   \
> -        temp[i] = mipsdsp_##func(rs_t[i], rt_t[i]);               \
> -        result |= (uint64_t)temp[i] << (8 * i);                   \
> -    }                                                             \
> -                                                                  \
> -    return result;                                                \
> -}
> -
> -#define ARITH_OB_ENV(name, func) \
> -target_ulong helper_##name##_ob(target_ulong rs, target_ulong rt, \
> -                                CPUMIPSState *env)                \
> -{                                                                 \
> -    int i;                                                        \
> -    uint8_t rs_t[8], rt_t[8];                                     \
> -    uint8_t temp[8];                                              \
> -    uint64_t result;                                              \
> -                                                                  \
> -    result = 0;                                                   \
> -                                                                  \
> -    for (i = 0; i < 8; i++) {                                     \
> -        rs_t[i] = (rs >> (8 * i)) & MIPSDSP_Q0;                   \
> -        rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;                   \
> -        temp[i] = mipsdsp_##func(rs_t[i], rt_t[i], env);          \
> -        result |= (uint64_t)temp[i] << (8 * i);                   \
> -    }                                                             \
> -                                                                  \
> -    return result;                                                \
> -}
> -
> -ARITH_OB_ENV(addu, add_u8);
> -ARITH_OB_ENV(addu_s, sat_add_u8);
> -
> -ARITH_OB(adduh, rshift1_add_u8);
> -ARITH_OB(adduh_r, rrshift1_add_u8);
> -
> -ARITH_OB_ENV(subu, sub_u8);
> -ARITH_OB_ENV(subu_s, satu8_sub);
> -
> -ARITH_OB(subuh, rshift1_sub_u8);
> -ARITH_OB(subuh_r, rrshift1_sub_u8);
> -
> -#undef ARITH_OB
> -#undef ARITH_OB_ENV
> -
> -#endif
> -
> -#define SUBU_QB(name, func) \
> -target_ulong helper_##name##_qb(target_ulong rs,               \
> -                                target_ulong rt,               \
> -                                CPUMIPSState *env)             \
> -{                                                              \
> -    uint8_t rs3, rs2, rs1, rs0;                                \
> -    uint8_t rt3, rt2, rt1, rt0;                                \
> -    uint8_t tempD, tempC, tempB, tempA;                        \
> -                                                               \
> -    MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);                 \
> -    MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);                 \
> -                                                               \
> -    tempD = mipsdsp_##func(rs3, rt3, env);                     \
> -    tempC = mipsdsp_##func(rs2, rt2, env);                     \
> -    tempB = mipsdsp_##func(rs1, rt1, env);                     \
> -    tempA = mipsdsp_##func(rs0, rt0, env);                     \
> -                                                               \
> -    return MIPSDSP_RETURN32_8(tempD, tempC, tempB, tempA);     \
> -}
> -
> -SUBU_QB(subu, sub_u8);
> -SUBU_QB(subu_s, satu8_sub);
> -
> -#undef SUBU_QB
> -
>  #define SUBUH_QB(name, var) \
>  target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt) \
>  {                                                                 \
> @@ -4043,7 +3892,6 @@ target_ulong helper_rddsp(target_ulong masknum,
> CPUMIPSState *env)
>  #undef MIPSDSP_SPLIT32_8
>  #undef MIPSDSP_SPLIT32_16
> 
> -#undef MIPSDSP_RETURN32
>  #undef MIPSDSP_RETURN32_8
>  #undef MIPSDSP_RETURN32_16
> 
> --
> 1.7.10.4
> 

Reviewed-by: Eric Johnson <ericj@mips.com>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 5/7] target-mips: use DSP unions for unary DSP operators
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 5/7] target-mips: use DSP unions for unary " Aurelien Jarno
@ 2012-12-05  4:58   ` Johnson, Eric
  0 siblings, 0 replies; 17+ messages in thread
From: Johnson, Eric @ 2012-12-05  4:58 UTC (permalink / raw)
  To: Aurelien Jarno, qemu-devel@nongnu.org

> -----Original Message-----
> From: qemu-devel-bounces+ericj=mips.com@nongnu.org [mailto:qemu-devel-
> bounces+ericj=mips.com@nongnu.org] On Behalf Of Aurelien Jarno
> Sent: Friday, November 16, 2012 3:04 AM
> To: qemu-devel@nongnu.org
> Cc: Aurelien Jarno
> Subject: [Qemu-devel] [PATCH 5/7] target-mips: use DSP unions for unary
> DSP operators
> 
> This allow to reduce the number of macros.
> 
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-mips/dsp_helper.c |  124 ++++++++++++++++-------------------------
> -----
>  1 file changed, 42 insertions(+), 82 deletions(-)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index 931ca70..3bd2d35 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -1139,6 +1139,48 @@ static inline int32_t mipsdsp_cmpu_lt(uint32_t a,
> uint32_t b)
>  #endif
> 
>  /** DSP Arithmetic Sub-class insns **/
> +#define MIPSDSP32_UNOP_ENV(name, func, element)
> \
> +target_ulong helper_##name(target_ulong rt, CPUMIPSState *env)
> \
> +{
> \
> +    DSP32Value dt;
> \
> +    unsigned int i, n;
> \
> +
> \
> +    n = sizeof(DSP32Value) / sizeof(dt.element[0]);
> \
> +    dt.sw[0] = rt;
> \
> +
> \
> +    for (i = 0 ; i < n ; i++) {
> \
> +        dt.element[i] = mipsdsp_##func(dt.element[i], env);
> \
> +    }
> \
> +
> \
> +    return (int32_t)dt.sw[0];
> \
> +}
> +MIPSDSP32_UNOP_ENV(absq_s_ph, sat_abs16, sh)
> +MIPSDSP32_UNOP_ENV(absq_s_qb, sat_abs8, sb)
> +MIPSDSP32_UNOP_ENV(absq_s_w, sat_abs32, sw)
> +#undef MIPSDSP32_UNOP_ENV
> +
> +#if defined(TARGET_MIPS64)
> +#define MIPSDSP64_UNOP_ENV(name, func, element)
> \
> +target_ulong helper_##name(target_ulong rt, CPUMIPSState *env)
> \
> +{
> \
> +    DSP64Value dt;
> \
> +    unsigned int i, n;
> \
> +
> \
> +    n = sizeof(DSP64Value) / sizeof(dt.element[0]);
> \
> +    dt.sl[0] = rt;
> \
> +
> \
> +    for (i = 0 ; i < n ; i++) {
> \
> +        dt.element[i] = mipsdsp_##func(dt.element[i], env);
> \
> +    }
> \
> +
> \
> +    return dt.sl[0];
> \
> +}
> +MIPSDSP64_UNOP_ENV(absq_s_ob, sat_abs8, sb)
> +MIPSDSP64_UNOP_ENV(absq_s_qh, sat_abs16, sh)
> +MIPSDSP64_UNOP_ENV(absq_s_pw, sat_abs32, sw)
> +#undef MIPSDSP64_UNOP_ENV
> +#endif
> +
>  #define MIPSDSP32_BINOP(name, func, element)
> \
>  target_ulong helper_##name(target_ulong rs, target_ulong rt)
> \
>  {
> \
> @@ -1260,16 +1302,6 @@ MIPSDSP64_BINOP_ENV(subu_s_qh, satu16_sub_u16_u16,
> uh);
> 
>  #endif
> 
> -target_ulong helper_absq_s_w(target_ulong rt, CPUMIPSState *env)
> -{
> -    uint32_t rd;
> -
> -    rd = mipsdsp_sat_abs32(rt, env);
> -
> -    return (target_ulong)rd;
> -}
> -
> -
>  #define SUBUH_QB(name, var) \
>  target_ulong helper_##name##_qb(target_ulong rs, target_ulong rt) \
>  {                                                                 \
> @@ -1377,78 +1409,6 @@ target_ulong helper_raddu_l_ob(target_ulong rs)
>  }
>  #endif
> 
> -target_ulong helper_absq_s_qb(target_ulong rt, CPUMIPSState *env)
> -{
> -    uint8_t tempD, tempC, tempB, tempA;
> -
> -    MIPSDSP_SPLIT32_8(rt, tempD, tempC, tempB, tempA);
> -
> -    tempD = mipsdsp_sat_abs8(tempD, env);
> -    tempC = mipsdsp_sat_abs8(tempC, env);
> -    tempB = mipsdsp_sat_abs8(tempB, env);
> -    tempA = mipsdsp_sat_abs8(tempA, env);
> -
> -    return MIPSDSP_RETURN32_8(tempD, tempC, tempB, tempA);
> -}
> -
> -target_ulong helper_absq_s_ph(target_ulong rt, CPUMIPSState *env)
> -{
> -    uint16_t tempB, tempA;
> -
> -    MIPSDSP_SPLIT32_16(rt, tempB, tempA);
> -
> -    tempB = mipsdsp_sat_abs16 (tempB, env);
> -    tempA = mipsdsp_sat_abs16 (tempA, env);
> -
> -    return MIPSDSP_RETURN32_16(tempB, tempA);
> -}
> -
> -#if defined(TARGET_MIPS64)
> -target_ulong helper_absq_s_ob(target_ulong rt, CPUMIPSState *env)
> -{
> -    int i;
> -    int8_t temp[8];
> -    uint64_t result;
> -
> -    for (i = 0; i < 8; i++) {
> -        temp[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
> -        temp[i] = mipsdsp_sat_abs8(temp[i], env);
> -    }
> -
> -    for (i = 0; i < 8; i++) {
> -        result = (uint64_t)(uint8_t)temp[i] << (8 * i);
> -    }
> -
> -    return result;
> -}
> -
> -target_ulong helper_absq_s_qh(target_ulong rt, CPUMIPSState *env)
> -{
> -    int16_t tempD, tempC, tempB, tempA;
> -
> -    MIPSDSP_SPLIT64_16(rt, tempD, tempC, tempB, tempA);
> -
> -    tempD = mipsdsp_sat_abs16(tempD, env);
> -    tempC = mipsdsp_sat_abs16(tempC, env);
> -    tempB = mipsdsp_sat_abs16(tempB, env);
> -    tempA = mipsdsp_sat_abs16(tempA, env);
> -
> -    return MIPSDSP_RETURN64_16(tempD, tempC, tempB, tempA);
> -}
> -
> -target_ulong helper_absq_s_pw(target_ulong rt, CPUMIPSState *env)
> -{
> -    int32_t tempB, tempA;
> -
> -    MIPSDSP_SPLIT64_32(rt, tempB, tempA);
> -
> -    tempB = mipsdsp_sat_abs32(tempB, env);
> -    tempA = mipsdsp_sat_abs32(tempA, env);
> -
> -    return MIPSDSP_RETURN64_32(tempB, tempA);
> -}
> -#endif
> -
>  #define PRECR_QB_PH(name, a, b)\
>  target_ulong helper_##name##_qb_ph(target_ulong rs, target_ulong rt) \
>  {                                                                    \
> --
> 1.7.10.4
> 

Reviewed-by: Eric Johnson <ericj@mips.com>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 6/7] target-mips: use DSP unions for reduction add instructions
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 6/7] target-mips: use DSP unions for reduction add instructions Aurelien Jarno
@ 2012-12-05  4:58   ` Johnson, Eric
  0 siblings, 0 replies; 17+ messages in thread
From: Johnson, Eric @ 2012-12-05  4:58 UTC (permalink / raw)
  To: Aurelien Jarno, qemu-devel@nongnu.org

> -----Original Message-----
> From: qemu-devel-bounces+ericj=mips.com@nongnu.org [mailto:qemu-devel-
> bounces+ericj=mips.com@nongnu.org] On Behalf Of Aurelien Jarno
> Sent: Friday, November 16, 2012 3:04 AM
> To: qemu-devel@nongnu.org
> Cc: Aurelien Jarno
> Subject: [Qemu-devel] [PATCH 6/7] target-mips: use DSP unions for
> reduction add instructions
> 
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-mips/dsp_helper.c |   32 +++++++++++++++-----------------
>  1 file changed, 15 insertions(+), 17 deletions(-)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index 3bd2d35..474c249 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -1381,31 +1381,29 @@ target_ulong helper_modsub(target_ulong rs,
> target_ulong rt)
> 
>  target_ulong helper_raddu_w_qb(target_ulong rs)
>  {
> -    uint8_t  rs3, rs2, rs1, rs0;
> -    uint16_t temp;
> -
> -    MIPSDSP_SPLIT32_8(rs, rs3, rs2, rs1, rs0);
> -
> -    temp = (uint16_t)rs3 + (uint16_t)rs2 + (uint16_t)rs1 + (uint16_t)rs0;
> +    target_ulong ret = 0;
> +    DSP32Value ds;
> +    unsigned int i;
> 
> -    return (target_ulong)temp;
> +    ds.uw[0] = rs;
> +    for (i = 0 ; i < 4 ; i++) {
> +        ret += ds.ub[i];
> +    }
> +    return ret;
>  }
> 
>  #if defined(TARGET_MIPS64)
>  target_ulong helper_raddu_l_ob(target_ulong rs)
>  {
> -    int i;
> -    uint16_t rs_t[8];
> -    uint64_t temp;
> -
> -    temp = 0;
> +    target_ulong ret = 0;
> +    DSP64Value ds;
> +    unsigned int i;
> 
> -    for (i = 0; i < 8; i++) {
> -        rs_t[i] = (rs >> (8 * i)) & MIPSDSP_Q0;
> -        temp += (uint64_t)rs_t[i];
> +    ds.ul[0] = rs;
> +    for (i = 0 ; i < 8 ; i++) {
> +        ret += ds.ub[i];
>      }
> -
> -    return temp;
> +    return ret;
>  }
>  #endif
> 
> --
> 1.7.10.4
> 

Reviewed-by: Eric Johnson <ericj@mips.com>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 7/7] target-mips: implement DSP (d)append sub-class with TCG
  2012-11-16 11:04 ` [Qemu-devel] [PATCH 7/7] target-mips: implement DSP (d)append sub-class with TCG Aurelien Jarno
@ 2012-12-05  4:58   ` Johnson, Eric
  0 siblings, 0 replies; 17+ messages in thread
From: Johnson, Eric @ 2012-12-05  4:58 UTC (permalink / raw)
  To: Aurelien Jarno, qemu-devel@nongnu.org

> -----Original Message-----
> From: qemu-devel-bounces+ericj=mips.com@nongnu.org [mailto:qemu-devel-
> bounces+ericj=mips.com@nongnu.org] On Behalf Of Aurelien Jarno
> Sent: Friday, November 16, 2012 3:04 AM
> To: qemu-devel@nongnu.org
> Cc: Aurelien Jarno
> Subject: [Qemu-devel] [PATCH 7/7] target-mips: implement DSP (d)append
> sub-class with TCG
> 
> DSP instruction from the (d)append sub-class can be implemented with
> TCG. Use a different function for these instructions are they are quite
> different from compare-pick sub-class.
> 
> Fix BALIGN instruction for negative value, where the value should be
> zero-extended before being shift to the right.
> 
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  target-mips/dsp_helper.c |   67 -----------------------
>  target-mips/helper.h     |   13 -----
>  target-mips/translate.c  |  133 ++++++++++++++++++++++++++++++-----------
> -----
>  3 files changed, 87 insertions(+), 126 deletions(-)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index 474c249..22bbfa1 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -3140,73 +3140,6 @@ PICK_INSN(pick_pw, 2, MIPSDSP_LLO, 32, 0);
>  #endif
>  #undef PICK_INSN
> 
> -#define APPEND_INSN(name, ret_32) \
> -target_ulong helper_##name(target_ulong rt, target_ulong rs, uint32_t sa)
> \
> -{
> \
> -    target_ulong temp;
> \
> -
> \
> -    if (ret_32) {
> \
> -        temp = ((rt & MIPSDSP_LLO) << sa) |
> \
> -               ((rs & MIPSDSP_LLO) & ((0x01 << sa) - 1));
> \
> -        temp = (target_long)(int32_t)(temp & MIPSDSP_LLO);
> \
> -    } else {
> \
> -        temp = (rt << sa) | (rs & ((0x01 << sa) - 1));
> \
> -    }
> \
> -
> \
> -    return temp;
> \
> -}
> -
> -APPEND_INSN(append, 1);
> -#ifdef TARGET_MIPS64
> -APPEND_INSN(dappend, 0);
> -#endif
> -#undef APPEND_INSN
> -
> -#define PREPEND_INSN(name, or_val, ret_32)                    \
> -target_ulong helper_##name(target_ulong rs, target_ulong rt,  \
> -                           uint32_t sa)                       \
> -{                                                             \
> -    sa |= or_val;                                             \
> -                                                              \
> -    if (1) {                                                  \
> -        return (target_long)(int32_t)(uint32_t)               \
> -            (((rs & MIPSDSP_LLO) << (32 - sa)) |              \
> -             ((rt & MIPSDSP_LLO) >> sa));                     \
> -    } else {                                                  \
> -        return (rs << (64 - sa)) | (rt >> sa);                \
> -    }                                                         \
> -}
> -
> -PREPEND_INSN(prepend, 0, 1);
> -#ifdef TARGET_MIPS64
> -PREPEND_INSN(prependw, 0, 0);
> -PREPEND_INSN(prependd, 0x20, 0);
> -#endif
> -#undef PREPEND_INSN
> -
> -#define BALIGN_INSN(name, filter, ret32) \
> -target_ulong helper_##name(target_ulong rs, target_ulong rt, uint32_t bp)
> \
> -{
> \
> -    bp = bp & 0x03;
> \
> -
> \
> -    if ((bp & 1) == 0) {
> \
> -        return rt;
> \
> -    } else {
> \
> -        if (ret32) {
> \
> -            return (target_long)(int32_t)((rt << (8 * bp)) |
> \
> -                                          (rs >> (8 * (4 - bp))));
> \
> -        } else {
> \
> -            return (rt << (8 * bp)) | (rs >> (8 * (8 - bp)));
> \
> -        }
> \
> -    }
> \
> -}
> -
> -BALIGN_INSN(balign, 0x03, 1);
> -#if defined(TARGET_MIPS64)
> -BALIGN_INSN(dbalign, 0x07, 0);
> -#endif
> -#undef BALIGN_INSN
> -
>  target_ulong helper_packrl_ph(target_ulong rs, target_ulong rt)
>  {
>      uint32_t rsl, rth;
> diff --git a/target-mips/helper.h b/target-mips/helper.h
> index acf9ebd..4373ac5 100644
> --- a/target-mips/helper.h
> +++ b/target-mips/helper.h
> @@ -654,19 +654,6 @@ DEF_HELPER_FLAGS_3(pick_ob, 0, tl, tl, tl, env)
>  DEF_HELPER_FLAGS_3(pick_qh, 0, tl, tl, tl, env)
>  DEF_HELPER_FLAGS_3(pick_pw, 0, tl, tl, tl, env)
>  #endif
> -DEF_HELPER_FLAGS_3(append, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
> -#if defined(TARGET_MIPS64)
> -DEF_HELPER_FLAGS_3(dappend, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
> -#endif
> -DEF_HELPER_FLAGS_3(prepend, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
> -#if defined(TARGET_MIPS64)
> -DEF_HELPER_FLAGS_3(prependd, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
> -DEF_HELPER_FLAGS_3(prependw, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
> -#endif
> -DEF_HELPER_FLAGS_3(balign, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
> -#if defined(TARGET_MIPS64)
> -DEF_HELPER_FLAGS_3(dbalign, TCG_CALL_NO_RWG_SE, tl, tl, tl, i32)
> -#endif
>  DEF_HELPER_FLAGS_2(packrl_ph, TCG_CALL_NO_RWG_SE, tl, tl, tl)
>  #if defined(TARGET_MIPS64)
>  DEF_HELPER_FLAGS_2(packrl_pw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 910dd16..624d5a5 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -336,7 +336,7 @@ enum {
>      /* DSP Bit/Manipulation Sub-class */
>      OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
>      OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
> -    /* MIPS DSP Compare-Pick Sub-class */
> +    /* MIPS DSP Append Sub-class */
>      OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
>      OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
>      /* MIPS DSP Accumulator and DSPControl Access Sub-class */
> @@ -543,7 +543,7 @@ enum {
> 
>  #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
>  enum {
> -    /* MIPS DSP Compare-Pick Sub-class */
> +    /* MIPS DSP Append Sub-class */
>      OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
>      OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
>      OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
> @@ -667,7 +667,7 @@ enum {
> 
>  #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
>  enum {
> -    /* DSP Compare-Pick Sub-class */
> +    /* DSP Append Sub-class */
>      OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
>      OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
>      OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
> @@ -13844,7 +13844,6 @@ static void gen_mipsdsp_add_cmp_pick(CPUMIPSState
> *env, DisasContext *ctx,
>                                       int ret, int v1, int v2, int
> check_ret)
>  {
>      const char *opn = "mipsdsp add compare pick";
> -    TCGv_i32 t0;
>      TCGv t1;
>      TCGv v1_t;
>      TCGv v2_t;
> @@ -13855,7 +13854,6 @@ static void gen_mipsdsp_add_cmp_pick(CPUMIPSState
> *env, DisasContext *ctx,
>          return;
>      }
> 
> -    t0 = tcg_temp_new_i32();
>      t1 = tcg_temp_new();
>      v1_t = tcg_temp_new();
>      v2_t = tcg_temp_new();
> @@ -13864,26 +13862,6 @@ static void gen_mipsdsp_add_cmp_pick(CPUMIPSState
> *env, DisasContext *ctx,
>      gen_load_gpr(v2_t, v2);
> 
>      switch (op1) {
> -    case OPC_APPEND_DSP:
> -        switch (op2) {
> -        case OPC_APPEND:
> -            tcg_gen_movi_i32(t0, v2);
> -            gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
> -            break;
> -        case OPC_PREPEND:
> -            tcg_gen_movi_i32(t0, v2);
> -            gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
> -            break;
> -        case OPC_BALIGN:
> -            tcg_gen_movi_i32(t0, v2);
> -            gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
> -            break;
> -        default:            /* Invid */
> -            MIPS_INVAL("MASK APPEND");
> -            generate_exception(ctx, EXCP_RI);
> -            break;
> -        }
> -        break;
>      case OPC_CMPU_EQ_QB_DSP:
>          switch (op2) {
>          case OPC_CMPU_EQ_QB:
> @@ -14041,23 +14019,95 @@ static void
> gen_mipsdsp_add_cmp_pick(CPUMIPSState *env, DisasContext *ctx,
>              break;
>          }
>          break;
> +#endif
> +    }
> +
> +    tcg_temp_free(t1);
> +    tcg_temp_free(v1_t);
> +    tcg_temp_free(v2_t);
> +
> +    (void)opn; /* avoid a compiler warning */
> +    MIPS_DEBUG("%s", opn);
> +}
> +
> +static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
> +                               uint32_t op1, int rt, int rs, int sa)
> +{
> +    const char *opn = "mipsdsp append/dappend";
> +    TCGv t0;
> +
> +    check_dspr2(env, ctx);
> +
> +    if (rt == 0) {
> +        /* Treat as NOP. */
> +        MIPS_DEBUG("NOP");
> +        return;
> +    }
> +
> +    t0 = tcg_temp_new();
> +    gen_load_gpr(t0, rs);
> +
> +    switch (op1) {
> +    case OPC_APPEND_DSP:
> +        switch (MASK_APPEND(ctx->opcode)) {
> +        case OPC_APPEND:
> +            if (sa != 0) {
> +                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 -
> sa);
> +            }
> +            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
> +            break;
> +        case OPC_PREPEND:
> +            if (sa != 0) {
> +                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
> +                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
> +                tcg_gen_shli_tl(t0, t0, 32 - sa);
> +                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
> +            }
> +            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
> +            break;
> +        case OPC_BALIGN:
> +            sa &= 3;
> +            if (sa != 0 && sa != 2) {
> +                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
> +                tcg_gen_ext32u_tl(t0, t0);
> +                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
> +                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
> +            }
> +            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
> +            break;
> +        default:            /* Invalid */
> +            MIPS_INVAL("MASK APPEND");
> +            generate_exception(ctx, EXCP_RI);
> +            break;
> +        }
> +        break;
> +#ifdef TARGET_MIPS64
>      case OPC_DAPPEND_DSP:
> -        switch (op2) {
> +        switch (MASK_DAPPEND(ctx->opcode)) {
>          case OPC_DAPPEND:
> -            tcg_gen_movi_i32(t0, v2);
> -            gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
> +            if (sa != 0) {
> +                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 -
> sa);
> +            }
>              break;
>          case OPC_PREPENDD:
> -            tcg_gen_movi_i32(t0, v2);
> -            gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
> +            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
> +            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
> +            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
>              break;
>          case OPC_PREPENDW:
> -            tcg_gen_movi_i32(t0, v2);
> -            gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
> +            if (sa != 0) {
> +                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
> +                tcg_gen_shli_tl(t0, t0, 64 - sa);
> +                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
> +            }
>              break;
>          case OPC_DBALIGN:
> -            tcg_gen_movi_i32(t0, v2);
> -            gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
> +            sa &= 7;
> +            if (sa != 0 && sa != 2 && sa != 4) {
> +                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
> +                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
> +                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
> +            }
>              break;
>          default:            /* Invalid */
>              MIPS_INVAL("MASK DAPPEND");
> @@ -14067,12 +14117,7 @@ static void gen_mipsdsp_add_cmp_pick(CPUMIPSState
> *env, DisasContext *ctx,
>          break;
>  #endif
>      }
> -
> -    tcg_temp_free_i32(t0);
> -    tcg_temp_free(t1);
> -    tcg_temp_free(v1_t);
> -    tcg_temp_free(v2_t);
> -
> +    tcg_temp_free(t0);
>      (void)opn; /* avoid a compiler warning */
>      MIPS_DEBUG("%s", opn);
>  }
> @@ -14892,9 +14937,7 @@ static void decode_opc (CPUMIPSState *env,
> DisasContext *ctx, int *is_branch)
>              }
>              break;
>          case OPC_APPEND_DSP:
> -            check_dspr2(env, ctx);
> -            op2 = MASK_APPEND(ctx->opcode);
> -            gen_mipsdsp_add_cmp_pick(env, ctx, op1, op2, rt, rs, rd, 1);
> +            gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
>              break;
>          case OPC_EXTR_W_DSP:
>              op2 = MASK_EXTR_W(ctx->opcode);
> @@ -15068,9 +15111,7 @@ static void decode_opc (CPUMIPSState *env,
> DisasContext *ctx, int *is_branch)
>              }
>              break;
>          case OPC_DAPPEND_DSP:
> -            check_dspr2(ctx);
> -            op2 = MASK_DAPPEND(ctx->opcode);
> -            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
> +            gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
>              break;
>          case OPC_DEXTR_W_DSP:
>              op2 = MASK_DEXTR_W(ctx->opcode);
> --
> 1.7.10.4
> 

Reviewed-by: Eric Johnson <ericj@mips.com>


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2012-12-05  4:59 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-16 11:04 [Qemu-devel] [PATCH 0/7] target-mips: DSP ASE fixes and cleanup Aurelien Jarno
2012-11-16 11:04 ` [Qemu-devel] [PATCH 1/7] target-mips: fix DSP loads with rd = 0 Aurelien Jarno
2012-11-21  6:28   ` Johnson, Eric
2012-11-16 11:04 ` [Qemu-devel] [PATCH 2/7] target-mips: generate a reserved instruction exception on CPU without DSP Aurelien Jarno
2012-11-16 22:02   ` Richard Henderson
2012-11-21  6:51     ` Johnson, Eric
2012-11-16 11:04 ` [Qemu-devel] [PATCH 3/7] target-mips: add unions to access DSP elements Aurelien Jarno
2012-11-21  6:54   ` Johnson, Eric
2012-11-16 11:04 ` [Qemu-devel] [PATCH 4/7] target-mips: use DSP unions for binary DSP operators Aurelien Jarno
2012-11-16 22:04   ` Richard Henderson
2012-12-05  4:58   ` Johnson, Eric
2012-11-16 11:04 ` [Qemu-devel] [PATCH 5/7] target-mips: use DSP unions for unary " Aurelien Jarno
2012-12-05  4:58   ` Johnson, Eric
2012-11-16 11:04 ` [Qemu-devel] [PATCH 6/7] target-mips: use DSP unions for reduction add instructions Aurelien Jarno
2012-12-05  4:58   ` Johnson, Eric
2012-11-16 11:04 ` [Qemu-devel] [PATCH 7/7] target-mips: implement DSP (d)append sub-class with TCG Aurelien Jarno
2012-12-05  4:58   ` Johnson, Eric

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).