diff mbox series

[v2,03/33] target/mips: Add emulation of nanoMIPS 16-bit load and store instructions

Message ID 1531169431-10772-4-git-send-email-aleksandar.markovic@rt-rk.com
State New
Headers show
Series Add nanoMIPS support to QEMU | expand

Commit Message

Aleksandar Markovic July 9, 2018, 8:50 p.m. UTC
From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of LWXS16, LB16, SB16, LBU16, LH16, SH16, LHU16, LW16, LWSP16,
LW4X4, SW4X4, LWGP16, SWSP16, SW16, and SWGP16 instructions.

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

Comments

Aleksandar Markovic July 10, 2018, 12:46 p.m. UTC | #1
> Subject: [PATCH v2 03/33] target/mips: Add emulation of nanoMIPS 16-bit load and store > instructions
>
> From: Yongbok Kim <yongbok.kim@mips.com>
>
> Add emulation of LWXS16, LB16, SB16, LBU16, LH16, SH16, LHU16, LW16, LWSP16,
> LW4X4, SW4X4, LWGP16, SWSP16, SW16, and SWGP16 instructions.
>
> Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  target/mips/translate.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 114 insertions(+)
>

The mixture of using extract32(), NANOMIPS_EXTRACT_XXX(), and mask/shift for decoding opcodes and registers should be streamlined, as also Richard suggested in a comment for another patch.

However, this can be fixed later, after the first integration in the upstream, if the risk of regressions is too high for this stage od development of nanoMIPS support.

With all these caveats, still:

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
diff mbox series

Patch

diff --git a/target/mips/translate.c b/target/mips/translate.c
index bc369eb..c372483 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16342,6 +16342,14 @@  static int decode_gpr_gpr3(int r)
     return map[r & 0x7];
 }
 
+/* Used for 16-bit store instructions.  */
+static int decode_gpr_gpr3_src_store(int r)
+{
+    static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
+
+    return map[r & 0x7];
+}
+
 static int decode_gpr_gpr4(int r)
 {
     static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
@@ -16427,6 +16435,13 @@  static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_P16C:
+        switch (ctx->opcode & 1) {
+        case NM_POOL16C_0:
+            break;
+        case NM_LWXS16:
+            gen_ldxs(ctx, rt, rs, rd);
+            break;
+        }
         break;
     case NM_P16_A1:
         switch ((ctx->opcode >> 6) & 1) {
@@ -16510,24 +16525,123 @@  static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_P16_LB:
+        {
+            uint32_t u = extract32(ctx->opcode, 0, 2);
+            switch (((ctx->opcode) >> 2) & 0x03) {
+            case NM_LB16:
+                gen_ld(ctx, OPC_LB, rt, rs, u);
+                break;
+            case NM_SB16:
+                {
+                    int rt = decode_gpr_gpr3_src_store(
+                                 NANOMIPS_EXTRACT_RD(ctx->opcode));
+                    gen_st(ctx, OPC_SB, rt, rs, u);
+                }
+                break;
+            case NM_LBU16:
+                gen_ld(ctx, OPC_LBU, rt, rs, u);
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+        }
         break;
     case NM_P16_LH:
+        {
+            uint32_t u = extract32(ctx->opcode, 1, 2) << 1;
+            switch ((((ctx->opcode >> 3) & 1) << 1) | (ctx->opcode & 1)) {
+            case NM_LH16:
+                gen_ld(ctx, OPC_LH, rt, rs, u);
+                break;
+            case NM_SH16:
+                {
+                    int rt = decode_gpr_gpr3_src_store(
+                                 NANOMIPS_EXTRACT_RD(ctx->opcode));
+                    gen_st(ctx, OPC_SH, rt, rs, u);
+                }
+                break;
+            case NM_LHU16:
+                gen_ld(ctx, OPC_LHU, rt, rs, u);
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+        }
         break;
     case NM_LW16:
+        {
+            int u = extract32(ctx->opcode, 0, 4) << 2;
+            gen_ld(ctx, OPC_LW, rt, rs, u);
+        }
         break;
     case NM_LWSP16:
+        {
+            int rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
+            int u = extract32(ctx->opcode, 0, 5) << 2;
+
+            gen_ld(ctx, OPC_LW, rt, 29, u);
+        }
         break;
     case NM_LW4X4:
+        {
+            int rt = (extract32(ctx->opcode, 9, 1) << 3) |
+                     extract32(ctx->opcode, 5, 3);
+            int rs = (extract32(ctx->opcode, 4, 1) << 3) |
+                     extract32(ctx->opcode, 0, 3);
+            int u = (extract32(ctx->opcode, 3, 1) << 3) |
+                    (extract32(ctx->opcode, 8, 1) << 2);
+            rt = decode_gpr_gpr4(rt);
+            rs = decode_gpr_gpr4(rs);
+            gen_ld(ctx, OPC_LW, rt, rs, u);
+        }
         break;
     case NM_SW4X4:
+        {
+            int rt = (extract32(ctx->opcode, 9, 1) << 3) |
+                     extract32(ctx->opcode, 5, 3);
+            int rs = (extract32(ctx->opcode, 4, 1) << 3) |
+                     extract32(ctx->opcode, 0, 3);
+            int u = (extract32(ctx->opcode, 3, 1) << 3) |
+                    (extract32(ctx->opcode, 8, 1) << 2);
+            rt = decode_gpr_gpr4_zero(rt);
+            rs = decode_gpr_gpr4(rs);
+            gen_st(ctx, OPC_SW, rt, rs, u);
+        }
         break;
     case NM_LWGP16:
+        {
+            int u = extract32(ctx->opcode, 0, 7) << 2;
+            gen_ld(ctx, OPC_LW, rt, 28, u);
+        }
         break;
     case NM_SWSP16:
+        {
+            int rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
+            int u = extract32(ctx->opcode, 0, 5) << 2;
+
+            gen_st(ctx, OPC_SW, rt, 29, u);
+        }
         break;
     case NM_SW16:
+        {
+            int rt = decode_gpr_gpr3_src_store(
+                         NANOMIPS_EXTRACT_RD(ctx->opcode));
+            int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
+            int u = extract32(ctx->opcode, 0, 4) << 2;
+
+            gen_st(ctx, OPC_SW, rt, rs, u);
+        }
         break;
     case NM_SWGP16:
+        {
+            int rt = decode_gpr_gpr3_src_store(
+                         NANOMIPS_EXTRACT_RD(ctx->opcode));
+            int u = extract32(ctx->opcode, 0, 7) << 2;
+
+            gen_st(ctx, OPC_SW, rt, 28, u);
+        }
         break;
     case NM_BC16:
         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,