qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support
@ 2015-06-12 14:02 Yongbok Kim
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 01/13] target-mips: fix {D, W}RGPR in microMIPS Yongbok Kim
                   ` (12 more replies)
  0 siblings, 13 replies; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

The patchset implements the latest microMIPS32 Release 6 Instruction Set.
However LLX, LLXE, SCX and SCXE aren't included in the patchset.

For more information, microMIPS R6 Instruction Set document is available:
MIPS Architecture for Programmers Volume II-B: microMIPS32 Instruction Set
Revision 6.01
http://www.imgtec.com/mips/architectures/mips32.asp

Yongbok Kim (13):
  target-mips: fix {D,W}RGPR in microMIPS
  target-mips: add microMIPS TLBINV, TLBINVF
  target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP
  target-mips: rearrange gen_compute_compact_branch
  target-mips: signal RI for removed instructions in microMIPS R6
  target-mips: add microMIPS32 R6 opcode enum
  target-mips: microMIPS32 R6 branches and jumps
  target-mips: microMIPS32 R6 POOL32A{XF} instructions
  target-mips: microMIPS32 R6 POOL32F instructions
  target-mips: microMIPS32 R6 POOL32{I,C} instructions
  target-mips: microMIPS32 R6 Major instructions
  target-mips: microMIPS32 R6 POOL16{A,C} instructions
  target-mips: add mips32r6-generic CPU definition

 target-mips/translate.c      | 2027 +++++++++++++++++++++++++++++-------------
 target-mips/translate_init.c |   37 +
 2 files changed, 1434 insertions(+), 630 deletions(-)

-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 01/13] target-mips: fix {D, W}RGPR in microMIPS
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-15 11:16   ` Aurelien Jarno
  2015-06-15 16:19   ` Leon Alrae
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 02/13] target-mips: add microMIPS TLBINV, TLBINVF Yongbok Kim
                   ` (11 subsequent siblings)
  12 siblings, 2 replies; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

rt, rs were swapped

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index f6ae0d3..d4a530d 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12749,12 +12749,12 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
         case RDPGPR:
             check_cp0_enabled(ctx);
             check_insn(ctx, ISA_MIPS32R2);
-            gen_load_srsgpr(rt, rs);
+            gen_load_srsgpr(rs, rt);
             break;
         case WRPGPR:
             check_cp0_enabled(ctx);
             check_insn(ctx, ISA_MIPS32R2);
-            gen_store_srsgpr(rt, rs);
+            gen_store_srsgpr(rs, rt);
             break;
         default:
             goto pool32axf_invalid;
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 02/13] target-mips: add microMIPS TLBINV, TLBINVF
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 01/13] target-mips: fix {D, W}RGPR in microMIPS Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-15 11:50   ` Aurelien Jarno
  2015-06-15 16:19   ` Leon Alrae
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 03/13] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP Yongbok Kim
                   ` (10 subsequent siblings)
  12 siblings, 2 replies; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

add microMIPS TLBINV, TLBINVF

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index d4a530d..b8c7164 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -11991,6 +11991,8 @@ enum {
     TLBR = 0x1,
     TLBWI = 0x2,
     TLBWR = 0x3,
+    TLBINV = 0x4,
+    TLBINVF = 0x5,
     WAIT = 0x9,
     IRET = 0xd,
     DERET = 0xe,
@@ -12775,6 +12777,12 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
         case TLBWR:
             mips32_op = OPC_TLBWR;
             goto do_cp0;
+        case TLBINV:
+            mips32_op = OPC_TLBINV;
+            goto do_cp0;
+        case TLBINVF:
+            mips32_op = OPC_TLBINVF;
+            goto do_cp0;
         case WAIT:
             mips32_op = OPC_WAIT;
             goto do_cp0;
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 03/13] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 01/13] target-mips: fix {D, W}RGPR in microMIPS Yongbok Kim
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 02/13] target-mips: add microMIPS TLBINV, TLBINVF Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-15 11:32   ` Leon Alrae
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 04/13] target-mips: rearrange gen_compute_compact_branch Yongbok Kim
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

Refactor those instructions in order to reuse them for microMIPS32
Release 6.

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |  164 +++++++++++++++++++++++++++++-----------------
 1 files changed, 103 insertions(+), 61 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index b8c7164..2244630 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -4831,6 +4831,102 @@ static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
     tcg_temp_free(t0);
 }
 
+static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
+        int imm2)
+{
+    TCGv t0;
+    TCGv t1;
+    if (rd == 0) {
+        /* Treat as NOP. */
+        return;
+    }
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+    gen_load_gpr(t0, rs);
+    gen_load_gpr(t1, rt);
+    tcg_gen_shli_tl(t0, t0, imm2 + 1);
+    switch (opc) {
+    case OPC_LSA:
+        tcg_gen_add_tl(t0, t0, t1);
+        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
+        break;
+#if defined(TARGET_MIPS64)
+    case OPC_DLSA:
+        tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
+        break;
+#endif
+    }
+    tcg_temp_free(t1);
+    tcg_temp_free(t0);
+
+    return;
+}
+
+static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
+        int bp)
+{
+    TCGv t0;
+    if (rd == 0) {
+        /* Treat as NOP. */
+        return;
+    }
+    t0 = tcg_temp_new();
+    gen_load_gpr(t0, rt);
+    if (bp == 0) {
+        tcg_gen_mov_tl(cpu_gpr[rd], t0);
+    } else {
+        TCGv t1 = tcg_temp_new();
+        gen_load_gpr(t1, rs);
+        switch (opc) {
+        case OPC_ALIGN:
+            {
+                TCGv_i64 t2 = tcg_temp_new_i64();
+                tcg_gen_concat_tl_i64(t2, t1, t0);
+                tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
+#if defined(TARGET_MIPS64)
+                tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
+#else
+                tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
+#endif
+                tcg_temp_free_i64(t2);
+            }
+            break;
+#if defined(TARGET_MIPS64)
+        case OPC_DALIGN:
+            tcg_gen_shli_tl(t0, t0, 8 * bp);
+            tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
+            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
+            break;
+#endif
+        }
+        tcg_temp_free(t1);
+    }
+
+    tcg_temp_free(t0);
+}
+
+static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
+{
+    TCGv t0;
+    if (rd == 0) {
+        /* Treat as NOP. */
+        return;
+    }
+    t0 = tcg_temp_new();
+    gen_load_gpr(t0, rt);
+    switch (opc) {
+    case OPC_BITSWAP:
+        gen_helper_bitswap(cpu_gpr[rd], t0);
+        break;
+#if defined(TARGET_MIPS64)
+    case OPC_DBITSWAP:
+        gen_helper_dbitswap(cpu_gpr[rd], t0);
+        break;
+#endif
+    }
+    tcg_temp_free(t0);
+}
+
 #ifndef CONFIG_USER_ONLY
 /* CP0 (MMU and control) */
 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
@@ -16191,18 +16287,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
     op1 = MASK_SPECIAL(ctx->opcode);
     switch (op1) {
     case OPC_LSA:
-        if (rd != 0) {
-            int imm2 = extract32(ctx->opcode, 6, 3);
-            TCGv t0 = tcg_temp_new();
-            TCGv t1 = tcg_temp_new();
-            gen_load_gpr(t0, rs);
-            gen_load_gpr(t1, rt);
-            tcg_gen_shli_tl(t0, t0, imm2 + 1);
-            tcg_gen_add_tl(t0, t0, t1);
-            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
-            tcg_temp_free(t1);
-            tcg_temp_free(t0);
-        }
+        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
         break;
     case OPC_MULT ... OPC_DIVU:
         op2 = MASK_R6_MULDIV(ctx->opcode);
@@ -16247,17 +16332,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
 #if defined(TARGET_MIPS64)
     case OPC_DLSA:
         check_mips_64(ctx);
-        if (rd != 0) {
-            int imm2 = extract32(ctx->opcode, 6, 3);
-            TCGv t0 = tcg_temp_new();
-            TCGv t1 = tcg_temp_new();
-            gen_load_gpr(t0, rs);
-            gen_load_gpr(t1, rt);
-            tcg_gen_shli_tl(t0, t0, imm2 + 1);
-            tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
-            tcg_temp_free(t1);
-            tcg_temp_free(t0);
-        }
+        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
         break;
     case R6_OPC_DCLO:
     case R6_OPC_DCLZ:
@@ -16682,35 +16757,15 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
                 /* Treat as NOP. */
                 break;
             }
-            TCGv t0 = tcg_temp_new();
-            gen_load_gpr(t0, rt);
-
             op2 = MASK_BSHFL(ctx->opcode);
             switch (op2) {
             case OPC_ALIGN ... OPC_ALIGN_END:
-                sa &= 3;
-                if (sa == 0) {
-                    tcg_gen_mov_tl(cpu_gpr[rd], t0);
-                } else {
-                    TCGv t1 = tcg_temp_new();
-                    TCGv_i64 t2 = tcg_temp_new_i64();
-                    gen_load_gpr(t1, rs);
-                    tcg_gen_concat_tl_i64(t2, t1, t0);
-                    tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
-#if defined(TARGET_MIPS64)
-                    tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
-#else
-                    tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
-#endif
-                    tcg_temp_free_i64(t2);
-                    tcg_temp_free(t1);
-                }
+                gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
                 break;
             case OPC_BITSWAP:
-                gen_helper_bitswap(cpu_gpr[rd], t0);
+                gen_bitswap(ctx, op2, rd, rt);
                 break;
             }
-            tcg_temp_free(t0);
         }
         break;
 #if defined(TARGET_MIPS64)
@@ -16727,29 +16782,16 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
                 /* Treat as NOP. */
                 break;
             }
-            TCGv t0 = tcg_temp_new();
-            gen_load_gpr(t0, rt);
-
             op2 = MASK_DBSHFL(ctx->opcode);
             switch (op2) {
             case OPC_DALIGN ... OPC_DALIGN_END:
-                sa &= 7;
-                if (sa == 0) {
-                    tcg_gen_mov_tl(cpu_gpr[rd], t0);
-                } else {
-                    TCGv t1 = tcg_temp_new();
-                    gen_load_gpr(t1, rs);
-                    tcg_gen_shli_tl(t0, t0, 8 * sa);
-                    tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
-                    tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
-                    tcg_temp_free(t1);
-                }
+                gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
                 break;
             case OPC_DBITSWAP:
-                gen_helper_dbitswap(cpu_gpr[rd], t0);
+                gen_bitswap(ctx, op2, rd, rt);
                 break;
             }
-            tcg_temp_free(t0);
+
         }
         break;
 #endif
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 04/13] target-mips: rearrange gen_compute_compact_branch
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (2 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 03/13] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-15 16:19   ` Leon Alrae
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 05/13] target-mips: signal RI for removed instructions in microMIPS R6 Yongbok Kim
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

The function will be also used for microMIPS Release 6.

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |  472 +++++++++++++++++++++++-----------------------
 1 files changed, 236 insertions(+), 236 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 2244630..79a5c6b 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -10738,6 +10738,242 @@ static void gen_branch(DisasContext *ctx, int insn_bytes)
     }
 }
 
+/* Compact Branches */
+static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
+                                       int rs, int rt, int32_t offset)
+{
+    int bcond_compute = 0;
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+
+    if (ctx->hflags & MIPS_HFLAG_BMASK) {
+#ifdef MIPS_DEBUG_DISAS
+        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
+                  "\n", ctx->pc);
+#endif
+        generate_exception(ctx, EXCP_RI);
+        goto out;
+    }
+
+    /* Load needed operands and calculate btarget */
+    switch (opc) {
+    /* compact branch */
+    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
+    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
+        gen_load_gpr(t0, rs);
+        gen_load_gpr(t1, rt);
+        bcond_compute = 1;
+        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
+        if (rs <= rt && rs == 0) {
+            /* OPC_BEQZALC, OPC_BNEZALC */
+            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
+        }
+        break;
+    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
+    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
+        gen_load_gpr(t0, rs);
+        gen_load_gpr(t1, rt);
+        bcond_compute = 1;
+        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
+        break;
+    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
+    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
+        if (rs == 0 || rs == rt) {
+            /* OPC_BLEZALC, OPC_BGEZALC */
+            /* OPC_BGTZALC, OPC_BLTZALC */
+            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
+        }
+        gen_load_gpr(t0, rs);
+        gen_load_gpr(t1, rt);
+        bcond_compute = 1;
+        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
+        break;
+    case OPC_BC:
+    case OPC_BALC:
+        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
+        break;
+    case OPC_BEQZC:
+    case OPC_BNEZC:
+        if (rs != 0) {
+            /* OPC_BEQZC, OPC_BNEZC */
+            gen_load_gpr(t0, rs);
+            bcond_compute = 1;
+            ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
+        } else {
+            /* OPC_JIC, OPC_JIALC */
+            TCGv tbase = tcg_temp_new();
+            TCGv toffset = tcg_temp_new();
+
+            gen_load_gpr(tbase, rt);
+            tcg_gen_movi_tl(toffset, offset);
+            gen_op_addr_add(ctx, btarget, tbase, toffset);
+            tcg_temp_free(tbase);
+            tcg_temp_free(toffset);
+        }
+        break;
+    default:
+        MIPS_INVAL("Compact branch/jump");
+        generate_exception(ctx, EXCP_RI);
+        goto out;
+    }
+
+    if (bcond_compute == 0) {
+        /* Uncoditional compact branch */
+        switch (opc) {
+        case OPC_JIALC:
+            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
+            /* Fallthrough */
+        case OPC_JIC:
+            ctx->hflags |= MIPS_HFLAG_BR;
+            break;
+        case OPC_BALC:
+            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
+            /* Fallthrough */
+        case OPC_BC:
+            ctx->hflags |= MIPS_HFLAG_B;
+            break;
+        default:
+            MIPS_INVAL("Compact branch/jump");
+            generate_exception(ctx, EXCP_RI);
+            goto out;
+        }
+
+        /* Generating branch here as compact branches don't have delay slot */
+        gen_branch(ctx, 4);
+    } else {
+        /* Conditional compact branch */
+        TCGLabel *fs = gen_new_label();
+        save_cpu_state(ctx, 0);
+
+        switch (opc) {
+        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
+            if (rs == 0 && rt != 0) {
+                /* OPC_BLEZALC */
+                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
+            } else if (rs != 0 && rt != 0 && rs == rt) {
+                /* OPC_BGEZALC */
+                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
+            } else {
+                /* OPC_BGEUC */
+                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
+            }
+            break;
+        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
+            if (rs == 0 && rt != 0) {
+                /* OPC_BGTZALC */
+                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
+            } else if (rs != 0 && rt != 0 && rs == rt) {
+                /* OPC_BLTZALC */
+                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
+            } else {
+                /* OPC_BLTUC */
+                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
+            }
+            break;
+        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
+            if (rs == 0 && rt != 0) {
+                /* OPC_BLEZC */
+                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
+            } else if (rs != 0 && rt != 0 && rs == rt) {
+                /* OPC_BGEZC */
+                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
+            } else {
+                /* OPC_BGEC */
+                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
+            }
+            break;
+        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
+            if (rs == 0 && rt != 0) {
+                /* OPC_BGTZC */
+                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
+            } else if (rs != 0 && rt != 0 && rs == rt) {
+                /* OPC_BLTZC */
+                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
+            } else {
+                /* OPC_BLTC */
+                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
+            }
+            break;
+        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
+        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
+            if (rs >= rt) {
+                /* OPC_BOVC, OPC_BNVC */
+                TCGv t2 = tcg_temp_new();
+                TCGv t3 = tcg_temp_new();
+                TCGv t4 = tcg_temp_new();
+                TCGv input_overflow = tcg_temp_new();
+
+                gen_load_gpr(t0, rs);
+                gen_load_gpr(t1, rt);
+                tcg_gen_ext32s_tl(t2, t0);
+                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
+                tcg_gen_ext32s_tl(t3, t1);
+                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
+                tcg_gen_or_tl(input_overflow, input_overflow, t4);
+
+                tcg_gen_add_tl(t4, t2, t3);
+                tcg_gen_ext32s_tl(t4, t4);
+                tcg_gen_xor_tl(t2, t2, t3);
+                tcg_gen_xor_tl(t3, t4, t3);
+                tcg_gen_andc_tl(t2, t3, t2);
+                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
+                tcg_gen_or_tl(t4, t4, input_overflow);
+                if (opc == OPC_BOVC) {
+                    /* OPC_BOVC */
+                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
+                } else {
+                    /* OPC_BNVC */
+                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
+                }
+                tcg_temp_free(input_overflow);
+                tcg_temp_free(t4);
+                tcg_temp_free(t3);
+                tcg_temp_free(t2);
+            } else if (rs < rt && rs == 0) {
+                /* OPC_BEQZALC, OPC_BNEZALC */
+                if (opc == OPC_BEQZALC) {
+                    /* OPC_BEQZALC */
+                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
+                } else {
+                    /* OPC_BNEZALC */
+                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
+                }
+            } else {
+                /* OPC_BEQC, OPC_BNEC */
+                if (opc == OPC_BEQC) {
+                    /* OPC_BEQC */
+                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
+                } else {
+                    /* OPC_BNEC */
+                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
+                }
+            }
+            break;
+        case OPC_BEQZC:
+            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
+            break;
+        case OPC_BNEZC:
+            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
+            break;
+        default:
+            MIPS_INVAL("Compact conditional branch/jump");
+            generate_exception(ctx, EXCP_RI);
+            goto out;
+        }
+
+        /* Generating branch here as compact branches don't have delay slot */
+        gen_goto_tb(ctx, 1, ctx->btarget);
+        gen_set_label(fs);
+
+        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
+        MIPS_DEBUG("Compact conditional branch");
+    }
+
+out:
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+}
+
 /* ISA extensions (ASEs) */
 /* MIPS16 extension to MIPS32 */
 
@@ -16038,242 +16274,6 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
 
 /* End MIPSDSP functions. */
 
-/* Compact Branches */
-static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
-                                       int rs, int rt, int32_t offset)
-{
-    int bcond_compute = 0;
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    if (ctx->hflags & MIPS_HFLAG_BMASK) {
-#ifdef MIPS_DEBUG_DISAS
-        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
-                  "\n", ctx->pc);
-#endif
-        generate_exception(ctx, EXCP_RI);
-        goto out;
-    }
-
-    /* Load needed operands and calculate btarget */
-    switch (opc) {
-    /* compact branch */
-    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
-    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
-        gen_load_gpr(t0, rs);
-        gen_load_gpr(t1, rt);
-        bcond_compute = 1;
-        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
-        if (rs <= rt && rs == 0) {
-            /* OPC_BEQZALC, OPC_BNEZALC */
-            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
-        }
-        break;
-    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
-    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
-        gen_load_gpr(t0, rs);
-        gen_load_gpr(t1, rt);
-        bcond_compute = 1;
-        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
-        break;
-    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
-    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
-        if (rs == 0 || rs == rt) {
-            /* OPC_BLEZALC, OPC_BGEZALC */
-            /* OPC_BGTZALC, OPC_BLTZALC */
-            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
-        }
-        gen_load_gpr(t0, rs);
-        gen_load_gpr(t1, rt);
-        bcond_compute = 1;
-        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
-        break;
-    case OPC_BC:
-    case OPC_BALC:
-        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
-        break;
-    case OPC_BEQZC:
-    case OPC_BNEZC:
-        if (rs != 0) {
-            /* OPC_BEQZC, OPC_BNEZC */
-            gen_load_gpr(t0, rs);
-            bcond_compute = 1;
-            ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
-        } else {
-            /* OPC_JIC, OPC_JIALC */
-            TCGv tbase = tcg_temp_new();
-            TCGv toffset = tcg_temp_new();
-
-            gen_load_gpr(tbase, rt);
-            tcg_gen_movi_tl(toffset, offset);
-            gen_op_addr_add(ctx, btarget, tbase, toffset);
-            tcg_temp_free(tbase);
-            tcg_temp_free(toffset);
-        }
-        break;
-    default:
-        MIPS_INVAL("Compact branch/jump");
-        generate_exception(ctx, EXCP_RI);
-        goto out;
-    }
-
-    if (bcond_compute == 0) {
-        /* Uncoditional compact branch */
-        switch (opc) {
-        case OPC_JIALC:
-            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
-            /* Fallthrough */
-        case OPC_JIC:
-            ctx->hflags |= MIPS_HFLAG_BR;
-            break;
-        case OPC_BALC:
-            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
-            /* Fallthrough */
-        case OPC_BC:
-            ctx->hflags |= MIPS_HFLAG_B;
-            break;
-        default:
-            MIPS_INVAL("Compact branch/jump");
-            generate_exception(ctx, EXCP_RI);
-            goto out;
-        }
-
-        /* Generating branch here as compact branches don't have delay slot */
-        gen_branch(ctx, 4);
-    } else {
-        /* Conditional compact branch */
-        TCGLabel *fs = gen_new_label();
-        save_cpu_state(ctx, 0);
-
-        switch (opc) {
-        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
-            if (rs == 0 && rt != 0) {
-                /* OPC_BLEZALC */
-                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
-            } else if (rs != 0 && rt != 0 && rs == rt) {
-                /* OPC_BGEZALC */
-                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
-            } else {
-                /* OPC_BGEUC */
-                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
-            }
-            break;
-        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
-            if (rs == 0 && rt != 0) {
-                /* OPC_BGTZALC */
-                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
-            } else if (rs != 0 && rt != 0 && rs == rt) {
-                /* OPC_BLTZALC */
-                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
-            } else {
-                /* OPC_BLTUC */
-                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
-            }
-            break;
-        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
-            if (rs == 0 && rt != 0) {
-                /* OPC_BLEZC */
-                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
-            } else if (rs != 0 && rt != 0 && rs == rt) {
-                /* OPC_BGEZC */
-                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
-            } else {
-                /* OPC_BGEC */
-                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
-            }
-            break;
-        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
-            if (rs == 0 && rt != 0) {
-                /* OPC_BGTZC */
-                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
-            } else if (rs != 0 && rt != 0 && rs == rt) {
-                /* OPC_BLTZC */
-                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
-            } else {
-                /* OPC_BLTC */
-                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
-            }
-            break;
-        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
-        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
-            if (rs >= rt) {
-                /* OPC_BOVC, OPC_BNVC */
-                TCGv t2 = tcg_temp_new();
-                TCGv t3 = tcg_temp_new();
-                TCGv t4 = tcg_temp_new();
-                TCGv input_overflow = tcg_temp_new();
-
-                gen_load_gpr(t0, rs);
-                gen_load_gpr(t1, rt);
-                tcg_gen_ext32s_tl(t2, t0);
-                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
-                tcg_gen_ext32s_tl(t3, t1);
-                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
-                tcg_gen_or_tl(input_overflow, input_overflow, t4);
-
-                tcg_gen_add_tl(t4, t2, t3);
-                tcg_gen_ext32s_tl(t4, t4);
-                tcg_gen_xor_tl(t2, t2, t3);
-                tcg_gen_xor_tl(t3, t4, t3);
-                tcg_gen_andc_tl(t2, t3, t2);
-                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
-                tcg_gen_or_tl(t4, t4, input_overflow);
-                if (opc == OPC_BOVC) {
-                    /* OPC_BOVC */
-                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
-                } else {
-                    /* OPC_BNVC */
-                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
-                }
-                tcg_temp_free(input_overflow);
-                tcg_temp_free(t4);
-                tcg_temp_free(t3);
-                tcg_temp_free(t2);
-            } else if (rs < rt && rs == 0) {
-                /* OPC_BEQZALC, OPC_BNEZALC */
-                if (opc == OPC_BEQZALC) {
-                    /* OPC_BEQZALC */
-                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
-                } else {
-                    /* OPC_BNEZALC */
-                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
-                }
-            } else {
-                /* OPC_BEQC, OPC_BNEC */
-                if (opc == OPC_BEQC) {
-                    /* OPC_BEQC */
-                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
-                } else {
-                    /* OPC_BNEC */
-                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
-                }
-            }
-            break;
-        case OPC_BEQZC:
-            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
-            break;
-        case OPC_BNEZC:
-            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
-            break;
-        default:
-            MIPS_INVAL("Compact conditional branch/jump");
-            generate_exception(ctx, EXCP_RI);
-            goto out;
-        }
-
-        /* Generating branch here as compact branches don't have delay slot */
-        gen_goto_tb(ctx, 1, ctx->btarget);
-        gen_set_label(fs);
-
-        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
-        MIPS_DEBUG("Compact conditional branch");
-    }
-
-out:
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-}
-
 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
 {
     int rs, rt, rd, sa;
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 05/13] target-mips: signal RI for removed instructions in microMIPS R6
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (3 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 04/13] target-mips: rearrange gen_compute_compact_branch Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-15 16:18   ` Leon Alrae
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 06/13] target-mips: add microMIPS32 R6 opcode enum Yongbok Kim
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

Signal a Reserved Instruction exception for removed instruction encoding
in microMIPS Release 6.

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 79a5c6b..dbf51d1 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -13014,15 +13014,19 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
             gen_bshfl(ctx, OPC_WSBH, rs, rt);
             break;
         case MULT:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_MULT;
             goto do_mul;
         case MULTU:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_MULTU;
             goto do_mul;
         case DIV:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_DIV;
             goto do_div;
         case DIVU:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_DIVU;
             goto do_div;
         do_div:
@@ -13030,15 +13034,19 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
             gen_muldiv(ctx, mips32_op, 0, rs, rt);
             break;
         case MADD:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_MADD;
             goto do_mul;
         case MADDU:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_MADDU;
             goto do_mul;
         case MSUB:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_MSUB;
             goto do_mul;
         case MSUBU:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_MSUBU;
         do_mul:
             check_insn(ctx, ISA_MIPS32);
@@ -13071,6 +13079,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
             break;
         case JALRS:
         case JALRS_HB:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
             break;
@@ -13203,6 +13212,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
         }
         break;
     case 0x35:
+        check_insn_opc_removed(ctx, ISA_MIPS32R6);
         switch (minor) {
         case MFHI32:
             gen_HILO(ctx, OPC_MFHI, 0, rs);
@@ -13475,6 +13485,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
     case COND_FLOAT_MOV(MOVT, 5):
     case COND_FLOAT_MOV(MOVT, 6):
     case COND_FLOAT_MOV(MOVT, 7):
+        check_insn_opc_removed(ctx, ISA_MIPS32R6);
         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
         break;
     case COND_FLOAT_MOV(MOVF, 0):
@@ -13485,6 +13496,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
     case COND_FLOAT_MOV(MOVF, 5):
     case COND_FLOAT_MOV(MOVF, 6):
     case COND_FLOAT_MOV(MOVF, 7):
+        check_insn_opc_removed(ctx, ISA_MIPS32R6);
         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
         break;
     default:
@@ -13556,6 +13568,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                 mips32_op = OPC_SUBU;
                 goto do_arith;
             case MUL:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_MUL;
             do_arith:
                 gen_arith(ctx, mips32_op, rd, rs, rt);
@@ -13687,47 +13700,61 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
             check_cp1_enabled(ctx);
             switch (minor) {
             case ALNV_PS:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_ALNV_PS;
                 goto do_madd;
             case MADD_S:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_MADD_S;
                 goto do_madd;
             case MADD_D:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_MADD_D;
                 goto do_madd;
             case MADD_PS:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_MADD_PS;
                 goto do_madd;
             case MSUB_S:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_MSUB_S;
                 goto do_madd;
             case MSUB_D:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_MSUB_D;
                 goto do_madd;
             case MSUB_PS:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_MSUB_PS;
                 goto do_madd;
             case NMADD_S:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_NMADD_S;
                 goto do_madd;
             case NMADD_D:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_NMADD_D;
                 goto do_madd;
             case NMADD_PS:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_NMADD_PS;
                 goto do_madd;
             case NMSUB_S:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_NMSUB_S;
                 goto do_madd;
             case NMSUB_D:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_NMSUB_D;
                 goto do_madd;
             case NMSUB_PS:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 mips32_op = OPC_NMSUB_PS;
             do_madd:
                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
                 break;
             case CABS_COND_FMT:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 cond = (ctx->opcode >> 6) & 0xf;
                 cc = (ctx->opcode >> 13) & 0x7;
                 fmt = (ctx->opcode >> 10) & 0x3;
@@ -13746,6 +13773,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                 }
                 break;
             case C_COND_FMT:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 cond = (ctx->opcode >> 6) & 0xf;
                 cc = (ctx->opcode >> 13) & 0x7;
                 fmt = (ctx->opcode >> 10) & 0x3;
@@ -13782,6 +13810,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                     mips32_op = OPC_PUU_PS;
                     goto do_ps;
                 case CVT_PS_S:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     mips32_op = OPC_CVT_PS_S;
                 do_ps:
                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
@@ -13794,21 +13823,27 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                 /* [LS][WDU]XC1 */
                 switch ((ctx->opcode >> 6) & 0x7) {
                 case LWXC1:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     mips32_op = OPC_LWXC1;
                     goto do_ldst_cp1;
                 case SWXC1:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     mips32_op = OPC_SWXC1;
                     goto do_ldst_cp1;
                 case LDXC1:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     mips32_op = OPC_LDXC1;
                     goto do_ldst_cp1;
                 case SDXC1:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     mips32_op = OPC_SDXC1;
                     goto do_ldst_cp1;
                 case LUXC1:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     mips32_op = OPC_LUXC1;
                     goto do_ldst_cp1;
                 case SUXC1:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     mips32_op = OPC_SUXC1;
                 do_ldst_cp1:
                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
@@ -13819,6 +13854,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                 break;
             case 0x18:
                 /* 3D insns */
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
                 fmt = (ctx->opcode >> 9) & 0x3;
                 switch ((ctx->opcode >> 6) & 0x7) {
                 case RSQRT2_FMT:
@@ -13899,6 +13935,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                     }
                     break;
                 case PREFX:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     break;
                 default:
                     goto pool32f_invalid;
@@ -13974,31 +14011,39 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
         minor = (ctx->opcode >> 21) & 0x1f;
         switch (minor) {
         case BLTZ:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
             break;
         case BLTZAL:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
             break;
         case BLTZALS:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
             break;
         case BGEZ:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
             break;
         case BGEZAL:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
             break;
         case BGEZALS:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
             break;
         case BLEZ:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
             break;
         case BGTZ:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
             break;
 
@@ -14010,15 +14055,18 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
             mips32_op = OPC_TGEI;
             goto do_trapi;
         case TLTIU:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_TLTIU;
             goto do_trapi;
         case TGEIU:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_TGEIU;
             goto do_trapi;
         case TNEI:
             mips32_op = OPC_TNEI;
             goto do_trapi;
         case TEQI:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_TEQI;
         do_trapi:
             gen_trap(ctx, mips32_op, rs, -1, imm);
@@ -14026,6 +14074,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
 
         case BNEZC:
         case BEQZC:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
                                4, rs, 0, imm << 1, 0);
             /* Compact branches don't have a delay slot, so just let
@@ -14033,28 +14082,35 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                target. */
             break;
         case LUI:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
             break;
         case SYNCI:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             /* Break the TB to be able to sync copied instructions
                immediately */
             ctx->bstate = BS_STOP;
             break;
         case BC2F:
         case BC2T:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             /* COP2: Not implemented. */
             generate_exception_err(ctx, EXCP_CpU, 2);
             break;
         case BC1F:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
             goto do_cp1branch;
         case BC1T:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
             goto do_cp1branch;
         case BC1ANY4F:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_BC1FANY4;
             goto do_cp1mips3d;
         case BC1ANY4T:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_BC1TANY4;
         do_cp1mips3d:
             check_cop1x(ctx);
@@ -14083,36 +14139,44 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
         minor = (ctx->opcode >> 12) & 0xf;
         switch (minor) {
         case LWL:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_LWL;
             goto do_ld_lr;
         case SWL:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_SWL;
             goto do_st_lr;
         case LWR:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_LWR;
             goto do_ld_lr;
         case SWR:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_SWR;
             goto do_st_lr;
 #if defined(TARGET_MIPS64)
         case LDL:
             check_insn(ctx, ISA_MIPS3);
             check_mips_64(ctx);
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_LDL;
             goto do_ld_lr;
         case SDL:
             check_insn(ctx, ISA_MIPS3);
             check_mips_64(ctx);
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_SDL;
             goto do_st_lr;
         case LDR:
             check_insn(ctx, ISA_MIPS3);
             check_mips_64(ctx);
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_LDR;
             goto do_ld_lr;
         case SDR:
             check_insn(ctx, ISA_MIPS3);
             check_mips_64(ctx);
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_SDR;
             goto do_st_lr;
         case LWU:
@@ -14186,6 +14250,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
         break;
     case JALX32:
+        check_insn_opc_removed(ctx, ISA_MIPS32R6);
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
@@ -14202,10 +14267,12 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
         gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
         break;
     case J32:
+        check_insn_opc_removed(ctx, ISA_MIPS32R6);
         gen_compute_branch(ctx, OPC_J, 4, rt, rs,
                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
         break;
     case JAL32:
+        check_insn_opc_removed(ctx, ISA_MIPS32R6);
         gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
@@ -14384,6 +14451,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case POOL16F:
+        check_insn_opc_removed(ctx, ISA_MIPS32R6);
         if (ctx->opcode & 1) {
             generate_exception(ctx, EXCP_RI);
         } else {
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 06/13] target-mips: add microMIPS32 R6 opcode enum
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (4 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 05/13] target-mips: signal RI for removed instructions in microMIPS R6 Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 07/13] target-mips: microMIPS32 R6 branches and jumps Yongbok Kim
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

add microMIPS32 Release 6 opcode enum
remove RI checking for pre-R6 reserved opcode.

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |  123 ++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 107 insertions(+), 16 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index dbf51d1..fa81448 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12128,6 +12128,8 @@ enum {
     LBU16 = 0x02,
     MOVE16 = 0x03,
     ADDI32 = 0x04,
+    R6_LUI = 0x04,
+    AUI = 0x04,
     LBU32 = 0x05,
     SB32 = 0x06,
     LB32 = 0x07,
@@ -12150,56 +12152,89 @@ enum {
     POOL32S = 0x16,  /* MIPS64 */
     DADDIU32 = 0x17, /* MIPS64 */
 
-    /* 0x1f is reserved */
     POOL32C = 0x18,
     LWGP16 = 0x19,
     LW16 = 0x1a,
     POOL16E = 0x1b,
     XORI32 = 0x1c,
     JALS32 = 0x1d,
+    BOVC = 0x1d,
+    BEQC = 0x1d,
+    BEQZALC = 0x1d,
     ADDIUPC = 0x1e,
+    PCREL = 0x1e,
+    BNVC = 0x1f,
+    BNEC = 0x1f,
+    BNEZALC = 0x1f,
 
-    /* 0x20 is reserved */
-    RES_20 = 0x20,
+    R6_BEQZC = 0x20,
+    JIC = 0x20,
     POOL16F = 0x21,
     SB16 = 0x22,
     BEQZ16 = 0x23,
+    BEQZC16 = 0x23,
     SLTI32 = 0x24,
     BEQ32 = 0x25,
+    BC = 0x25,
     SWC132 = 0x26,
     LWC132 = 0x27,
 
-    /* 0x28 and 0x29 are reserved */
-    RES_28 = 0x28,
+    /* 0x29 is reserved */
     RES_29 = 0x29,
+    R6_BNEZC = 0x28,
+    JIALC = 0x28,
     SH16 = 0x2a,
     BNEZ16 = 0x2b,
+    BNEZC16 = 0x2b,
     SLTIU32 = 0x2c,
     BNE32 = 0x2d,
+    BALC = 0x2d,
     SDC132 = 0x2e,
     LDC132 = 0x2f,
 
-    /* 0x30 and 0x31 are reserved */
-    RES_30 = 0x30,
+    /* 0x31 is reserved */
     RES_31 = 0x31,
+    BLEZALC = 0x30,
+    BGEZALC = 0x30,
+    BGEUC = 0x30,
     SWSP16 = 0x32,
     B16 = 0x33,
+    BC16 = 0x33,
     ANDI32 = 0x34,
     J32 = 0x35,
+    BGTZC = 0x35,
+    BLTZC = 0x35,
+    BLTC = 0x35,
     SD32 = 0x36, /* MIPS64 */
     LD32 = 0x37, /* MIPS64 */
 
-    /* 0x38 and 0x39 are reserved */
-    RES_38 = 0x38,
+    /* 0x39 is reserved */
     RES_39 = 0x39,
+    BGTZALC = 0x38,
+    BLTZALC = 0x38,
+    BLTUC = 0x38,
     SW16 = 0x3a,
     LI16 = 0x3b,
     JALX32 = 0x3c,
+    DAUI = 0x3c,
     JAL32 = 0x3d,
+    BLEZC = 0x3d,
+    BGEZC = 0x3d,
+    BGEC = 0x3d,
     SW32 = 0x3e,
     LW32 = 0x3f
 };
 
+/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
+enum {
+    ADDIUPC_00 = 0x00,
+    ADDIUPC_07 = 0x07,
+    AUIPC = 0x1e,
+    ALUIPC = 0x1f,
+    LWPC_08 = 0x08,
+    LWPC_0F = 0x0F,
+};
+
 /* POOL32A encoding of minor opcode field */
 
 enum {
@@ -12209,6 +12244,9 @@ enum {
     SRL32 = 0x1,
     SRA = 0x2,
     ROTR = 0x3,
+    R6_LWXS = 0x4,
+    SELEQZ = 0x5,
+    SELNEZ = 0x6,
 
     SLLV = 0x0,
     SRLV = 0x1,
@@ -12227,11 +12265,21 @@ enum {
     SLTU = 0xe,
 
     MOVN = 0x0,
+    R6_MUL  = 0x0,
     MOVZ = 0x1,
+    MUH  = 0x1,
+    MULU = 0x2,
+    MUHU = 0x3,
     LWXS = 0x4,
+    R6_DIV  = 0x4,
+    MOD  = 0x5,
+    R6_DIVU = 0x6,
+    MODU = 0x7,
 
     /* The following can be distinguished by their lower 6 bits. */
     INS = 0x0c,
+    LSA = 0x0f,
+    ALIGN = 0x1f,
     EXT = 0x2c,
     POOL32AXF = 0x3c
 };
@@ -12284,6 +12332,7 @@ enum {
     /* end of microMIPS32 DSP */
 
     /* bits 15..12 for 0x2c */
+    BITSWAP = 0x0,
     SEB = 0x2,
     SEH = 0x3,
     CLO = 0x4,
@@ -12310,7 +12359,10 @@ enum {
     /* bits 15..12 for 0x3c */
     JALR = 0x0,
     JR = 0x0,                   /* alias */
+    JALRC = 0x0,
+    JRC = 0x0,
     JALR_HB = 0x1,
+    JALRC_HB = 0x1,
     JALRS = 0x4,
     JALRS_HB = 0x5,
 
@@ -12394,32 +12446,39 @@ enum {
 enum {
     /* These are the bit 7..6 values */
     ADD_FMT = 0x0,
-    MOVN_FMT = 0x0,
 
     SUB_FMT = 0x1,
-    MOVZ_FMT = 0x1,
 
     MUL_FMT = 0x2,
 
     DIV_FMT = 0x3,
 
     /* These are the bit 8..6 values */
+    MOVN_FMT = 0x0,
     RSQRT2_FMT = 0x0,
     MOVF_FMT = 0x0,
+    RINT_FMT = 0x0,
+    SELNEZ_FMT = 0x0,
 
+    MOVZ_FMT = 0x1,
     LWXC1 = 0x1,
     MOVT_FMT = 0x1,
+    CLASS_FMT = 0x1,
+    SELEQZ_FMT = 0x1,
 
     PLL_PS = 0x2,
     SWXC1 = 0x2,
+    SEL_FMT = 0x2,
 
     PLU_PS = 0x3,
     LDXC1 = 0x3,
 
+    MOVN_FMT_04 = 0x4,
     PUL_PS = 0x4,
     SDXC1 = 0x4,
     RECIP2_FMT = 0x4,
 
+    MOVZ_FMT_05 = 0x05,
     PUU_PS = 0x5,
     LUXC1 = 0x5,
 
@@ -12427,8 +12486,10 @@ enum {
     SUXC1 = 0x6,
     ADDR_PS = 0x6,
     PREFX = 0x6,
+    MADDF_FMT = 0x6,
 
     MULR_PS = 0x7,
+    MSUBF_FMT = 0x7,
 
     MADD_S = 0x01,
     MADD_D = 0x09,
@@ -12445,10 +12506,17 @@ enum {
     NMSUB_D = 0x2a,
     NMSUB_PS = 0x32,
 
+    MIN_FMT = 0x3,
+    MAX_FMT = 0xb,
+    MINA_FMT = 0x23,
+    MAXA_FMT = 0x2b,
     POOL32FXF = 0x3b,
 
     CABS_COND_FMT = 0x1c,              /* MIPS3D */
-    C_COND_FMT = 0x3c
+    C_COND_FMT = 0x3c,
+
+    CMP_CONDN_S = 0x5,
+    CMP_CONDN_D = 0x15
 };
 
 /* POOL32Fxf encoding of minor opcode extension field */
@@ -12501,14 +12569,21 @@ enum {
     BGTZ = 0x06,
     BEQZC = 0x07,
     TLTI = 0x08,
+    BC1EQZC = 0x08,
     TGEI = 0x09,
+    BC1NEZC = 0x09,
     TLTIU = 0x0a,
+    BC2EQZC = 0x0a,
     TGEIU = 0x0b,
+    BC2NEZC = 0x0a,
     TNEI = 0x0c,
+    R6_SYNCI = 0x0c,
     LUI = 0x0d,
     TEQI = 0x0e,
     SYNCI = 0x10,
+    DATI = 0x10,
     BLTZALS = 0x11,
+    DAHI = 0x10,
     BGEZALS = 0x13,
     BC2F = 0x14,
     BC2T = 0x15,
@@ -12557,6 +12632,26 @@ enum {
     JRADDIUSP = 0x30
 };
 
+/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
+
+enum {
+    R6_NOT16    = 0x00,
+    R6_AND16    = 0x01,
+    R6_LWM16    = 0x02,
+    R6_JRC16    = 0x03,
+    MOVEP       = 0x04,
+    MOVEP_07    = 0x07,
+    R6_XOR16    = 0x08,
+    R6_OR16     = 0x09,
+    R6_SWM16    = 0x0a,
+    JALRC16     = 0x0b,
+    MOVEP_0C    = 0x0c,
+    MOVEP_0F    = 0x0f,
+    JRCADDIUSP  = 0x13,
+    R6_BREAK16  = 0x1b,
+    R6_SDBBP16  = 0x3b
+};
+
 /* POOL16D encoding of minor opcode field */
 
 enum {
@@ -14596,12 +14691,8 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
             tcg_gen_movi_tl(cpu_gpr[reg], imm);
         }
         break;
-    case RES_20:
-    case RES_28:
     case RES_29:
-    case RES_30:
     case RES_31:
-    case RES_38:
     case RES_39:
         generate_exception(ctx, EXCP_RI);
         break;
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 07/13] target-mips: microMIPS32 R6 branches and jumps
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (5 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 06/13] target-mips: add microMIPS32 R6 opcode enum Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 08/13] target-mips: microMIPS32 R6 POOL32A{XF} instructions Yongbok Kim
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

add new microMIPS32 Release 6 branch and jump instructions.

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |  209 ++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 181 insertions(+), 28 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index fa81448..0efaa02 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -8198,7 +8198,8 @@ static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
 
 /* R6 CP1 Branches */
 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
-                                   int32_t ft, int32_t offset)
+                                   int32_t ft, int32_t offset,
+                                   int delayslot_size)
 {
     target_ulong btarget;
     const char *opn = "cp1 cond branch";
@@ -8241,7 +8242,15 @@ static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
                ctx->hflags, btarget);
     ctx->btarget = btarget;
-    ctx->hflags |= MIPS_HFLAG_BDS32;
+
+    switch (delayslot_size) {
+    case 2:
+        ctx->hflags |= MIPS_HFLAG_BDS16;
+        break;
+    case 4:
+        ctx->hflags |= MIPS_HFLAG_BDS32;
+        break;
+    }
 
 out:
     tcg_temp_free_i64(t0);
@@ -10766,7 +10775,8 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
         ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
         if (rs <= rt && rs == 0) {
             /* OPC_BEQZALC, OPC_BNEZALC */
-            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
+            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 +
+                    !!(ctx->hflags & MIPS_HFLAG_M16));
         }
         break;
     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
@@ -10781,7 +10791,8 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
         if (rs == 0 || rs == rt) {
             /* OPC_BLEZALC, OPC_BGEZALC */
             /* OPC_BGTZALC, OPC_BLTZALC */
-            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
+            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 +
+                    !!(ctx->hflags & MIPS_HFLAG_M16));
         }
         gen_load_gpr(t0, rs);
         gen_load_gpr(t1, rt);
@@ -10821,13 +10832,15 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
         /* Uncoditional compact branch */
         switch (opc) {
         case OPC_JIALC:
-            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
+            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 +
+                    !!(ctx->hflags & MIPS_HFLAG_M16));
             /* Fallthrough */
         case OPC_JIC:
             ctx->hflags |= MIPS_HFLAG_BR;
             break;
         case OPC_BALC:
-            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
+            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 +
+                    !!(ctx->hflags & MIPS_HFLAG_M16));
             /* Fallthrough */
         case OPC_BC:
             ctx->hflags |= MIPS_HFLAG_B;
@@ -13169,8 +13182,13 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
         switch (minor) {
         case JALR:
         case JALR_HB:
-            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
-            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
+            /* JALRC */
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
+            } else {
+                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
+                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
+            }
             break;
         case JALRS:
         case JALRS_HB:
@@ -14144,11 +14162,25 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
 
             /* Traps */
         case TLTI:
-            mips32_op = OPC_TLTI;
-            goto do_trapi;
+            /* BC1EQZC */
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                check_cp1_enabled(ctx);
+                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
+            } else {
+                mips32_op = OPC_TLTI;
+                goto do_trapi;
+            }
+            break;
         case TGEI:
-            mips32_op = OPC_TGEI;
-            goto do_trapi;
+            /* BC1NEZC */
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                check_cp1_enabled(ctx);
+                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
+            } else {
+                mips32_op = OPC_TGEI;
+                goto do_trapi;
+            }
+            break;
         case TLTIU:
             check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_TLTIU;
@@ -14351,26 +14383,75 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
         break;
     case JALS32:
-        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
-        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
-        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
+        /* BOVC, BEQC, BEQZALC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            if (rs >= rt) {
+                /* BOVC */
+                mips32_op = OPC_BOVC;
+            } else if (rs < rt && rs == 0) {
+                /* BEQZALC */
+                mips32_op = OPC_BEQZALC;
+            } else {
+                /* BEQC */
+                mips32_op = OPC_BEQC;
+            }
+            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
+        } else {
+            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
+            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
+            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
+        }
         break;
     case BEQ32:
-        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
+        /* BC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
+                                       sextract32(ctx->opcode << 1, 0, 27));
+        } else {
+            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
+        }
         break;
     case BNE32:
-        gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
+        /* BALC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
+                                       sextract32(ctx->opcode << 1, 0, 27));
+        } else {
+            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
+        }
         break;
     case J32:
-        check_insn_opc_removed(ctx, ISA_MIPS32R6);
-        gen_compute_branch(ctx, OPC_J, 4, rt, rs,
-                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
+        /* BGTZC, BLTZC, BLTC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            if (rs == 0 && rt != 0) {
+                mips32_op = OPC_BGTZC;
+            } else if (rs != 0 && rt != 0 && rs == rt) {
+                mips32_op = OPC_BLTZC;
+            } else {
+                mips32_op = OPC_BLTC;
+            }
+            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
+        } else {
+            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
+                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
+        }
         break;
     case JAL32:
-        check_insn_opc_removed(ctx, ISA_MIPS32R6);
-        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
-                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
-        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
+        /* BLEZC, BGEZC, BGEC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            if (rs == 0 && rt != 0) {
+                mips32_op = OPC_BLEZC;
+            } else if (rs != 0 && rt != 0 && rs == rt) {
+                mips32_op = OPC_BGEZC;
+            } else {
+                mips32_op = OPC_BGEC;
+            }
+            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
+        } else {
+            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
+                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
+            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
+        }
         break;
         /* Floating point (COP1) */
     case LWC132:
@@ -14395,6 +14476,65 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
             gen_addiupc(ctx, reg, offset, 0, 0);
         }
         break;
+    case BNVC:
+        /* BNEC, BNEZALC */
+        check_insn(ctx, ISA_MIPS32R6);
+        if (rs >= rt) {
+            /* BNVC */
+            mips32_op = OPC_BNVC;
+        } else if (rs < rt && rs == 0) {
+            /* BNEZALC */
+            mips32_op = OPC_BNEZALC;
+        } else {
+            /* BNEC */
+            mips32_op = OPC_BNEC;
+        }
+        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
+        break;
+    case R6_BNEZC:
+        /* JIALC */
+        check_insn(ctx, ISA_MIPS32R6);
+        if (rt != 0) {
+            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
+                                       sextract32(ctx->opcode << 1, 0, 22));
+        } else {
+            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
+        }
+        break;
+    case R6_BEQZC:
+        /* JIC */
+        check_insn(ctx, ISA_MIPS32R6);
+        if (rt != 0) {
+            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
+                                       sextract32(ctx->opcode << 1, 0, 22));
+        } else {
+            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
+        }
+        break;
+    case BLEZALC:
+        /* BGEZALC, BGEUC */
+        check_insn(ctx, ISA_MIPS32R6);
+        if (rs == 0 && rt != 0) {
+            mips32_op = OPC_BLEZALC;
+        } else if (rs != 0 && rt != 0 && rs == rt) {
+            mips32_op = OPC_BGEZALC;
+        } else {
+            mips32_op = OPC_BGEUC;
+        }
+        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
+        break;
+    case BGTZALC:
+        /* BLTZALC, BLTUC */
+        check_insn(ctx, ISA_MIPS32R6);
+        if (rs == 0 && rt != 0) {
+            mips32_op = OPC_BGTZALC;
+        } else if (rs != 0 && rt != 0 && rs == rt) {
+            mips32_op = OPC_BLTZALC;
+        } else {
+            mips32_op = OPC_BLTUC;
+        }
+        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
+        break;
         /* Loads and stores */
     case LB32:
         mips32_op = OPC_LB;
@@ -14673,14 +14813,20 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case B16:
+        /* BC16 */
         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
-                           SIMM(ctx->opcode, 0, 10) << 1, 4);
+                           SIMM(ctx->opcode, 0, 10) << 1,
+                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
         break;
     case BNEZ16:
+        /* BNEZC16 */
     case BEQZ16:
+        /* BEQZC16 */
         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
                            mmreg(uMIPS_RD(ctx->opcode)),
-                           0, SIMM(ctx->opcode, 0, 7) << 1, 4);
+                           0, SIMM(ctx->opcode, 0, 7) << 1,
+                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
+
         break;
     case LI16:
         {
@@ -19047,7 +19193,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
             if (ctx->insn_flags & ISA_MIPS32R6) {
                 /* OPC_BC1EQZ */
                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
-                                rt, imm << 2);
+                                       rt, imm << 2, 4);
             } else {
                 /* OPC_BC1ANY2 */
                 check_cop1x(ctx);
@@ -19060,7 +19206,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
             check_cp1_enabled(ctx);
             check_insn(ctx, ISA_MIPS32R6);
             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
-                            rt, imm << 2);
+                                   rt, imm << 2, 4);
             break;
         case OPC_BC1ANY4:
             check_cp1_enabled(ctx);
@@ -19451,6 +19597,13 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
                    forbidden slot */
                 is_slot = 1;
             }
+            if ((ctx.hflags & MIPS_HFLAG_M16) &&
+                (ctx.insn_flags & ISA_MIPS32R6) &&
+                (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
+                /* Force to generate branch as microMIPS R6 doesn't restrict
+                   branches in the forbidden slot. */
+                is_slot = 1;
+            }
         }
         if (is_slot) {
             gen_branch(&ctx, insn_bytes);
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 08/13] target-mips: microMIPS32 R6 POOL32A{XF} instructions
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (6 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 07/13] target-mips: microMIPS32 R6 branches and jumps Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-16 15:24   ` Leon Alrae
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 09/13] target-mips: microMIPS32 R6 POOL32F instructions Yongbok Kim
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

add new microMIPS32 Release 6 pool32a/pool32axf instructions.

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |   71 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 0efaa02..9422de0 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -13100,6 +13100,10 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
         break;
     case 0x2c:
         switch (minor) {
+        case BITSWAP:
+            check_insn(ctx, ISA_MIPS32R6);
+            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
+            break;
         case SEB:
             gen_bshfl(ctx, OPC_SEB, rs, rt);
             break;
@@ -13660,6 +13664,18 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
             do_shifti:
                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
                 break;
+            case R6_LWXS:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_ldxs(ctx, rs, rt, rd);
+                break;
+            case SELEQZ:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
+                break;
+            case SELNEZ:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
+                break;
             default:
                 goto pool32a_invalid;
             }
@@ -13734,15 +13750,48 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
             switch (minor) {
                 /* Conditional moves */
             case MOVN:
-                mips32_op = OPC_MOVN;
-                goto do_cmov;
+                /* MUL */
+                if (ctx->insn_flags & ISA_MIPS32R6) {
+                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
+                } else {
+                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
+                }
+                break;
             case MOVZ:
-                mips32_op = OPC_MOVZ;
-            do_cmov:
-                gen_cond_move(ctx, mips32_op, rd, rs, rt);
+                /* MUH */
+                if (ctx->insn_flags & ISA_MIPS32R6) {
+                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
+                } else {
+                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
+                }
+                break;
+            case MULU:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
+                break;
+            case MUHU:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
                 break;
             case LWXS:
-                gen_ldxs(ctx, rs, rt, rd);
+                /* DIV */
+                if (ctx->insn_flags & ISA_MIPS32R6) {
+                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
+                } else {
+                    gen_ldxs(ctx, rs, rt, rd);
+                }
+                break;
+            case MOD:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
+                break;
+            case R6_DIVU:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
+                break;
+            case MODU:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
                 break;
             default:
                 goto pool32a_invalid;
@@ -13751,6 +13800,16 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
         case INS:
             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
             return;
+        case LSA:
+            check_insn(ctx, ISA_MIPS32R6);
+            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
+                    extract32(ctx->opcode, 9, 2));
+            break;
+        case ALIGN:
+            check_insn(ctx, ISA_MIPS32R6);
+            gen_align(ctx, OPC_ALIGN, rd, rs, rt,
+                      extract32(ctx->opcode, 9, 2));
+            break;
         case EXT:
             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
             return;
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 09/13] target-mips: microMIPS32 R6 POOL32F instructions
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (7 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 08/13] target-mips: microMIPS32 R6 POOL32A{XF} instructions Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-17 15:50   ` Leon Alrae
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 10/13] target-mips: microMIPS32 R6 POOL32{I, C} instructions Yongbok Kim
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

add new microMIPS32 Release 6 POOL32F instructions

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |  215 +++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 189 insertions(+), 26 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 9422de0..3d9145c 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -13963,6 +13963,14 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                     goto pool32f_invalid;
                 }
                 break;
+            case CMP_CONDN_S:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_r6_cmp_s(ctx, ctx->opcode >> 6 & 0x1f, rt, rs, rd);
+                break;
+            case CMP_CONDN_D:
+                check_insn(ctx, ISA_MIPS32R6);
+                gen_r6_cmp_d(ctx, ctx->opcode >> 6 & 0x1f, rt, rs, rd);
+                break;
             case POOL32FXF:
                 gen_pool32fxf(ctx, rt, rs);
                 break;
@@ -13991,6 +13999,19 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                     goto pool32f_invalid;
                 }
                 break;
+            case MIN_FMT:
+                check_insn(ctx, ISA_MIPS32R6);
+                switch (ctx->opcode >> 9 & 0x3) {
+                case FMT_SDPS_S:
+                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
+                    break;
+                case FMT_SDPS_D:
+                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
+                    break;
+                default:
+                    goto pool32f_invalid;
+                }
+                break;
             case 0x08:
                 /* [LS][WDU]XC1 */
                 switch ((ctx->opcode >> 6) & 0x7) {
@@ -14024,6 +14045,19 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                     goto pool32f_invalid;
                 }
                 break;
+            case MAX_FMT:
+                check_insn(ctx, ISA_MIPS32R6);
+                switch (ctx->opcode >> 9 & 0x3) {
+                case FMT_SDPS_S:
+                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
+                    break;
+                case FMT_SDPS_D:
+                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
+                    break;
+                default:
+                    goto pool32f_invalid;
+                }
+                break;
             case 0x18:
                 /* 3D insns */
                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
@@ -14072,38 +14106,66 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                 }
                 break;
             case 0x20:
-                /* MOV[FT].fmt and PREFX */
+                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
                 cc = (ctx->opcode >> 13) & 0x7;
                 fmt = (ctx->opcode >> 9) & 0x3;
                 switch ((ctx->opcode >> 6) & 0x7) {
                 case MOVF_FMT:
-                    switch (fmt) {
-                    case FMT_SDPS_S:
-                        gen_movcf_s(ctx, rs, rt, cc, 0);
-                        break;
-                    case FMT_SDPS_D:
-                        gen_movcf_d(ctx, rs, rt, cc, 0);
-                        break;
-                    case FMT_SDPS_PS:
-                        gen_movcf_ps(ctx, rs, rt, cc, 0);
-                        break;
-                    default:
-                        goto pool32f_invalid;
+                    /* RINT_FMT */
+                    if (ctx->insn_flags & ISA_MIPS32R6) {
+                        switch (fmt) {
+                        case FMT_SDPS_S:
+                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
+                            break;
+                        case FMT_SDPS_D:
+                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
+                            break;
+                        default:
+                            goto pool32f_invalid;
+                        }
+                    } else {
+                        switch (fmt) {
+                        case FMT_SDPS_S:
+                            gen_movcf_s(ctx, rs, rt, cc, 0);
+                            break;
+                        case FMT_SDPS_D:
+                            gen_movcf_d(ctx, rs, rt, cc, 0);
+                            break;
+                        case FMT_SDPS_PS:
+                            gen_movcf_ps(ctx, rs, rt, cc, 0);
+                            break;
+                        default:
+                            goto pool32f_invalid;
+                        }
                     }
                     break;
                 case MOVT_FMT:
-                    switch (fmt) {
-                    case FMT_SDPS_S:
-                        gen_movcf_s(ctx, rs, rt, cc, 1);
-                        break;
-                    case FMT_SDPS_D:
-                        gen_movcf_d(ctx, rs, rt, cc, 1);
-                        break;
-                    case FMT_SDPS_PS:
-                        gen_movcf_ps(ctx, rs, rt, cc, 1);
-                        break;
-                    default:
-                        goto pool32f_invalid;
+                    /* CLASS_FMT */
+                    if (ctx->insn_flags & ISA_MIPS32R6) {
+                        switch (fmt) {
+                        case FMT_SDPS_S:
+                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
+                            break;
+                        case FMT_SDPS_D:
+                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
+                            break;
+                        default:
+                            goto pool32f_invalid;
+                        }
+                    } else {
+                        switch (fmt) {
+                        case FMT_SDPS_S:
+                            gen_movcf_s(ctx, rs, rt, cc, 1);
+                            break;
+                        case FMT_SDPS_D:
+                            gen_movcf_d(ctx, rs, rt, cc, 1);
+                            break;
+                        case FMT_SDPS_PS:
+                            gen_movcf_ps(ctx, rs, rt, cc, 1);
+                            break;
+                        default:
+                            goto pool32f_invalid;
+                        }
                     }
                     break;
                 case PREFX:
@@ -14127,6 +14189,32 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                 default:                                \
                     goto pool32f_invalid;               \
                 }
+            case MINA_FMT:
+                check_insn(ctx, ISA_MIPS32R6);
+                switch (ctx->opcode >> 9 & 0x3) {
+                case FMT_SDPS_S:
+                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
+                    break;
+                case FMT_SDPS_D:
+                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
+                    break;
+                default:
+                    goto pool32f_invalid;
+                }
+                break;
+            case MAXA_FMT:
+                check_insn(ctx, ISA_MIPS32R6);
+                switch (ctx->opcode >> 9 & 0x3) {
+                case FMT_SDPS_S:
+                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
+                    break;
+                case FMT_SDPS_D:
+                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
+                    break;
+                default:
+                    goto pool32f_invalid;
+                }
+                break;
             case 0x30:
                 /* regular FP ops */
                 switch ((ctx->opcode >> 6) & 0x3) {
@@ -14155,13 +14243,88 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
                 break;
             case 0x38:
                 /* cmovs */
-                switch ((ctx->opcode >> 6) & 0x3) {
+                switch ((ctx->opcode >> 6) & 0x7) {
                 case MOVN_FMT:
+                    /* SELNEZ_FMT */
+                    if (ctx->insn_flags & ISA_MIPS32R6) {
+                        switch (ctx->opcode >> 9 & 0x3) {
+                        case FMT_SDPS_S:
+                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
+                            break;
+                        case FMT_SDPS_D:
+                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
+                            break;
+                        default:
+                            goto pool32f_invalid;
+                        }
+                    } else {
+                        FINSN_3ARG_SDPS(MOVN);
+                    }
+                    break;
+                case MOVN_FMT_04:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     FINSN_3ARG_SDPS(MOVN);
                     break;
                 case MOVZ_FMT:
+                    /* SELEQZ_FMT */
+                    if (ctx->insn_flags & ISA_MIPS32R6) {
+                        switch (ctx->opcode >> 9 & 0x3) {
+                        case FMT_SDPS_S:
+                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
+                            break;
+                        case FMT_SDPS_D:
+                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
+                            break;
+                        default:
+                            goto pool32f_invalid;
+                        }
+                    } else {
+                        FINSN_3ARG_SDPS(MOVZ);
+                    }
+                    break;
+                case MOVZ_FMT_05:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     FINSN_3ARG_SDPS(MOVZ);
                     break;
+                case SEL_FMT:
+                    check_insn(ctx, ISA_MIPS32R6);
+                    switch (ctx->opcode >> 9 & 0x3) {
+                    case FMT_SDPS_S:
+                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
+                        break;
+                    case FMT_SDPS_D:
+                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
+                        break;
+                    default:
+                        goto pool32f_invalid;
+                    }
+                    break;
+                case MADDF_FMT:
+                    check_insn(ctx, ISA_MIPS32R6);
+                    switch (ctx->opcode >> 9 & 0x3) {
+                    case FMT_SDPS_S:
+                        mips32_op = OPC_MADDF_S;
+                        goto do_fpop;
+                    case FMT_SDPS_D:
+                        mips32_op = OPC_MADDF_D;
+                        goto do_fpop;
+                    default:
+                        goto pool32f_invalid;
+                    }
+                    break;
+                case MSUBF_FMT:
+                    check_insn(ctx, ISA_MIPS32R6);
+                    switch (ctx->opcode >> 9 & 0x3) {
+                    case FMT_SDPS_S:
+                        mips32_op = OPC_MSUBF_S;
+                        goto do_fpop;
+                    case FMT_SDPS_D:
+                        mips32_op = OPC_MSUBF_D;
+                        goto do_fpop;
+                    default:
+                        goto pool32f_invalid;
+                    }
+                    break;
                 default:
                     goto pool32f_invalid;
                 }
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 10/13] target-mips: microMIPS32 R6 POOL32{I, C} instructions
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (8 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 09/13] target-mips: microMIPS32 R6 POOL32F instructions Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-16 13:13   ` Leon Alrae
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 11/13] target-mips: microMIPS32 R6 Major instructions Yongbok Kim
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

add new microMIPS32 Release 6 POOL32I/POOL32C type instructions

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |   36 ++++++++++++++++++++++++++++++++----
 1 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 3d9145c..5be2a9c 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -14412,8 +14412,16 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
             mips32_op = OPC_TGEIU;
             goto do_trapi;
         case TNEI:
-            mips32_op = OPC_TNEI;
-            goto do_trapi;
+            /* SYNCI */
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                /* Break the TB to be able to sync copied instructions
+                   immediately */
+                ctx->bstate = BS_STOP;
+            } else {
+                mips32_op = OPC_TNEI;
+                goto do_trapi;
+            }
+            break;
         case TEQI:
             check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_TEQI;
@@ -14537,10 +14545,18 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
             check_insn(ctx, ISA_MIPS3);
             check_mips_64(ctx);
             mips32_op = OPC_LLD;
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 9));
+                break;
+            }
             goto do_ld_lr;
 #endif
         case LL:
             mips32_op = OPC_LL;
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 9));
+                break;
+            }
             goto do_ld_lr;
         do_ld_lr:
             gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
@@ -14549,17 +14565,29 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
             gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
             break;
         case SC:
-            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 9));
+            } else {
+                gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
+            }
             break;
 #if defined(TARGET_MIPS64)
         case SCD:
             check_insn(ctx, ISA_MIPS3);
             check_mips_64(ctx);
-            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 9));
+            } else {
+                gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
+            }
             break;
 #endif
         case PREF:
             /* Treat as no-op */
+            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
+                /* hint codes 24-31 are reserved and signal RI */
+                generate_exception(ctx, EXCP_RI);
+            }
             break;
         default:
             MIPS_INVAL("pool32c");
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 11/13] target-mips: microMIPS32 R6 Major instructions
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (9 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 10/13] target-mips: microMIPS32 R6 POOL32{I, C} instructions Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-16 13:07   ` Leon Alrae
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 12/13] target-mips: microMIPS32 R6 POOL16{A, C} instructions Yongbok Kim
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 13/13] target-mips: add mips32r6-generic CPU definition Yongbok Kim
  12 siblings, 1 reply; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

add new microMIPS32 Release 6 Major opcode instructions

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |   58 ++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 5be2a9c..3ac9632 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -14596,8 +14596,21 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
         }
         break;
     case ADDI32:
-        mips32_op = OPC_ADDI;
-        goto do_addi;
+        /* AUI, LUI */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            if (rs != 0) {
+                /* AUI */
+                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
+                tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
+            } else {
+                /* LUI */
+                tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
+            }
+        } else {
+            mips32_op = OPC_ADDI;
+            goto do_addi;
+        }
+        break;
     case ADDIU32:
         mips32_op = OPC_ADDIU;
     do_addi:
@@ -14719,7 +14732,46 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
         break;
     case ADDIUPC:
-        {
+        /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            int reg = ZIMM(ctx->opcode, 21, 5);
+            target_long offset;
+            target_long addr;
+            switch ((ctx->opcode >> 16) & 0x1f) {
+            case ADDIUPC_00 ... ADDIUPC_07:
+                if (reg != 0) {
+                    offset = sextract32(ctx->opcode << 2, 0, 21);
+                    addr = addr_add(ctx, ctx->pc & ~0x3, offset);
+                    tcg_gen_movi_tl(cpu_gpr[reg], addr);
+                }
+                break;
+            case AUIPC:
+                if (reg != 0) {
+                    offset = imm << 16;
+                    addr = addr_add(ctx, ctx->pc, offset);
+                    tcg_gen_movi_tl(cpu_gpr[reg], addr);
+                }
+                break;
+            case ALUIPC:
+                if (reg != 0) {
+                    offset = imm << 16;
+                    addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
+                    tcg_gen_movi_tl(cpu_gpr[reg], addr);
+                }
+                break;
+            case LWPC_08 ... LWPC_0F:
+                if (reg != 0) {
+                    target_long addr;
+                    offset = sextract32(ctx->opcode << 2, 0, 21);
+                    addr = addr_add(ctx, ctx->pc & ~0x3, offset);
+                    gen_r6_ld(addr, reg, ctx->mem_idx, MO_TESL);
+                }
+                break;
+            default:
+                generate_exception(ctx, EXCP_RI);
+                break;
+            }
+        } else {
             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
             int offset = SIMM(ctx->opcode, 0, 23) << 2;
 
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 12/13] target-mips: microMIPS32 R6 POOL16{A, C} instructions
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (10 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 11/13] target-mips: microMIPS32 R6 Major instructions Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 13/13] target-mips: add mips32r6-generic CPU definition Yongbok Kim
  12 siblings, 0 replies; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

microMIPS32 Release 6 POOL16A/ POOL16C instructions

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate.c |  107 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 3ac9632..936fb3e 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12929,6 +12929,101 @@ static void gen_pool16c_insn(DisasContext *ctx)
     }
 }
 
+static void gen_pool16c_r6_insn(DisasContext *ctx)
+{
+    int rt = mmreg((ctx->opcode >> 7) & 0x7);
+    int rs = mmreg((ctx->opcode >> 4) & 0x7);
+
+    switch (ctx->opcode & 0xf) {
+    case R6_NOT16:
+        gen_logic(ctx, OPC_NOR, rt, rs, 0);
+        break;
+    case R6_AND16:
+        gen_logic(ctx, OPC_AND, rt, rt, rs);
+        break;
+    case R6_LWM16:
+        {
+            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
+            int offset = ZIMM(ctx->opcode, 4, 4);
+            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 8) & 0x3],
+                              29, offset << 2);
+        }
+        break;
+    case R6_JRC16:
+        switch (ctx->opcode >> 4 & 1) {
+        case 0:
+            /* JRC16 */
+            {
+                int reg = (ctx->opcode >> 5) & 0x1f;
+                gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
+            }
+            break;
+        case 1:
+            /* JRCADDIUSP */
+            {
+                int imm = ZIMM(ctx->opcode, 5, 5);
+                gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
+                gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
+            }
+            break;
+        }
+        break;
+    case MOVEP ... MOVEP_07:
+    case MOVEP_0C ... MOVEP_0F:
+        {
+            int enc_dest = uMIPS_RD(ctx->opcode);
+            int enc_rt = uMIPS_RS2(ctx->opcode);
+            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
+            int rd, rs, re, rt;
+            static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
+            static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
+            static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
+            rd = rd_enc[enc_dest];
+            re = re_enc[enc_dest];
+            rs = rs_rt_enc[enc_rs];
+            rt = rs_rt_enc[enc_rt];
+            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
+            gen_arith(ctx, OPC_ADDU, re, rt, 0);
+        }
+        break;
+    case R6_XOR16:
+        gen_logic(ctx, OPC_XOR, rt, rt, rs);
+        break;
+    case R6_OR16:
+        gen_logic(ctx, OPC_OR, rt, rt, rs);
+        break;
+    case R6_SWM16:
+        {
+            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
+            int offset = ZIMM(ctx->opcode, 4, 4);
+            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 8) & 0x3],
+                              29, offset << 2);
+        }
+        break;
+    case JALRC16:
+        switch (ctx->opcode >> 4 & 3) {
+        case 0:
+        case 2:
+            /* JALRC16 */
+            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
+                               31, 0, 0);
+            break;
+        case 1:
+            /* BREAK16 */
+            generate_exception(ctx, EXCP_BREAK);
+            break;
+        case 3:
+            /* SDBBP16 */
+            generate_exception(ctx, EXCP_DBp);
+            break;
+        }
+        break;
+    default:
+        generate_exception(ctx, EXCP_RI);
+        break;
+    }
+}
+
 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
 {
     TCGv t0 = tcg_temp_new();
@@ -14942,7 +15037,11 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
             uint32_t opc = 0;
-
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                rd = mmreg(uMIPS_RS1(ctx->opcode));
+                rs1 = mmreg(uMIPS_RD(ctx->opcode));
+                rs2 = mmreg(uMIPS_RS2(ctx->opcode));
+            }
             switch (ctx->opcode & 0x1) {
             case ADDU16:
                 opc = OPC_ADDU;
@@ -14976,7 +15075,11 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case POOL16C:
-        gen_pool16c_insn(ctx);
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            gen_pool16c_r6_insn(ctx);
+        } else {
+            gen_pool16c_insn(ctx);
+        }
         break;
     case LWGP16:
         {
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH 13/13] target-mips: add mips32r6-generic CPU definition
  2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (11 preceding siblings ...)
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 12/13] target-mips: microMIPS32 R6 POOL16{A, C} instructions Yongbok Kim
@ 2015-06-12 14:02 ` Yongbok Kim
  12 siblings, 0 replies; 25+ messages in thread
From: Yongbok Kim @ 2015-06-12 14:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

Define a new CPU definition supporting MIPS32 Release 6 ISA and
microMIPS32 Release 6 ISA.

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
---
 target-mips/translate_init.c |   37 +++++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 51e7c98..c18517e 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -421,6 +421,43 @@ static const mips_def_t mips_defs[] =
         .insn_flags = CPU_MIPS32R5 | ASE_MIPS16 | ASE_MSA,
         .mmu_type = MMU_TYPE_R4000,
     },
+    {
+        /* A generic CPU supporting MIPS32 Release 6 ISA.
+           FIXME: Support IEEE 754-2008 FP.
+                  Eventually this should be replaced by a real CPU model. */
+        .name = "mips32r6-generic",
+        .CP0_PRid = 0x00010000,
+        .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) |
+                       (MMU_TYPE_R4000 << CP0C0_MT),
+        .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) |
+                       (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
+                       (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
+                       (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
+        .CP0_Config2 = MIPS_CONFIG2,
+        .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_BP) | (1 << CP0C3_BI) |
+                       (2 << CP0C3_ISA) | (1 << CP0C3_ULRI) |
+                       (1 << CP0C3_RXI) | (1U << CP0C3_M),
+        .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
+                       (3 << CP0C4_IE) | (1U << CP0C4_M),
+        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB),
+        .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
+                                  (1 << CP0C5_UFE),
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 0,
+        .SYNCI_Step = 32,
+        .CCRes = 2,
+        .CP0_Status_rw_bitmask = 0x3058FF1F,
+        .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) |
+                         (1U << CP0PG_RIE),
+        .CP0_PageGrain_rw_bitmask = 0,
+        .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) |
+                    (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
+                    (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
+        .SEGBITS = 32,
+        .PABITS = 32,
+        .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS,
+        .mmu_type = MMU_TYPE_R4000,
+    },
 #if defined(TARGET_MIPS64)
     {
         .name = "R4000",
-- 
1.7.5.4

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

* Re: [Qemu-devel] [PATCH 01/13] target-mips: fix {D, W}RGPR in microMIPS
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 01/13] target-mips: fix {D, W}RGPR in microMIPS Yongbok Kim
@ 2015-06-15 11:16   ` Aurelien Jarno
  2015-06-15 16:19   ` Leon Alrae
  1 sibling, 0 replies; 25+ messages in thread
From: Aurelien Jarno @ 2015-06-15 11:16 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-12 15:02, Yongbok Kim wrote:
> rt, rs were swapped
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index f6ae0d3..d4a530d 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -12749,12 +12749,12 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
>          case RDPGPR:
>              check_cp0_enabled(ctx);
>              check_insn(ctx, ISA_MIPS32R2);
> -            gen_load_srsgpr(rt, rs);
> +            gen_load_srsgpr(rs, rt);
>              break;
>          case WRPGPR:
>              check_cp0_enabled(ctx);
>              check_insn(ctx, ISA_MIPS32R2);
> -            gen_store_srsgpr(rt, rs);
> +            gen_store_srsgpr(rs, rt);
>              break;
>          default:
>              goto pool32axf_invalid;

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>

Note however that your subject should be {RD,WR}PGPR to correctly match
both instructions.


-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

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

* Re: [Qemu-devel] [PATCH 03/13] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 03/13] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP Yongbok Kim
@ 2015-06-15 11:32   ` Leon Alrae
  0 siblings, 0 replies; 25+ messages in thread
From: Leon Alrae @ 2015-06-15 11:32 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 12/06/2015 15:02, Yongbok Kim wrote:
> Refactor those instructions in order to reuse them for microMIPS32
> Release 6.
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |  164 +++++++++++++++++++++++++++++-----------------
>  1 files changed, 103 insertions(+), 61 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index b8c7164..2244630 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -4831,6 +4831,102 @@ static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
>      tcg_temp_free(t0);
>  }
>  
> +static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
> +        int imm2)

Indentation is unusual.

> +{
> +    TCGv t0;
> +    TCGv t1;
> +    if (rd == 0) {
> +        /* Treat as NOP. */
> +        return;
> +    }
> +    t0 = tcg_temp_new();
> +    t1 = tcg_temp_new();
> +    gen_load_gpr(t0, rs);
> +    gen_load_gpr(t1, rt);
> +    tcg_gen_shli_tl(t0, t0, imm2 + 1);
> +    switch (opc) {
> +    case OPC_LSA:
> +        tcg_gen_add_tl(t0, t0, t1);
> +        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
> +        break;
> +#if defined(TARGET_MIPS64)
> +    case OPC_DLSA:
> +        tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
> +        break;
> +#endif

The only difference between LSA and DLSA is that LSA sign extends the value
from bit 31.

Wouldn't it be better to replace this switch with:

tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
if (opc == OPC_LSA) {
    tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
}

> +    }
> +    tcg_temp_free(t1);
> +    tcg_temp_free(t0);
> +
> +    return;
> +}
> +
> +static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
> +        int bp)
> +{
> +    TCGv t0;
> +    if (rd == 0) {
> +        /* Treat as NOP. */
> +        return;
> +    }
> +    t0 = tcg_temp_new();
> +    gen_load_gpr(t0, rt);
> +    if (bp == 0) {
> +        tcg_gen_mov_tl(cpu_gpr[rd], t0);
> +    } else {
> +        TCGv t1 = tcg_temp_new();
> +        gen_load_gpr(t1, rs);
> +        switch (opc) {
> +        case OPC_ALIGN:
> +            {
> +                TCGv_i64 t2 = tcg_temp_new_i64();
> +                tcg_gen_concat_tl_i64(t2, t1, t0);
> +                tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
> +#if defined(TARGET_MIPS64)
> +                tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
> +#else
> +                tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
> +#endif

This can be replaced with gen_move_low32().

> +                tcg_temp_free_i64(t2);
> +            }
> +            break;
> +#if defined(TARGET_MIPS64)
> +        case OPC_DALIGN:
> +            tcg_gen_shli_tl(t0, t0, 8 * bp);
> +            tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
> +            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
> +            break;
> +#endif
> +        }
> +        tcg_temp_free(t1);
> +    }
> +
> +    tcg_temp_free(t0);
> +}
> +
> +static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
> +{
> +    TCGv t0;
> +    if (rd == 0) {
> +        /* Treat as NOP. */
> +        return;
> +    }
> +    t0 = tcg_temp_new();
> +    gen_load_gpr(t0, rt);
> +    switch (opc) {
> +    case OPC_BITSWAP:
> +        gen_helper_bitswap(cpu_gpr[rd], t0);
> +        break;
> +#if defined(TARGET_MIPS64)
> +    case OPC_DBITSWAP:
> +        gen_helper_dbitswap(cpu_gpr[rd], t0);
> +        break;
> +#endif
> +    }
> +    tcg_temp_free(t0);
> +}
> +
>  #ifndef CONFIG_USER_ONLY
>  /* CP0 (MMU and control) */
>  static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
> @@ -16191,18 +16287,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
>      op1 = MASK_SPECIAL(ctx->opcode);
>      switch (op1) {
>      case OPC_LSA:
> -        if (rd != 0) {
> -            int imm2 = extract32(ctx->opcode, 6, 3);
> -            TCGv t0 = tcg_temp_new();
> -            TCGv t1 = tcg_temp_new();
> -            gen_load_gpr(t0, rs);
> -            gen_load_gpr(t1, rt);
> -            tcg_gen_shli_tl(t0, t0, imm2 + 1);
> -            tcg_gen_add_tl(t0, t0, t1);
> -            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
> -            tcg_temp_free(t1);
> -            tcg_temp_free(t0);
> -        }
> +        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));

Thanks for fixing the bug, length is indeed 2. It worked because additional
bit we read here was always 0.

>          break;
>      case OPC_MULT ... OPC_DIVU:
>          op2 = MASK_R6_MULDIV(ctx->opcode);
> @@ -16247,17 +16332,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
>  #if defined(TARGET_MIPS64)
>      case OPC_DLSA:
>          check_mips_64(ctx);
> -        if (rd != 0) {
> -            int imm2 = extract32(ctx->opcode, 6, 3);
> -            TCGv t0 = tcg_temp_new();
> -            TCGv t1 = tcg_temp_new();
> -            gen_load_gpr(t0, rs);
> -            gen_load_gpr(t1, rt);
> -            tcg_gen_shli_tl(t0, t0, imm2 + 1);
> -            tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
> -            tcg_temp_free(t1);
> -            tcg_temp_free(t0);
> -        }
> +        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
>          break;
>      case R6_OPC_DCLO:
>      case R6_OPC_DCLZ:
> @@ -16682,35 +16757,15 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
>                  /* Treat as NOP. */
>                  break;
>              }
> -            TCGv t0 = tcg_temp_new();
> -            gen_load_gpr(t0, rt);
> -
>              op2 = MASK_BSHFL(ctx->opcode);
>              switch (op2) {
>              case OPC_ALIGN ... OPC_ALIGN_END:
> -                sa &= 3;
> -                if (sa == 0) {
> -                    tcg_gen_mov_tl(cpu_gpr[rd], t0);
> -                } else {
> -                    TCGv t1 = tcg_temp_new();
> -                    TCGv_i64 t2 = tcg_temp_new_i64();
> -                    gen_load_gpr(t1, rs);
> -                    tcg_gen_concat_tl_i64(t2, t1, t0);
> -                    tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
> -#if defined(TARGET_MIPS64)
> -                    tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
> -#else
> -                    tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
> -#endif
> -                    tcg_temp_free_i64(t2);
> -                    tcg_temp_free(t1);
> -                }
> +                gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
>                  break;
>              case OPC_BITSWAP:
> -                gen_helper_bitswap(cpu_gpr[rd], t0);
> +                gen_bitswap(ctx, op2, rd, rt);
>                  break;
>              }
> -            tcg_temp_free(t0);
>          }
>          break;
>  #if defined(TARGET_MIPS64)
> @@ -16727,29 +16782,16 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
>                  /* Treat as NOP. */
>                  break;
>              }
> -            TCGv t0 = tcg_temp_new();
> -            gen_load_gpr(t0, rt);
> -
>              op2 = MASK_DBSHFL(ctx->opcode);
>              switch (op2) {
>              case OPC_DALIGN ... OPC_DALIGN_END:
> -                sa &= 7;
> -                if (sa == 0) {
> -                    tcg_gen_mov_tl(cpu_gpr[rd], t0);
> -                } else {
> -                    TCGv t1 = tcg_temp_new();
> -                    gen_load_gpr(t1, rs);
> -                    tcg_gen_shli_tl(t0, t0, 8 * sa);
> -                    tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
> -                    tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
> -                    tcg_temp_free(t1);
> -                }
> +                gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
>                  break;
>              case OPC_DBITSWAP:
> -                gen_helper_dbitswap(cpu_gpr[rd], t0);
> +                gen_bitswap(ctx, op2, rd, rt);
>                  break;
>              }
> -            tcg_temp_free(t0);
> +
>          }
>          break;
>  #endif
> 

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

* Re: [Qemu-devel] [PATCH 02/13] target-mips: add microMIPS TLBINV, TLBINVF
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 02/13] target-mips: add microMIPS TLBINV, TLBINVF Yongbok Kim
@ 2015-06-15 11:50   ` Aurelien Jarno
  2015-06-15 16:19   ` Leon Alrae
  1 sibling, 0 replies; 25+ messages in thread
From: Aurelien Jarno @ 2015-06-15 11:50 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-12 15:02, Yongbok Kim wrote:
> add microMIPS TLBINV, TLBINVF
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index d4a530d..b8c7164 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -11991,6 +11991,8 @@ enum {
>      TLBR = 0x1,
>      TLBWI = 0x2,
>      TLBWR = 0x3,
> +    TLBINV = 0x4,
> +    TLBINVF = 0x5,
>      WAIT = 0x9,
>      IRET = 0xd,
>      DERET = 0xe,
> @@ -12775,6 +12777,12 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
>          case TLBWR:
>              mips32_op = OPC_TLBWR;
>              goto do_cp0;
> +        case TLBINV:
> +            mips32_op = OPC_TLBINV;
> +            goto do_cp0;
> +        case TLBINVF:
> +            mips32_op = OPC_TLBINVF;
> +            goto do_cp0;
>          case WAIT:
>              mips32_op = OPC_WAIT;
>              goto do_cp0;

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

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

* Re: [Qemu-devel] [PATCH 05/13] target-mips: signal RI for removed instructions in microMIPS R6
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 05/13] target-mips: signal RI for removed instructions in microMIPS R6 Yongbok Kim
@ 2015-06-15 16:18   ` Leon Alrae
  0 siblings, 0 replies; 25+ messages in thread
From: Leon Alrae @ 2015-06-15 16:18 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 12/06/2015 15:02, Yongbok Kim wrote:
> Signal a Reserved Instruction exception for removed instruction encoding
> in microMIPS Release 6.
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 68 insertions(+), 0 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 79a5c6b..dbf51d1 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -13014,15 +13014,19 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
>              gen_bshfl(ctx, OPC_WSBH, rs, rt);
>              break;
>          case MULT:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_MULT;
>              goto do_mul;
>          case MULTU:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_MULTU;
>              goto do_mul;
>          case DIV:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_DIV;
>              goto do_div;
>          case DIVU:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_DIVU;
>              goto do_div;
>          do_div:
> @@ -13030,15 +13034,19 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
>              gen_muldiv(ctx, mips32_op, 0, rs, rt);
>              break;
>          case MADD:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_MADD;
>              goto do_mul;
>          case MADDU:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_MADDU;
>              goto do_mul;
>          case MSUB:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_MSUB;
>              goto do_mul;
>          case MSUBU:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_MSUBU;
>          do_mul:
>              check_insn(ctx, ISA_MIPS32);
> @@ -13071,6 +13079,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
>              break;
>          case JALRS:
>          case JALRS_HB:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
>              ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
>              break;
> @@ -13203,6 +13212,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
>          }
>          break;
>      case 0x35:
> +        check_insn_opc_removed(ctx, ISA_MIPS32R6);
>          switch (minor) {
>          case MFHI32:
>              gen_HILO(ctx, OPC_MFHI, 0, rs);
> @@ -13475,6 +13485,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
>      case COND_FLOAT_MOV(MOVT, 5):
>      case COND_FLOAT_MOV(MOVT, 6):
>      case COND_FLOAT_MOV(MOVT, 7):
> +        check_insn_opc_removed(ctx, ISA_MIPS32R6);
>          gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
>          break;
>      case COND_FLOAT_MOV(MOVF, 0):
> @@ -13485,6 +13496,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
>      case COND_FLOAT_MOV(MOVF, 5):
>      case COND_FLOAT_MOV(MOVF, 6):
>      case COND_FLOAT_MOV(MOVF, 7):
> +        check_insn_opc_removed(ctx, ISA_MIPS32R6);

I couldn't find MOVF on the list of removed instructions in Table 2.3 in the
microMIPS R6 manual. But there is MOVT and also MOVF was removed in MIPS R6,
so I presume it's manual's issue and code is correct.

>          gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
>          break;
>      default:
> @@ -13556,6 +13568,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>                  mips32_op = OPC_SUBU;
>                  goto do_arith;
>              case MUL:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_MUL;
>              do_arith:
>                  gen_arith(ctx, mips32_op, rd, rs, rt);
> @@ -13687,47 +13700,61 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>              check_cp1_enabled(ctx);
>              switch (minor) {
>              case ALNV_PS:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_ALNV_PS;
>                  goto do_madd;
>              case MADD_S:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_MADD_S;
>                  goto do_madd;
>              case MADD_D:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_MADD_D;
>                  goto do_madd;
>              case MADD_PS:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_MADD_PS;
>                  goto do_madd;
>              case MSUB_S:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_MSUB_S;
>                  goto do_madd;
>              case MSUB_D:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_MSUB_D;
>                  goto do_madd;
>              case MSUB_PS:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_MSUB_PS;
>                  goto do_madd;
>              case NMADD_S:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_NMADD_S;
>                  goto do_madd;
>              case NMADD_D:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_NMADD_D;
>                  goto do_madd;
>              case NMADD_PS:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_NMADD_PS;
>                  goto do_madd;
>              case NMSUB_S:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_NMSUB_S;
>                  goto do_madd;
>              case NMSUB_D:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_NMSUB_D;
>                  goto do_madd;
>              case NMSUB_PS:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  mips32_op = OPC_NMSUB_PS;
>              do_madd:
>                  gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
>                  break;
>              case CABS_COND_FMT:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  cond = (ctx->opcode >> 6) & 0xf;
>                  cc = (ctx->opcode >> 13) & 0x7;
>                  fmt = (ctx->opcode >> 10) & 0x3;
> @@ -13746,6 +13773,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>                  }
>                  break;
>              case C_COND_FMT:
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  cond = (ctx->opcode >> 6) & 0xf;
>                  cc = (ctx->opcode >> 13) & 0x7;
>                  fmt = (ctx->opcode >> 10) & 0x3;
> @@ -13782,6 +13810,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>                      mips32_op = OPC_PUU_PS;
>                      goto do_ps;
>                  case CVT_PS_S:
> +                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                      mips32_op = OPC_CVT_PS_S;
>                  do_ps:
>                      gen_farith(ctx, mips32_op, rt, rs, rd, 0);
> @@ -13794,21 +13823,27 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>                  /* [LS][WDU]XC1 */
>                  switch ((ctx->opcode >> 6) & 0x7) {
>                  case LWXC1:
> +                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                      mips32_op = OPC_LWXC1;
>                      goto do_ldst_cp1;
>                  case SWXC1:
> +                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                      mips32_op = OPC_SWXC1;
>                      goto do_ldst_cp1;
>                  case LDXC1:
> +                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                      mips32_op = OPC_LDXC1;
>                      goto do_ldst_cp1;
>                  case SDXC1:
> +                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                      mips32_op = OPC_SDXC1;
>                      goto do_ldst_cp1;
>                  case LUXC1:
> +                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                      mips32_op = OPC_LUXC1;
>                      goto do_ldst_cp1;
>                  case SUXC1:
> +                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                      mips32_op = OPC_SUXC1;
>                  do_ldst_cp1:
>                      gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
> @@ -13819,6 +13854,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>                  break;
>              case 0x18:
>                  /* 3D insns */
> +                check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                  fmt = (ctx->opcode >> 9) & 0x3;
>                  switch ((ctx->opcode >> 6) & 0x7) {
>                  case RSQRT2_FMT:
> @@ -13899,6 +13935,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>                      }
>                      break;
>                  case PREFX:
> +                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
>                      break;
>                  default:
>                      goto pool32f_invalid;
> @@ -13974,31 +14011,39 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>          minor = (ctx->opcode >> 21) & 0x1f;
>          switch (minor) {
>          case BLTZ:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
>              break;
>          case BLTZAL:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
>              ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
>              break;
>          case BLTZALS:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
>              ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
>              break;
>          case BGEZ:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
>              break;
>          case BGEZAL:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
>              ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
>              break;
>          case BGEZALS:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
>              ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
>              break;
>          case BLEZ:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
>              break;
>          case BGTZ:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
>              break;
>  
> @@ -14010,15 +14055,18 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>              mips32_op = OPC_TGEI;
>              goto do_trapi;
>          case TLTIU:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_TLTIU;
>              goto do_trapi;
>          case TGEIU:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_TGEIU;
>              goto do_trapi;
>          case TNEI:
>              mips32_op = OPC_TNEI;
>              goto do_trapi;
>          case TEQI:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_TEQI;
>          do_trapi:
>              gen_trap(ctx, mips32_op, rs, -1, imm);
> @@ -14026,6 +14074,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>  
>          case BNEZC:
>          case BEQZC:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
>                                 4, rs, 0, imm << 1, 0);
>              /* Compact branches don't have a delay slot, so just let
> @@ -14033,28 +14082,35 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>                 target. */
>              break;
>          case LUI:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
>              break;
>          case SYNCI:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              /* Break the TB to be able to sync copied instructions
>                 immediately */
>              ctx->bstate = BS_STOP;
>              break;
>          case BC2F:
>          case BC2T:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              /* COP2: Not implemented. */
>              generate_exception_err(ctx, EXCP_CpU, 2);
>              break;
>          case BC1F:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
>              goto do_cp1branch;
>          case BC1T:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
>              goto do_cp1branch;
>          case BC1ANY4F:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_BC1FANY4;
>              goto do_cp1mips3d;
>          case BC1ANY4T:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_BC1TANY4;
>          do_cp1mips3d:
>              check_cop1x(ctx);
> @@ -14083,36 +14139,44 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>          minor = (ctx->opcode >> 12) & 0xf;
>          switch (minor) {
>          case LWL:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_LWL;
>              goto do_ld_lr;
>          case SWL:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_SWL;
>              goto do_st_lr;
>          case LWR:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_LWR;
>              goto do_ld_lr;
>          case SWR:
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_SWR;
>              goto do_st_lr;
>  #if defined(TARGET_MIPS64)
>          case LDL:
>              check_insn(ctx, ISA_MIPS3);
>              check_mips_64(ctx);
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_LDL;
>              goto do_ld_lr;
>          case SDL:
>              check_insn(ctx, ISA_MIPS3);
>              check_mips_64(ctx);
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_SDL;
>              goto do_st_lr;
>          case LDR:
>              check_insn(ctx, ISA_MIPS3);
>              check_mips_64(ctx);
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_LDR;
>              goto do_ld_lr;
>          case SDR:
>              check_insn(ctx, ISA_MIPS3);
>              check_mips_64(ctx);
> +            check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_SDR;
>              goto do_st_lr;
>          case LWU:
> @@ -14186,6 +14250,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>          gen_slt_imm(ctx, mips32_op, rt, rs, imm);
>          break;
>      case JALX32:
> +        check_insn_opc_removed(ctx, ISA_MIPS32R6);
>          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
>          gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
>          ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
> @@ -14202,10 +14267,12 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>          gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
>          break;
>      case J32:
> +        check_insn_opc_removed(ctx, ISA_MIPS32R6);
>          gen_compute_branch(ctx, OPC_J, 4, rt, rs,
>                             (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
>          break;
>      case JAL32:
> +        check_insn_opc_removed(ctx, ISA_MIPS32R6);
>          gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
>                             (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
>          ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
> @@ -14384,6 +14451,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
>          }
>          break;
>      case POOL16F:
> +        check_insn_opc_removed(ctx, ISA_MIPS32R6);
>          if (ctx->opcode & 1) {
>              generate_exception(ctx, EXCP_RI);
>          } else {
> 

AFAICT you missed *.PS instructions.

Leon

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

* Re: [Qemu-devel] [PATCH 01/13] target-mips: fix {D, W}RGPR in microMIPS
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 01/13] target-mips: fix {D, W}RGPR in microMIPS Yongbok Kim
  2015-06-15 11:16   ` Aurelien Jarno
@ 2015-06-15 16:19   ` Leon Alrae
  1 sibling, 0 replies; 25+ messages in thread
From: Leon Alrae @ 2015-06-15 16:19 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 12/06/2015 15:02, Yongbok Kim wrote:
> rt, rs were swapped
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>

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

* Re: [Qemu-devel] [PATCH 02/13] target-mips: add microMIPS TLBINV, TLBINVF
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 02/13] target-mips: add microMIPS TLBINV, TLBINVF Yongbok Kim
  2015-06-15 11:50   ` Aurelien Jarno
@ 2015-06-15 16:19   ` Leon Alrae
  1 sibling, 0 replies; 25+ messages in thread
From: Leon Alrae @ 2015-06-15 16:19 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 12/06/2015 15:02, Yongbok Kim wrote:
> add microMIPS TLBINV, TLBINVF
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)

Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>

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

* Re: [Qemu-devel] [PATCH 04/13] target-mips: rearrange gen_compute_compact_branch
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 04/13] target-mips: rearrange gen_compute_compact_branch Yongbok Kim
@ 2015-06-15 16:19   ` Leon Alrae
  0 siblings, 0 replies; 25+ messages in thread
From: Leon Alrae @ 2015-06-15 16:19 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 12/06/2015 15:02, Yongbok Kim wrote:
> The function will be also used for microMIPS Release 6.
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |  472 +++++++++++++++++++++++-----------------------
>  1 files changed, 236 insertions(+), 236 deletions(-)

Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>

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

* Re: [Qemu-devel] [PATCH 11/13] target-mips: microMIPS32 R6 Major instructions
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 11/13] target-mips: microMIPS32 R6 Major instructions Yongbok Kim
@ 2015-06-16 13:07   ` Leon Alrae
  0 siblings, 0 replies; 25+ messages in thread
From: Leon Alrae @ 2015-06-16 13:07 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 12/06/2015 15:02, Yongbok Kim wrote:
> add new microMIPS32 Release 6 Major opcode instructions
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |   58 ++++++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 55 insertions(+), 3 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 5be2a9c..3ac9632 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -14596,8 +14596,21 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>          }
>          break;
>      case ADDI32:
> -        mips32_op = OPC_ADDI;
> -        goto do_addi;
> +        /* AUI, LUI */
> +        if (ctx->insn_flags & ISA_MIPS32R6) {
> +            if (rs != 0) {
> +                /* AUI */
> +                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
> +                tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
> +            } else {
> +                /* LUI */
> +                tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
> +            }

Can't we just call gen_logic_imm(ctx, OPC_LUI, rt, rs, imm) here to avoid
duplication?

> +        } else {
> +            mips32_op = OPC_ADDI;
> +            goto do_addi;
> +        }
> +        break;
>      case ADDIU32:
>          mips32_op = OPC_ADDIU;
>      do_addi:
> @@ -14719,7 +14732,46 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>          gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
>          break;
>      case ADDIUPC:
> -        {
> +        /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
> +        if (ctx->insn_flags & ISA_MIPS32R6) {
> +            int reg = ZIMM(ctx->opcode, 21, 5);
> +            target_long offset;
> +            target_long addr;
> +            switch ((ctx->opcode >> 16) & 0x1f) {
> +            case ADDIUPC_00 ... ADDIUPC_07:
> +                if (reg != 0) {
> +                    offset = sextract32(ctx->opcode << 2, 0, 21);
> +                    addr = addr_add(ctx, ctx->pc & ~0x3, offset);
> +                    tcg_gen_movi_tl(cpu_gpr[reg], addr);
> +                }
> +                break;
> +            case AUIPC:
> +                if (reg != 0) {
> +                    offset = imm << 16;
> +                    addr = addr_add(ctx, ctx->pc, offset);
> +                    tcg_gen_movi_tl(cpu_gpr[reg], addr);
> +                }
> +                break;
> +            case ALUIPC:
> +                if (reg != 0) {
> +                    offset = imm << 16;
> +                    addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
> +                    tcg_gen_movi_tl(cpu_gpr[reg], addr);
> +                }
> +                break;
> +            case LWPC_08 ... LWPC_0F:
> +                if (reg != 0) {
> +                    target_long addr;
> +                    offset = sextract32(ctx->opcode << 2, 0, 21);
> +                    addr = addr_add(ctx, ctx->pc & ~0x3, offset);
> +                    gen_r6_ld(addr, reg, ctx->mem_idx, MO_TESL);
> +                }
> +                break;
> +            default:
> +                generate_exception(ctx, EXCP_RI);
> +                break;
> +            }

This looks very similar to equivalent MIPS R6 instructions. With relatively
small changes in gen_pcrel() we could reuse it for these instructions I think.

Leon

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

* Re: [Qemu-devel] [PATCH 10/13] target-mips: microMIPS32 R6 POOL32{I, C} instructions
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 10/13] target-mips: microMIPS32 R6 POOL32{I, C} instructions Yongbok Kim
@ 2015-06-16 13:13   ` Leon Alrae
  0 siblings, 0 replies; 25+ messages in thread
From: Leon Alrae @ 2015-06-16 13:13 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 12/06/2015 15:02, Yongbok Kim wrote:
> add new microMIPS32 Release 6 POOL32I/POOL32C type instructions
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |   36 ++++++++++++++++++++++++++++++++----
>  1 files changed, 32 insertions(+), 4 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 3d9145c..5be2a9c 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -14412,8 +14412,16 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>              mips32_op = OPC_TGEIU;
>              goto do_trapi;
>          case TNEI:
> -            mips32_op = OPC_TNEI;
> -            goto do_trapi;
> +            /* SYNCI */

I think the comment can be improved a bit because I still need to figure out
from the actual code which block implements SYNCI. I would suggest sticking to
existing style we have for single R6 and pre-R6 instructions which share
opcode, for example:

case OPC_BC1EQZ: /* OPC_BC1ANY2 */
    if (ctx->insn_flags & ISA_MIPS32R6) {
        /* OPC_BC1EQZ */
        ...
    } else {
        /* OPC_BC1ANY2 */
        ...
    }
    break;

> +            if (ctx->insn_flags & ISA_MIPS32R6) {
> +                /* Break the TB to be able to sync copied instructions
> +                   immediately */
> +                ctx->bstate = BS_STOP;
> +            } else {
> +                mips32_op = OPC_TNEI;
> +                goto do_trapi;
> +            }
> +            break;
>          case TEQI:
>              check_insn_opc_removed(ctx, ISA_MIPS32R6);
>              mips32_op = OPC_TEQI;
> @@ -14537,10 +14545,18 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>              check_insn(ctx, ISA_MIPS3);
>              check_mips_64(ctx);
>              mips32_op = OPC_LLD;
> +            if (ctx->insn_flags & ISA_MIPS32R6) {
> +                gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 9));
> +                break;
> +            }
>              goto do_ld_lr;
>  #endif
>          case LL:
>              mips32_op = OPC_LL;
> +            if (ctx->insn_flags & ISA_MIPS32R6) {
> +                gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 9));
> +                break;
> +            }
>              goto do_ld_lr;
>          do_ld_lr:
>              gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
> @@ -14549,17 +14565,29 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>              gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
>              break;
>          case SC:
> -            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
> +            if (ctx->insn_flags & ISA_MIPS32R6) {
> +                gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 9));
> +            } else {
> +                gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
> +            }
>              break;
>  #if defined(TARGET_MIPS64)
>          case SCD:
>              check_insn(ctx, ISA_MIPS3);
>              check_mips_64(ctx);
> -            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
> +            if (ctx->insn_flags & ISA_MIPS32R6) {
> +                gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 9));
> +            } else {
> +                gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
> +            }

Instead of adding new "if R6" to each of these instructions and calling the
same gen_st_cond/gen_ld function with just different hardcoded value, I think
it would be cleaner to reuse offset variable and set it just once (9 in R6 or
12 in pre-R6) at the beginning of case POOL32C. Thus here we would have just:

gen_st_cond(ctx, OPC_SCD, rt, rs, offset);

Thanks,
Leon

>              break;
>  #endif
>          case PREF:
>              /* Treat as no-op */
> +            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
> +                /* hint codes 24-31 are reserved and signal RI */
> +                generate_exception(ctx, EXCP_RI);
> +            }
>              break;
>          default:
>              MIPS_INVAL("pool32c");
> 

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

* Re: [Qemu-devel] [PATCH 08/13] target-mips: microMIPS32 R6 POOL32A{XF} instructions
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 08/13] target-mips: microMIPS32 R6 POOL32A{XF} instructions Yongbok Kim
@ 2015-06-16 15:24   ` Leon Alrae
  0 siblings, 0 replies; 25+ messages in thread
From: Leon Alrae @ 2015-06-16 15:24 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 12/06/2015 15:02, Yongbok Kim wrote:
> +            case R6_LWXS:
> +                check_insn(ctx, ISA_MIPS32R6);
> +                gen_ldxs(ctx, rs, rt, rd);
> +                break;

According to the manual LWXS is removed, not recoded.

Otherwise,

Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>

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

* Re: [Qemu-devel] [PATCH 09/13] target-mips: microMIPS32 R6 POOL32F instructions
  2015-06-12 14:02 ` [Qemu-devel] [PATCH 09/13] target-mips: microMIPS32 R6 POOL32F instructions Yongbok Kim
@ 2015-06-17 15:50   ` Leon Alrae
  0 siblings, 0 replies; 25+ messages in thread
From: Leon Alrae @ 2015-06-17 15:50 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 12/06/2015 15:02, Yongbok Kim wrote:
> @@ -14155,13 +14243,88 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
>                  break;
>              case 0x38:
>                  /* cmovs */
> -                switch ((ctx->opcode >> 6) & 0x3) {
> +                switch ((ctx->opcode >> 6) & 0x7) {
>                  case MOVN_FMT:
> +                    /* SELNEZ_FMT */
> +                    if (ctx->insn_flags & ISA_MIPS32R6) {
> +                        switch (ctx->opcode >> 9 & 0x3) {

Could you please add parentheses for consistency? (also in other patches in
this series)

Otherwise,

Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>

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

end of thread, other threads:[~2015-06-17 15:50 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-12 14:02 [Qemu-devel] [PATCH 00/13] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
2015-06-12 14:02 ` [Qemu-devel] [PATCH 01/13] target-mips: fix {D, W}RGPR in microMIPS Yongbok Kim
2015-06-15 11:16   ` Aurelien Jarno
2015-06-15 16:19   ` Leon Alrae
2015-06-12 14:02 ` [Qemu-devel] [PATCH 02/13] target-mips: add microMIPS TLBINV, TLBINVF Yongbok Kim
2015-06-15 11:50   ` Aurelien Jarno
2015-06-15 16:19   ` Leon Alrae
2015-06-12 14:02 ` [Qemu-devel] [PATCH 03/13] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP Yongbok Kim
2015-06-15 11:32   ` Leon Alrae
2015-06-12 14:02 ` [Qemu-devel] [PATCH 04/13] target-mips: rearrange gen_compute_compact_branch Yongbok Kim
2015-06-15 16:19   ` Leon Alrae
2015-06-12 14:02 ` [Qemu-devel] [PATCH 05/13] target-mips: signal RI for removed instructions in microMIPS R6 Yongbok Kim
2015-06-15 16:18   ` Leon Alrae
2015-06-12 14:02 ` [Qemu-devel] [PATCH 06/13] target-mips: add microMIPS32 R6 opcode enum Yongbok Kim
2015-06-12 14:02 ` [Qemu-devel] [PATCH 07/13] target-mips: microMIPS32 R6 branches and jumps Yongbok Kim
2015-06-12 14:02 ` [Qemu-devel] [PATCH 08/13] target-mips: microMIPS32 R6 POOL32A{XF} instructions Yongbok Kim
2015-06-16 15:24   ` Leon Alrae
2015-06-12 14:02 ` [Qemu-devel] [PATCH 09/13] target-mips: microMIPS32 R6 POOL32F instructions Yongbok Kim
2015-06-17 15:50   ` Leon Alrae
2015-06-12 14:02 ` [Qemu-devel] [PATCH 10/13] target-mips: microMIPS32 R6 POOL32{I, C} instructions Yongbok Kim
2015-06-16 13:13   ` Leon Alrae
2015-06-12 14:02 ` [Qemu-devel] [PATCH 11/13] target-mips: microMIPS32 R6 Major instructions Yongbok Kim
2015-06-16 13:07   ` Leon Alrae
2015-06-12 14:02 ` [Qemu-devel] [PATCH 12/13] target-mips: microMIPS32 R6 POOL16{A, C} instructions Yongbok Kim
2015-06-12 14:02 ` [Qemu-devel] [PATCH 13/13] target-mips: add mips32r6-generic CPU definition Yongbok Kim

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