[Qemu-devel] [PATCH v5 43/76] target/mips: Add emulation of DSP ASE for nanoMIPS - part 6

Aleksandar Markovic posted 76 patches 7 years, 3 months ago
There is a newer version of this series
[Qemu-devel] [PATCH v5 43/76] target/mips: Add emulation of DSP ASE for nanoMIPS - part 6
Posted by Aleksandar Markovic 7 years, 3 months ago
From: Stefan Markovic <smarkovic@wavecomp.com>

Add emulation of DSP ASE instructions for nanoMIPS - part 6.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 132e40e..5066eff 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17543,6 +17543,61 @@ static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
     tcg_temp_free(v1_t);
 }
 
+static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
+                                          int ret, int v1, int v2)
+{
+    int16_t imm;
+
+    TCGv t0;
+    TCGv v1_t;
+
+    t0 = tcg_temp_new();
+    v1_t = tcg_temp_new();
+
+    gen_load_gpr(v1_t, v1);
+
+    switch (opc) {
+    case NM_SHRA_R_QB:
+        tcg_gen_movi_tl(t0, v2 >> 2);
+        switch (extract32(ctx->opcode, 12, 1)) {
+        case 0:
+            /* NM_SHRA_QB */
+            check_dspr2(ctx);
+            gen_helper_shra_qb(cpu_gpr[ret], t0, v1_t);
+            break;
+        case 1:
+            /* NM_SHRA_R_QB */
+            check_dspr2(ctx);
+            gen_helper_shra_r_qb(cpu_gpr[ret], t0, v1_t);
+            break;
+        }
+        break;
+    case NM_SHRL_PH:
+        check_dspr2(ctx);
+        tcg_gen_movi_tl(t0, v2 >> 1);
+        gen_helper_shrl_ph(cpu_gpr[ret], t0, v1_t);
+        break;
+    case NM_REPL_QB:
+        {
+            check_dsp(ctx);
+            target_long result;
+            imm = extract32(ctx->opcode, 13, 8);
+            result = (uint32_t)imm << 24 |
+                     (uint32_t)imm << 16 |
+                    (uint32_t)imm << 8  |
+                     (uint32_t)imm;
+            result = (int32_t)result;
+            tcg_gen_movi_tl(cpu_gpr[ret], result);
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+    tcg_temp_free(t0);
+    tcg_temp_free(v1_t);
+}
+
 
 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
 {
@@ -17644,6 +17699,10 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_POOL32AXF_7:
+        {
+            int32_t op1 = extract32(ctx->opcode, 9, 3);
+            gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
+        }
         break;
     default:
         generate_exception_end(ctx, EXCP_RI);
-- 
2.7.4


Re: [Qemu-devel] [PATCH v5 43/76] target/mips: Add emulation of DSP ASE for nanoMIPS - part 6
Posted by Richard Henderson 7 years, 3 months ago
On 07/30/2018 12:12 PM, Aleksandar Markovic wrote:
> +        switch (extract32(ctx->opcode, 12, 1)) {
> +        case 0:
> +            /* NM_SHRA_QB */
> +            check_dspr2(ctx);
> +            gen_helper_shra_qb(cpu_gpr[ret], t0, v1_t);
More unprotected use of cpu_gpr[0].

I think you need some sort of solution that prevents this completely, without
having to think about it.  E.g. global replace cpu_gpr[x] -> read_gpr(ctx, x) /
dest_gpr(ctx, x), where the two functions allocate tcg temporaries on demand.

I think the model used in target/alpha/translate.c is ideal.  However, there
are variations on this theme in target/arm/translate-a64.c,
target/sparc/translate.c, and target/openrisc/translate.c.


r~

Re: [Qemu-devel] [PATCH v5 43/76] target/mips: Add emulation of DSP ASE for nanoMIPS - part 6
Posted by Richard Henderson 7 years, 3 months ago
On 07/31/2018 02:58 PM, Richard Henderson wrote:
> On 07/30/2018 12:12 PM, Aleksandar Markovic wrote:
>> +        switch (extract32(ctx->opcode, 12, 1)) {
>> +        case 0:
>> +            /* NM_SHRA_QB */
>> +            check_dspr2(ctx);
>> +            gen_helper_shra_qb(cpu_gpr[ret], t0, v1_t);
> More unprotected use of cpu_gpr[0].
> 
> I think you need some sort of solution that prevents this completely, without
> having to think about it.  E.g. global replace cpu_gpr[x] -> read_gpr(ctx, x) /
> dest_gpr(ctx, x), where the two functions allocate tcg temporaries on demand.

I forgot to say... and then poison cpu_gpr so that uses cannot creep back into
the codebase.  See e.g. include/exec/poison.h.


r~