diff mbox series

[v3,07/40] target/mips: Add emulation of nanoMIPS 16-bit load and store instructions

Message ID 1532004912-13899-8-git-send-email-stefan.markovic@rt-rk.com
State New
Headers show
Series Add nanoMIPS support to QEMU | expand

Commit Message

Stefan Markovic July 19, 2018, 12:54 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

Richard Henderson July 19, 2018, 6:28 p.m. UTC | #1
On 07/19/2018 05:54 AM, Stefan Markovic wrote:
> +/* 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];
> +}

Same comment re comment as before.

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

Shadowing outer rt variable.  And indeed, NANOMIPS_EXTRACT_RD has already been
extracted into it, so this becomes just

    rt = decode_gpr_gpr3_src_store(rt);

Similarly throughout the rest of this file.

Consider creating one "int imm" variable at the top of the function that you
can reuse for all of these immediate value extractions and not have to create
these local variable blocks.


r~
diff mbox series

Patch

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 798f977..1a839be 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16472,6 +16472,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,
@@ -16568,6 +16576,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) {
@@ -16651,24 +16666,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,