All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support
@ 2015-06-23 15:38 Yongbok Kim
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 01/15] target-mips: fix {RD, WR}PGPR in microMIPS Yongbok Kim
                   ` (14 more replies)
  0 siblings, 15 replies; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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

---
v3:
* Avoided code duplication with pre-R6 (Leon)
* Cosmetic changes

v2:
* Updated for review comment (Leon, Aurelien)
* Added signal RI exception when FIR.PS = 0 (Leon) 
* Removed an unused argument from decode_micromips32_opc()
* Reused gen_pcrel() for pc relative instructions (Leon)

Yongbok Kim (15):
  target-mips: fix {RD,WR}PGPR in microMIPS
  target-mips: add microMIPS TLBINV, TLBINVF
  target-mips: remove an unused argument
  target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP
  target-mips: rearrange gen_compute_compact_branch
  target-mips: raise RI exceptions when FIR.PS = 0
  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      | 2099 ++++++++++++++++++++++++++++--------------
 target-mips/translate_init.c |   37 +
 2 files changed, 1450 insertions(+), 686 deletions(-)

-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v3 01/15] target-mips: fix {RD, WR}PGPR in microMIPS
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 02/15] target-mips: add microMIPS TLBINV, TLBINVF Yongbok Kim
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

rt, rs were swapped

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Leon Alrae <leon.alrae@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 1d128ee..97b74ba 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12991,12 +12991,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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 02/15] target-mips: add microMIPS TLBINV, TLBINVF
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 01/15] target-mips: fix {RD, WR}PGPR in microMIPS Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 03/15] target-mips: remove an unused argument Yongbok Kim
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

add microMIPS TLBINV, TLBINVF

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Leon Alrae <leon.alrae@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 97b74ba..963ff8b 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12233,6 +12233,8 @@ enum {
     TLBR = 0x1,
     TLBWI = 0x2,
     TLBWR = 0x3,
+    TLBINV = 0x4,
+    TLBINVF = 0x5,
     WAIT = 0x9,
     IRET = 0xd,
     DERET = 0xe,
@@ -13017,6 +13019,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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 03/15] target-mips: remove an unused argument
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 01/15] target-mips: fix {RD, WR}PGPR in microMIPS Yongbok Kim
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 02/15] target-mips: add microMIPS TLBINV, TLBINVF Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-23 23:35   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 04/15] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP Yongbok Kim
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

remove an unused argument from decode_micromips32_opc()

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 963ff8b..83dfb2f 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -13404,8 +13404,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
     }
 }
 
-static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
-                                    uint16_t insn_hw1)
+static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
 {
     int32_t offset;
     uint16_t insn;
@@ -14448,7 +14447,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
         generate_exception(ctx, EXCP_RI);
         break;
     default:
-        decode_micromips32_opc (env, ctx, op);
+        decode_micromips32_opc(env, ctx);
         return 4;
     }
 
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v3 04/15] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (2 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 03/15] target-mips: remove an unused argument Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-24 11:04   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 05/15] target-mips: rearrange gen_compute_compact_branch Yongbok Kim
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

Refactor those instructions in order to reuse them for microMIPS32
Release 6.
Rearrange gen_move_low32().

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate.c |  166 ++++++++++++++++++++++++++++-------------------
 1 files changed, 99 insertions(+), 67 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 83dfb2f..e294bb6 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1723,6 +1723,15 @@ static target_long addr_add(DisasContext *ctx, target_long base,
     return sum;
 }
 
+static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
+{
+#if defined(TARGET_MIPS64)
+    tcg_gen_ext32s_tl(ret, arg);
+#else
+    tcg_gen_trunc_i64_tl(ret, arg);
+#endif
+}
+
 static inline void check_cp0_enabled(DisasContext *ctx)
 {
     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
@@ -4845,17 +4854,94 @@ static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
     tcg_temp_free(t0);
 }
 
-#ifndef CONFIG_USER_ONLY
-/* CP0 (MMU and control) */
-static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
+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);
+    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));
+                gen_move_low32(cpu_gpr[rd], t2);
+                tcg_temp_free_i64(t2);
+            }
+            break;
 #if defined(TARGET_MIPS64)
-    tcg_gen_ext32s_tl(ret, arg);
-#else
-    tcg_gen_trunc_i64_tl(ret, arg);
+        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_mthc0_entrylo(TCGv arg, target_ulong off)
 {
     TCGv_i64 t0 = tcg_temp_new_i64();
@@ -16432,18 +16518,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);
@@ -16488,17 +16563,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:
@@ -16923,35 +16988,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)
@@ -16968,29 +17013,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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 05/15] target-mips: rearrange gen_compute_compact_branch
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (3 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 04/15] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-24 11:15   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0 Yongbok Kim
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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>
Reviewed-by: Leon Alrae <leon.alrae@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 e294bb6..dc9aae6 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -10970,6 +10970,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 */
 
@@ -16269,242 +16505,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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (4 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 05/15] target-mips: rearrange gen_compute_compact_branch Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-24 12:28   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 07/15] target-mips: signal RI for removed instructions in microMIPS R6 Yongbok Kim
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: leon.alrae, aurelien

64-bit paired-single (PS) floating point data type is optional in the
pre-Release 6.
It has to raise RI exception when PS type is not implemented. (FIR.PS = 0)
(The PS data type is removed in the Release 6.)

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate.c |   77 +++++++++++++++++++++++++++--------------------
 1 files changed, 44 insertions(+), 33 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index dc9aae6..1688bd5 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -1429,6 +1429,7 @@ typedef struct DisasContext {
     uint64_t PAMask;
     bool mvh;
     int CP0_LLAddr_shift;
+    bool ps;
 } DisasContext;
 
 enum {
@@ -1825,6 +1826,16 @@ static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
     }
 }
 
+/* This code generates a "reserved instruction" exception if the
+   CPU does not support 64-bit paired-single (PS) floating point data type */
+static inline void check_ps(DisasContext *ctx)
+{
+    if (unlikely(!ctx->ps)) {
+        generate_exception(ctx, EXCP_RI);
+    }
+    check_cp1_64bitmode(ctx);
+}
+
 #ifdef TARGET_MIPS64
 /* This code generates a "reserved instruction" exception if 64-bit
    instructions are not enabled. */
@@ -1858,7 +1869,7 @@ static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
     switch (ifmt) {                                                           \
     case FMT_PS:                                                              \
-        check_cp1_64bitmode(ctx);                                             \
+        check_ps(ctx);                                                        \
         break;                                                                \
     case FMT_D:                                                               \
         if (abs) {                                                            \
@@ -8998,7 +9009,6 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
     };
     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
     uint32_t func = ctx->opcode & 0x3f;
-
     switch (op1) {
     case OPC_ADD_S:
         {
@@ -9491,8 +9501,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "cvt.l.s";
         break;
     case OPC_CVT_PS_S:
-        check_insn_opc_removed(ctx, ISA_MIPS32R6);
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp64 = tcg_temp_new_i64();
             TCGv_i32 fp32_0 = tcg_temp_new_i32();
@@ -10109,8 +10118,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "cvt.d.l";
         break;
     case OPC_CVT_PS_PW:
-        check_insn_opc_removed(ctx, ISA_MIPS32R6);
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
@@ -10122,7 +10130,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "cvt.ps.pw";
         break;
     case OPC_ADD_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10137,7 +10145,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "add.ps";
         break;
     case OPC_SUB_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10152,7 +10160,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "sub.ps";
         break;
     case OPC_MUL_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10167,7 +10175,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "mul.ps";
         break;
     case OPC_ABS_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
@@ -10179,7 +10187,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "abs.ps";
         break;
     case OPC_MOV_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
@@ -10190,7 +10198,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "mov.ps";
         break;
     case OPC_NEG_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
@@ -10202,12 +10210,12 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "neg.ps";
         break;
     case OPC_MOVCF_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
         opn = "movcf.ps";
         break;
     case OPC_MOVZ_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGLabel *l1 = gen_new_label();
             TCGv_i64 fp0;
@@ -10223,7 +10231,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "movz.ps";
         break;
     case OPC_MOVN_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGLabel *l1 = gen_new_label();
             TCGv_i64 fp0;
@@ -10240,7 +10248,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "movn.ps";
         break;
     case OPC_ADDR_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10255,7 +10263,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "addr.ps";
         break;
     case OPC_MULR_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10270,7 +10278,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "mulr.ps";
         break;
     case OPC_RECIP2_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10285,7 +10293,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "recip2.ps";
         break;
     case OPC_RECIP1_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
@@ -10297,7 +10305,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "recip1.ps";
         break;
     case OPC_RSQRT1_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
@@ -10309,7 +10317,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "rsqrt1.ps";
         break;
     case OPC_RSQRT2_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10336,7 +10344,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "cvt.s.pu";
         break;
     case OPC_CVT_PW_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
 
@@ -10360,7 +10368,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "cvt.s.pl";
         break;
     case OPC_PLL_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i32 fp0 = tcg_temp_new_i32();
             TCGv_i32 fp1 = tcg_temp_new_i32();
@@ -10375,7 +10383,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "pll.ps";
         break;
     case OPC_PLU_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i32 fp0 = tcg_temp_new_i32();
             TCGv_i32 fp1 = tcg_temp_new_i32();
@@ -10390,7 +10398,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "plu.ps";
         break;
     case OPC_PUL_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i32 fp0 = tcg_temp_new_i32();
             TCGv_i32 fp1 = tcg_temp_new_i32();
@@ -10405,7 +10413,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
         opn = "pul.ps";
         break;
     case OPC_PUU_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i32 fp0 = tcg_temp_new_i32();
             TCGv_i32 fp1 = tcg_temp_new_i32();
@@ -10564,7 +10572,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
 
     switch (opc) {
     case OPC_ALNV_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv t0 = tcg_temp_local_new();
             TCGv_i32 fp = tcg_temp_new_i32();
@@ -10639,7 +10647,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
         opn = "madd.d";
         break;
     case OPC_MADD_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10694,7 +10702,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
         opn = "msub.d";
         break;
     case OPC_MSUB_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10749,7 +10757,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
         opn = "nmadd.d";
         break;
     case OPC_NMADD_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -10804,7 +10812,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
         opn = "nmsub.d";
         break;
     case OPC_NMSUB_PS:
-        check_cp1_64bitmode(ctx);
+        check_ps(ctx);
         {
             TCGv_i64 fp0 = tcg_temp_new_i64();
             TCGv_i64 fp1 = tcg_temp_new_i64();
@@ -14108,6 +14116,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
                         gen_movcf_d(ctx, rs, rt, cc, 0);
                         break;
                     case FMT_SDPS_PS:
+                        check_ps(ctx);
                         gen_movcf_ps(ctx, rs, rt, cc, 0);
                         break;
                     default:
@@ -14123,6 +14132,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
                         gen_movcf_d(ctx, rs, rt, cc, 1);
                         break;
                     case FMT_SDPS_PS:
+                        check_ps(ctx);
                         gen_movcf_ps(ctx, rs, rt, cc, 1);
                         break;
                     default:
@@ -14144,6 +14154,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
                     mips32_op = OPC_##prfx##_D;         \
                     goto do_fpop;                       \
                 case FMT_SDPS_PS:                       \
+                    check_ps(ctx);                      \
                     mips32_op = OPC_##prfx##_PS;        \
                     goto do_fpop;                       \
                 default:                                \
@@ -19149,8 +19160,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
                                 (rt >> 2) & 0x7, imm << 2);
             break;
         case OPC_PS_FMT:
-            check_cp1_enabled(ctx);
-            check_insn_opc_removed(ctx, ISA_MIPS32R6);
+            check_ps(ctx);
             /* fall through */
         case OPC_S_FMT:
         case OPC_D_FMT:
@@ -19459,6 +19469,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
     /* Restore delay slot state from the tb context.  */
     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
     ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
+    ctx.ps = (env->active_fpu.fcr0 >> FCR0_PS) & 1;
     restore_cpu_state(env, &ctx);
 #ifdef CONFIG_USER_ONLY
         ctx.mem_idx = MIPS_HFLAG_UM;
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v3 07/15] target-mips: signal RI for removed instructions in microMIPS R6
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (5 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0 Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-24 12:32   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 08/15] target-mips: add microMIPS32 R6 opcode enum Yongbok Kim
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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>
Reviewed-by: Leon Alrae <leon.alrae@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 1688bd5..7ab9440 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -13254,15 +13254,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:
@@ -13270,15 +13274,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);
@@ -13311,6 +13319,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;
@@ -13443,6 +13452,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);
@@ -13715,6 +13725,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):
@@ -13725,6 +13736,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:
@@ -13795,6 +13807,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);
@@ -13926,47 +13939,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;
@@ -13985,6 +14012,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;
@@ -14021,6 +14049,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);
@@ -14033,21 +14062,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);
@@ -14058,6 +14093,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:
@@ -14140,6 +14176,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;
@@ -14216,31 +14253,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;
 
@@ -14252,15 +14297,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);
@@ -14268,6 +14316,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
@@ -14275,28 +14324,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);
@@ -14325,36 +14381,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:
@@ -14428,6 +14492,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;
@@ -14444,10 +14509,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;
@@ -14626,6 +14693,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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 08/15] target-mips: add microMIPS32 R6 opcode enum
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (6 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 07/15] target-mips: signal RI for removed instructions in microMIPS R6 Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-24 13:23   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 09/15] target-mips: microMIPS32 R6 branches and jumps Yongbok Kim
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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 |  119 ++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 103 insertions(+), 16 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 7ab9440..3dcaaec 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12368,6 +12368,8 @@ enum {
     LBU16 = 0x02,
     MOVE16 = 0x03,
     ADDI32 = 0x04,
+    R6_LUI = 0x04,
+    AUI = 0x04,
     LBU32 = 0x05,
     SB32 = 0x06,
     LB32 = 0x07,
@@ -12390,56 +12392,88 @@ 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,
     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 {
@@ -12449,6 +12483,8 @@ enum {
     SRL32 = 0x1,
     SRA = 0x2,
     ROTR = 0x3,
+    SELEQZ = 0x5,
+    SELNEZ = 0x6,
 
     SLLV = 0x0,
     SRLV = 0x1,
@@ -12467,11 +12503,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
 };
@@ -12524,6 +12570,7 @@ enum {
     /* end of microMIPS32 DSP */
 
     /* bits 15..12 for 0x2c */
+    BITSWAP = 0x0,
     SEB = 0x2,
     SEH = 0x3,
     CLO = 0x4,
@@ -12550,7 +12597,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,
 
@@ -12634,32 +12684,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,
 
@@ -12667,8 +12724,10 @@ enum {
     SUXC1 = 0x6,
     ADDR_PS = 0x6,
     PREFX = 0x6,
+    MADDF_FMT = 0x6,
 
     MULR_PS = 0x7,
+    MSUBF_FMT = 0x7,
 
     MADD_S = 0x01,
     MADD_D = 0x09,
@@ -12685,10 +12744,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 */
@@ -12741,10 +12807,15 @@ 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,
@@ -12797,6 +12868,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 {
@@ -14838,12 +14929,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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 09/15] target-mips: microMIPS32 R6 branches and jumps
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (7 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 08/15] target-mips: add microMIPS32 R6 opcode enum Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-24 13:24   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 10/15] target-mips: microMIPS32 R6 POOL32A{XF} instructions Yongbok Kim
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate.c |  242 +++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 202 insertions(+), 40 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 3dcaaec..c0db5ec 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -8441,7 +8441,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";
@@ -8484,7 +8485,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);
@@ -10985,6 +10994,7 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
     int bcond_compute = 0;
     TCGv t0 = tcg_temp_new();
     TCGv t1 = tcg_temp_new();
+    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
 
     if (ctx->hflags & MIPS_HFLAG_BMASK) {
 #ifdef MIPS_DEBUG_DISAS
@@ -11006,7 +11016,7 @@ 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 + m16_lowbit);
         }
         break;
     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
@@ -11021,7 +11031,7 @@ 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 + m16_lowbit);
         }
         gen_load_gpr(t0, rs);
         gen_load_gpr(t1, rt);
@@ -11061,13 +11071,13 @@ 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 + m16_lowbit);
             /* 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 + m16_lowbit);
             /* Fallthrough */
         case OPC_BC:
             ctx->hflags |= MIPS_HFLAG_B;
@@ -13403,10 +13413,16 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
         break;
     case 0x3c:
         switch (minor) {
-        case JALR:
-        case JALR_HB:
-            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
-            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
+        case JALR:    /* JALRC */
+        case JALR_HB: /* JALRC_HB */
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                /* JALRC, JALRC_HB */
+                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
+            } else {
+                /* JALR, JALR_HB */
+                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
+                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
+            }
             break;
         case JALRS:
         case JALRS_HB:
@@ -14381,12 +14397,28 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             break;
 
             /* Traps */
-        case TLTI:
-            mips32_op = OPC_TLTI;
-            goto do_trapi;
-        case TGEI:
-            mips32_op = OPC_TGEI;
-            goto do_trapi;
+        case TLTI: /* BC1EQZC */
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                /* BC1EQZC */
+                check_cp1_enabled(ctx);
+                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
+            } else {
+                /* TLTI */
+                mips32_op = OPC_TLTI;
+                goto do_trapi;
+            }
+            break;
+        case TGEI: /* BC1NEZC */
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                /* BC1NEZC */
+                check_cp1_enabled(ctx);
+                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
+            } else {
+                /* TGEI */
+                mips32_op = OPC_TGEI;
+                goto do_trapi;
+            }
+            break;
         case TLTIU:
             check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_TLTIU;
@@ -14588,27 +14620,84 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
         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;
+    case JALS32: /* 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 {
+            /* 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;
+        }
         break;
-    case BEQ32:
-        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
+    case BEQ32: /* BC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            /* BC */
+            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
+                                       sextract32(ctx->opcode << 1, 0, 27));
+        } else {
+            /* BEQ32 */
+            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);
+    case BNE32: /* BALC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            /* BALC */
+            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
+                                       sextract32(ctx->opcode << 1, 0, 27));
+        } else {
+            /* BNE32 */
+            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);
+    case J32: /* BGTZC, BLTZC, BLTC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            if (rs == 0 && rt != 0) {
+                /* BGTZC */
+                mips32_op = OPC_BGTZC;
+            } else if (rs != 0 && rt != 0 && rs == rt) {
+                /* BLTZC */
+                mips32_op = OPC_BLTZC;
+            } else {
+                /* BLTC */
+                mips32_op = OPC_BLTC;
+            }
+            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
+        } else {
+            /* J32 */
+            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;
+    case JAL32: /* BLEZC, BGEZC, BGEC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            if (rs == 0 && rt != 0) {
+                /* BLEZC */
+                mips32_op = OPC_BLEZC;
+            } else if (rs != 0 && rt != 0 && rs == rt) {
+                /* BGEZC */
+                mips32_op = OPC_BGEZC;
+            } else {
+                /* BGEC */
+                mips32_op = OPC_BGEC;
+            }
+            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
+        } else {
+            /* JAL32 */
+            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:
@@ -14633,6 +14722,70 @@ 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) {
+            /* BNEZC */
+            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
+                                       sextract32(ctx->opcode << 1, 0, 22));
+        } else {
+            /* JIALC */
+            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
+        }
+        break;
+    case R6_BEQZC: /* JIC */
+        check_insn(ctx, ISA_MIPS32R6);
+        if (rt != 0) {
+            /* BEQZC */
+            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
+                                       sextract32(ctx->opcode << 1, 0, 22));
+        } else {
+            /* JIC */
+            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) {
+            /* BLEZALC */
+            mips32_op = OPC_BLEZALC;
+        } else if (rs != 0 && rt != 0 && rs == rt) {
+            /* BGEZALC */
+            mips32_op = OPC_BGEZALC;
+        } else {
+            /* BGEUC */
+            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) {
+            /* BGTZALC */
+            mips32_op = OPC_BGTZALC;
+        } else if (rs != 0 && rt != 0 && rs == rt) {
+            /* BLTZALC */
+            mips32_op = OPC_BLTZALC;
+        } else {
+            /* BLTUC */
+            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;
@@ -14910,15 +15063,18 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
             break;
         }
         break;
-    case B16:
+    case B16: /* BC16 */
         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
-                           SIMM(ctx->opcode, 0, 10) << 1, 4);
+                           sextract32(ctx->opcode, 0, 10) << 1,
+                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
         break;
-    case BNEZ16:
-    case BEQZ16:
+    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, sextract32(ctx->opcode, 0, 7) << 1,
+                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
+
         break;
     case LI16:
         {
@@ -19287,7 +19443,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);
@@ -19300,7 +19456,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);
@@ -19694,6 +19850,12 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
                    forbidden slot */
                 is_slot = 1;
             }
+            if ((ctx.hflags & MIPS_HFLAG_M16) &&
+                (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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 10/15] target-mips: microMIPS32 R6 POOL32A{XF} instructions
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (8 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 09/15] target-mips: microMIPS32 R6 branches and jumps Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-24 13:24   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 11/15] target-mips: microMIPS32 R6 POOL32F instructions Yongbok Kim
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate.c |   80 ++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index c0db5ec..6a29796 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -13333,6 +13333,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;
@@ -13530,8 +13534,8 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
             break;
         case SDBBP:
             check_insn(ctx, ISA_MIPS32);
-            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
-                generate_exception(ctx, EXCP_DBp);
+            if (ctx->hflags & MIPS_HFLAG_SBRI) {
+                generate_exception(ctx, EXCP_RI);
             } else {
                 generate_exception(ctx, EXCP_DBp);
             }
@@ -13893,6 +13897,14 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             do_shifti:
                 gen_shift_imm(ctx, mips32_op, rt, rs, 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;
             }
@@ -13966,16 +13978,52 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             minor = (ctx->opcode >> 6) & 0xf;
             switch (minor) {
                 /* Conditional moves */
-            case MOVN:
-                mips32_op = OPC_MOVN;
-                goto do_cmov;
-            case MOVZ:
-                mips32_op = OPC_MOVZ;
-            do_cmov:
-                gen_cond_move(ctx, mips32_op, rd, rs, rt);
+            case MOVN: /* MUL */
+                if (ctx->insn_flags & ISA_MIPS32R6) {
+                    /* MUL */
+                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
+                } else {
+                    /* MOVN */
+                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
+                }
+                break;
+            case MOVZ: /* MUH */
+                if (ctx->insn_flags & ISA_MIPS32R6) {
+                    /* MUH */
+                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
+                } else {
+                    /* MOVZ */
+                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
+                }
                 break;
-            case LWXS:
-                gen_ldxs(ctx, rs, rt, rd);
+            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: /* DIV */
+                if (ctx->insn_flags & ISA_MIPS32R6) {
+                    /* DIV */
+                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
+                } else {
+                    /* LWXS */
+                    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;
@@ -13984,6 +14032,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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 11/15] target-mips: microMIPS32 R6 POOL32F instructions
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (9 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 10/15] target-mips: microMIPS32 R6 POOL32A{XF} instructions Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 12/15] target-mips: microMIPS32 R6 POOL32{I, C} instructions Yongbok Kim
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate.c |  231 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 199 insertions(+), 32 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 6a29796..5f6ae43 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -14195,6 +14195,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;
@@ -14223,6 +14231,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) {
@@ -14256,6 +14277,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);
@@ -14304,40 +14338,70 @@ 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:
-                        check_ps(ctx);
-                        gen_movcf_ps(ctx, rs, rt, cc, 0);
-                        break;
-                    default:
-                        goto pool32f_invalid;
+                case MOVF_FMT: /* RINT_FMT */
+                    if (ctx->insn_flags & ISA_MIPS32R6) {
+                        /* RINT_FMT */
+                        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 {
+                        /* 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:
+                            check_ps(ctx);
+                            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:
-                        check_ps(ctx);
-                        gen_movcf_ps(ctx, rs, rt, cc, 1);
-                        break;
-                    default:
-                        goto pool32f_invalid;
+                case MOVT_FMT: /* CLASS_FMT */
+                    if (ctx->insn_flags & ISA_MIPS32R6) {
+                        /* CLASS_FMT */
+                        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 {
+                        /* 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:
+                            check_ps(ctx);
+                            gen_movcf_ps(ctx, rs, rt, cc, 1);
+                            break;
+                        default:
+                            goto pool32f_invalid;
+                        }
                     }
                     break;
                 case PREFX:
@@ -14362,6 +14426,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) {
@@ -14390,13 +14480,90 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
                 break;
             case 0x38:
                 /* cmovs */
-                switch ((ctx->opcode >> 6) & 0x3) {
-                case MOVN_FMT:
+                switch ((ctx->opcode >> 6) & 0x7) {
+                case MOVN_FMT: /* SELNEZ_FMT */
+                    if (ctx->insn_flags & ISA_MIPS32R6) {
+                        /* SELNEZ_FMT */
+                        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 {
+                        /* MOVN_FMT */
+                        FINSN_3ARG_SDPS(MOVN);
+                    }
+                    break;
+                case MOVN_FMT_04:
+                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
                     FINSN_3ARG_SDPS(MOVN);
                     break;
-                case MOVZ_FMT:
+                case MOVZ_FMT: /* SELEQZ_FMT */
+                    if (ctx->insn_flags & ISA_MIPS32R6) {
+                        /* SELEQZ_FMT */
+                        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 {
+                        /* MOVZ_FMT */
+                        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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 12/15] target-mips: microMIPS32 R6 POOL32{I, C} instructions
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (10 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 11/15] target-mips: microMIPS32 R6 POOL32F instructions Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-23 16:16   ` Leon Alrae
  2015-06-24 13:29   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 13/15] target-mips: microMIPS32 R6 Major instructions Yongbok Kim
                   ` (2 subsequent siblings)
  14 siblings, 2 replies; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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 |   27 +++++++++++++++++++++------
 1 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 5f6ae43..596ba1b 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -14652,9 +14652,18 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_TGEIU;
             goto do_trapi;
-        case TNEI:
-            mips32_op = OPC_TNEI;
-            goto do_trapi;
+        case TNEI: /* SYNCI */
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                /* SYNCI */
+                /* Break the TB to be able to sync copied instructions
+                   immediately */
+                ctx->bstate = BS_STOP;
+            } else {
+                /* TNEI */
+                mips32_op = OPC_TNEI;
+                goto do_trapi;
+            }
+            break;
         case TEQI:
             check_insn_opc_removed(ctx, ISA_MIPS32R6);
             mips32_op = OPC_TEQI;
@@ -14727,6 +14736,8 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
         break;
     case POOL32C:
         minor = (ctx->opcode >> 12) & 0xf;
+        offset = sextract32(ctx->opcode, 0,
+                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
         switch (minor) {
         case LWL:
             check_insn_opc_removed(ctx, ISA_MIPS32R6);
@@ -14784,23 +14795,27 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             mips32_op = OPC_LL;
             goto do_ld_lr;
         do_ld_lr:
-            gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
+            gen_ld(ctx, mips32_op, rt, rs, offset);
             break;
         do_st_lr:
             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));
+            gen_st_cond(ctx, OPC_SC, rt, rs, offset);
             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));
+            gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
             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] 36+ messages in thread

* [Qemu-devel] [PATCH v3 13/15] target-mips: microMIPS32 R6 Major instructions
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (11 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 12/15] target-mips: microMIPS32 R6 POOL32{I, C} instructions Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-24 13:33   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 14/15] target-mips: microMIPS32 R6 POOL16{A, C} instructions Yongbok Kim
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 15/15] target-mips: add mips32r6-generic CPU definition Yongbok Kim
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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 |   62 ++++++++++++++++++++++++++++++++++-------------
 1 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 596ba1b..4bce6e8 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -3208,45 +3208,46 @@ static inline void gen_r6_ld(target_long addr, int reg, int memidx,
     tcg_temp_free(t0);
 }
 
-static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
+static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
+                             int rs)
 {
     target_long offset;
     target_long addr;
 
-    switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
+    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
     case OPC_ADDIUPC:
         if (rs != 0) {
             offset = sextract32(ctx->opcode << 2, 0, 21);
-            addr = addr_add(ctx, ctx->pc, offset);
+            addr = addr_add(ctx, pc, offset);
             tcg_gen_movi_tl(cpu_gpr[rs], addr);
         }
         break;
     case R6_OPC_LWPC:
         offset = sextract32(ctx->opcode << 2, 0, 21);
-        addr = addr_add(ctx, ctx->pc, offset);
+        addr = addr_add(ctx, pc, offset);
         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
         break;
 #if defined(TARGET_MIPS64)
     case OPC_LWUPC:
         check_mips_64(ctx);
         offset = sextract32(ctx->opcode << 2, 0, 21);
-        addr = addr_add(ctx, ctx->pc, offset);
+        addr = addr_add(ctx, pc, offset);
         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
         break;
 #endif
     default:
-        switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
+        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
         case OPC_AUIPC:
             if (rs != 0) {
-                offset = imm << 16;
-                addr = addr_add(ctx, ctx->pc, offset);
+                offset = sextract32(ctx->opcode, 0, 16) << 16;
+                addr = addr_add(ctx, pc, offset);
                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
             }
             break;
         case OPC_ALUIPC:
             if (rs != 0) {
-                offset = imm << 16;
-                addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
+                offset = sextract32(ctx->opcode, 0, 16) << 16;
+                addr = ~0xFFFF & addr_add(ctx, pc, offset);
                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
             }
             break;
@@ -3257,7 +3258,7 @@ static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
         case R6_OPC_LDPC + (3 << 16):
             check_mips_64(ctx);
             offset = sextract32(ctx->opcode << 3, 0, 21);
-            addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
+            addr = addr_add(ctx, (pc & ~0x7), offset);
             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
             break;
 #endif
@@ -14823,9 +14824,16 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             break;
         }
         break;
-    case ADDI32:
-        mips32_op = OPC_ADDI;
-        goto do_addi;
+    case ADDI32: /* AUI, LUI */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            /* AUI, LUI */
+            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
+        } else {
+            /* ADDI32 */
+            mips32_op = OPC_ADDI;
+            goto do_addi;
+        }
+        break;
     case ADDIU32:
         mips32_op = OPC_ADDIU;
     do_addi:
@@ -14954,8 +14962,28 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
     do_cop1:
         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
         break;
-    case ADDIUPC:
-        {
+    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
+        if (ctx->insn_flags & ISA_MIPS32R6) {
+            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
+            switch ((ctx->opcode >> 16) & 0x1f) {
+            case ADDIUPC_00 ... ADDIUPC_07:
+                gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
+                break;
+            case AUIPC:
+                gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
+                break;
+            case ALUIPC:
+                gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
+                break;
+            case LWPC_08 ... LWPC_0F:
+                gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
+                break;
+            default:
+                generate_exception(ctx, EXCP_RI);
+                break;
+            }
+        } else {
+            /* ADDIUPC */
             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
             int offset = SIMM(ctx->opcode, 0, 23) << 2;
 
@@ -19972,7 +20000,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
         break;
     case OPC_PCREL:
         check_insn(ctx, ISA_MIPS32R6);
-        gen_pcrel(ctx, rs, imm);
+        gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
         break;
     default:            /* Invalid */
         MIPS_INVAL("major opcode");
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v3 14/15] target-mips: microMIPS32 R6 POOL16{A, C} instructions
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (12 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 13/15] target-mips: microMIPS32 R6 Major instructions Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-23 16:16   ` Leon Alrae
  2015-06-24 13:43   ` Aurelien Jarno
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 15/15] target-mips: add mips32r6-generic CPU definition Yongbok Kim
  14 siblings, 2 replies; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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 |  122 +++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 107 insertions(+), 15 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 4bce6e8..82764e7 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -13163,6 +13163,102 @@ static void gen_pool16c_insn(DisasContext *ctx)
     }
 }
 
+static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
+                             int enc_rs)
+{
+    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);
+}
+
+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:
+        {
+            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
+            int offset = extract32(ctx->opcode, 4, 4);
+            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
+        }
+        break;
+    case R6_JRC16: /* JRCADDIUSP */
+        if ((ctx->opcode >> 4) & 1) {
+            /* JRCADDIUSP */
+            int imm = extract32(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);
+        } else {
+            /* JRC16 */
+            int rs = extract32(ctx->opcode, 5, 5);
+            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
+        }
+        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);
+            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
+        }
+        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:
+        {
+            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
+            int offset = extract32(ctx->opcode, 4, 4);
+            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
+        }
+        break;
+    case JALRC16: /* BREAK16, SDBBP16 */
+        switch (ctx->opcode & 0x3f) {
+        case JALRC16:
+        case JALRC16 + 0x20:
+            /* JALRC16 */
+            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
+                               31, 0, 0);
+            break;
+        case R6_BREAK16:
+            /* BREAK16 */
+            generate_exception(ctx, EXCP_BREAK);
+            break;
+        case R6_SDBBP16:
+            /* SDBBP16 */
+            if (ctx->hflags & MIPS_HFLAG_SBRI) {
+                generate_exception(ctx, EXCP_RI);
+            } else {
+                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();
@@ -15168,8 +15264,11 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
                 opc = OPC_SUBU;
                 break;
             }
-
-            gen_arith(ctx, opc, rd, rs1, rs2);
+            if (ctx->insn_flags & ISA_MIPS32R6) {
+                gen_arith(ctx, opc, rs1, rd, rs2);
+            } else {
+                gen_arith(ctx, opc, rd, rs1, rs2);
+            }
         }
         break;
     case POOL16B:
@@ -15193,7 +15292,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:
         {
@@ -15213,18 +15316,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
             int enc_dest = uMIPS_RD(ctx->opcode);
             int enc_rt = uMIPS_RS2(ctx->opcode);
             int enc_rs = uMIPS_RS1(ctx->opcode);
-            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);
+            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
         }
         break;
     case LBU16:
-- 
1.7.5.4

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

* [Qemu-devel] [PATCH v3 15/15] target-mips: add mips32r6-generic CPU definition
  2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
                   ` (13 preceding siblings ...)
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 14/15] target-mips: microMIPS32 R6 POOL16{A, C} instructions Yongbok Kim
@ 2015-06-23 15:38 ` Yongbok Kim
  2015-06-24 13:44   ` Aurelien Jarno
  14 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-23 15:38 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 30605da..ddfaff8 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -424,6 +424,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] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v3 12/15] target-mips: microMIPS32 R6 POOL32{I, C} instructions
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 12/15] target-mips: microMIPS32 R6 POOL32{I, C} instructions Yongbok Kim
@ 2015-06-23 16:16   ` Leon Alrae
  2015-06-24 13:29   ` Aurelien Jarno
  1 sibling, 0 replies; 36+ messages in thread
From: Leon Alrae @ 2015-06-23 16:16 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 23/06/2015 16:38, 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 |   27 +++++++++++++++++++++------
>  1 files changed, 21 insertions(+), 6 deletions(-)

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

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

* Re: [Qemu-devel] [PATCH v3 14/15] target-mips: microMIPS32 R6 POOL16{A, C} instructions
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 14/15] target-mips: microMIPS32 R6 POOL16{A, C} instructions Yongbok Kim
@ 2015-06-23 16:16   ` Leon Alrae
  2015-06-24 13:43   ` Aurelien Jarno
  1 sibling, 0 replies; 36+ messages in thread
From: Leon Alrae @ 2015-06-23 16:16 UTC (permalink / raw)
  To: Yongbok Kim, qemu-devel; +Cc: aurelien

On 23/06/2015 16:38, Yongbok Kim wrote:
> microMIPS32 Release 6 POOL16A/ POOL16C instructions
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |  122 +++++++++++++++++++++++++++++++++++++++++------
>  1 files changed, 107 insertions(+), 15 deletions(-)

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

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

* Re: [Qemu-devel] [PATCH v3 03/15] target-mips: remove an unused argument
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 03/15] target-mips: remove an unused argument Yongbok Kim
@ 2015-06-23 23:35   ` Aurelien Jarno
  0 siblings, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-23 23:35 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, Yongbok Kim wrote:
> remove an unused argument from decode_micromips32_opc()
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
>  target-mips/translate.c |    5 ++---
>  1 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 963ff8b..83dfb2f 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -13404,8 +13404,7 @@ static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
>      }
>  }
>  
> -static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
> -                                    uint16_t insn_hw1)
> +static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
>  {
>      int32_t offset;
>      uint16_t insn;
> @@ -14448,7 +14447,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
>          generate_exception(ctx, EXCP_RI);
>          break;
>      default:
> -        decode_micromips32_opc (env, ctx, op);
> +        decode_micromips32_opc(env, ctx);
>          return 4;
>      }

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

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

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

* Re: [Qemu-devel] [PATCH v3 04/15] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 04/15] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP Yongbok Kim
@ 2015-06-24 11:04   ` Aurelien Jarno
  2015-06-24 12:31     ` Leon Alrae
  0 siblings, 1 reply; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 11:04 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, Yongbok Kim wrote:
> Refactor those instructions in order to reuse them for microMIPS32
> Release 6.
> Rearrange gen_move_low32().
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
>  target-mips/translate.c |  166 ++++++++++++++++++++++++++++-------------------
>  1 files changed, 99 insertions(+), 67 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 83dfb2f..e294bb6 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -1723,6 +1723,15 @@ static target_long addr_add(DisasContext *ctx, target_long base,
>      return sum;
>  }
>  
> +static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
> +{
> +#if defined(TARGET_MIPS64)
> +    tcg_gen_ext32s_tl(ret, arg);
> +#else
> +    tcg_gen_trunc_i64_tl(ret, arg);
> +#endif
> +}
> +
>  static inline void check_cp0_enabled(DisasContext *ctx)
>  {
>      if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
> @@ -4845,17 +4854,94 @@ static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
>      tcg_temp_free(t0);
>  }
>  
> -#ifndef CONFIG_USER_ONLY
> -/* CP0 (MMU and control) */
> -static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
> +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);
> +    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));
> +                gen_move_low32(cpu_gpr[rd], t2);
> +                tcg_temp_free_i64(t2);
> +            }
> +            break;

Not a problem in your patch (you basically just moved code), but I
think this implementation is incorrect. It should be the same code as
for DALIGN, but with the input operands zero extended to 32 bits, and
the result sign extended to 32 bits. Something like that should work:

tcg_gen_ext32u_tl(t0, t0);
tcg_gen_shli_tl(t0, t0, 8 * bp);
tcg_gen_ext32u_tl(t1, t1);
tcg_gen_shri_tl(t1, t1, 8 * (4 - bp));
tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);

In practice we can drop the zero extension on t0 (rt) as the bits there
will be dropped by the sign extension on the result. Note that on
32-bit, the zero and sign extension will be dropped, so there is no need
for #ifdef TARGET_MIPS64.

>  #if defined(TARGET_MIPS64)
> -    tcg_gen_ext32s_tl(ret, arg);
> -#else
> -    tcg_gen_trunc_i64_tl(ret, arg);
> +        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_mthc0_entrylo(TCGv arg, target_ulong off)
>  {
>      TCGv_i64 t0 = tcg_temp_new_i64();
> @@ -16432,18 +16518,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);
> @@ -16488,17 +16563,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:
> @@ -16923,35 +16988,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)
> @@ -16968,29 +17013,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

The remaining of the patch looks correct to me.

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

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

* Re: [Qemu-devel] [PATCH v3 05/15] target-mips: rearrange gen_compute_compact_branch
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 05/15] target-mips: rearrange gen_compute_compact_branch Yongbok Kim
@ 2015-06-24 11:15   ` Aurelien Jarno
  0 siblings, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 11:15 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

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

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

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

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

* Re: [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0 Yongbok Kim
@ 2015-06-24 12:28   ` Aurelien Jarno
  2015-06-24 14:24     ` Yongbok Kim
  0 siblings, 1 reply; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 12:28 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, Yongbok Kim wrote:
> 64-bit paired-single (PS) floating point data type is optional in the
> pre-Release 6.
> It has to raise RI exception when PS type is not implemented. (FIR.PS = 0)
> (The PS data type is removed in the Release 6.)
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
>  target-mips/translate.c |   77 +++++++++++++++++++++++++++--------------------
>  1 files changed, 44 insertions(+), 33 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index dc9aae6..1688bd5 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -1429,6 +1429,7 @@ typedef struct DisasContext {
>      uint64_t PAMask;
>      bool mvh;
>      int CP0_LLAddr_shift;
> +    bool ps;
>  } DisasContext;
>  
>  enum {
> @@ -1825,6 +1826,16 @@ static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
>      }
>  }
>  
> +/* This code generates a "reserved instruction" exception if the
> +   CPU does not support 64-bit paired-single (PS) floating point data type */
> +static inline void check_ps(DisasContext *ctx)
> +{
> +    if (unlikely(!ctx->ps)) {
> +        generate_exception(ctx, EXCP_RI);
> +    }
> +    check_cp1_64bitmode(ctx);
> +}
> +
>  #ifdef TARGET_MIPS64
>  /* This code generates a "reserved instruction" exception if 64-bit
>     instructions are not enabled. */
> @@ -1858,7 +1869,7 @@ static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
>      TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
>      switch (ifmt) {                                                           \
>      case FMT_PS:                                                              \
> -        check_cp1_64bitmode(ctx);                                             \
> +        check_ps(ctx);                                                        \
>          break;                                                                \
>      case FMT_D:                                                               \
>          if (abs) {                                                            \
> @@ -8998,7 +9009,6 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>      };
>      enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
>      uint32_t func = ctx->opcode & 0x3f;
> -
>      switch (op1) {
>      case OPC_ADD_S:
>          {
> @@ -9491,8 +9501,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "cvt.l.s";
>          break;
>      case OPC_CVT_PS_S:
> -        check_insn_opc_removed(ctx, ISA_MIPS32R6);
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp64 = tcg_temp_new_i64();
>              TCGv_i32 fp32_0 = tcg_temp_new_i32();
> @@ -10109,8 +10118,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "cvt.d.l";
>          break;
>      case OPC_CVT_PS_PW:
> -        check_insn_opc_removed(ctx, ISA_MIPS32R6);
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10122,7 +10130,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "cvt.ps.pw";
>          break;
>      case OPC_ADD_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10137,7 +10145,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "add.ps";
>          break;
>      case OPC_SUB_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10152,7 +10160,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "sub.ps";
>          break;
>      case OPC_MUL_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10167,7 +10175,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "mul.ps";
>          break;
>      case OPC_ABS_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10179,7 +10187,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "abs.ps";
>          break;
>      case OPC_MOV_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10190,7 +10198,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "mov.ps";
>          break;
>      case OPC_NEG_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10202,12 +10210,12 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "neg.ps";
>          break;
>      case OPC_MOVCF_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
>          opn = "movcf.ps";
>          break;
>      case OPC_MOVZ_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGLabel *l1 = gen_new_label();
>              TCGv_i64 fp0;
> @@ -10223,7 +10231,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "movz.ps";
>          break;
>      case OPC_MOVN_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGLabel *l1 = gen_new_label();
>              TCGv_i64 fp0;
> @@ -10240,7 +10248,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "movn.ps";
>          break;
>      case OPC_ADDR_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10255,7 +10263,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "addr.ps";
>          break;
>      case OPC_MULR_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10270,7 +10278,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "mulr.ps";
>          break;
>      case OPC_RECIP2_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10285,7 +10293,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "recip2.ps";
>          break;
>      case OPC_RECIP1_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10297,7 +10305,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "recip1.ps";
>          break;
>      case OPC_RSQRT1_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10309,7 +10317,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "rsqrt1.ps";
>          break;
>      case OPC_RSQRT2_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10336,7 +10344,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "cvt.s.pu";
>          break;
>      case OPC_CVT_PW_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10360,7 +10368,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "cvt.s.pl";
>          break;
>      case OPC_PLL_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i32 fp0 = tcg_temp_new_i32();
>              TCGv_i32 fp1 = tcg_temp_new_i32();
> @@ -10375,7 +10383,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "pll.ps";
>          break;
>      case OPC_PLU_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i32 fp0 = tcg_temp_new_i32();
>              TCGv_i32 fp1 = tcg_temp_new_i32();
> @@ -10390,7 +10398,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "plu.ps";
>          break;
>      case OPC_PUL_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i32 fp0 = tcg_temp_new_i32();
>              TCGv_i32 fp1 = tcg_temp_new_i32();
> @@ -10405,7 +10413,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
>          opn = "pul.ps";
>          break;
>      case OPC_PUU_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i32 fp0 = tcg_temp_new_i32();
>              TCGv_i32 fp1 = tcg_temp_new_i32();
> @@ -10564,7 +10572,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
>  
>      switch (opc) {
>      case OPC_ALNV_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv t0 = tcg_temp_local_new();
>              TCGv_i32 fp = tcg_temp_new_i32();
> @@ -10639,7 +10647,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
>          opn = "madd.d";
>          break;
>      case OPC_MADD_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10694,7 +10702,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
>          opn = "msub.d";
>          break;
>      case OPC_MSUB_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10749,7 +10757,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
>          opn = "nmadd.d";
>          break;
>      case OPC_NMADD_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10804,7 +10812,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
>          opn = "nmsub.d";
>          break;
>      case OPC_NMSUB_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -14108,6 +14116,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
>                          gen_movcf_d(ctx, rs, rt, cc, 0);
>                          break;
>                      case FMT_SDPS_PS:
> +                        check_ps(ctx);
>                          gen_movcf_ps(ctx, rs, rt, cc, 0);
>                          break;
>                      default:
> @@ -14123,6 +14132,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
>                          gen_movcf_d(ctx, rs, rt, cc, 1);
>                          break;
>                      case FMT_SDPS_PS:
> +                        check_ps(ctx);
>                          gen_movcf_ps(ctx, rs, rt, cc, 1);
>                          break;
>                      default:
> @@ -14144,6 +14154,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
>                      mips32_op = OPC_##prfx##_D;         \
>                      goto do_fpop;                       \
>                  case FMT_SDPS_PS:                       \
> +                    check_ps(ctx);                      \
>                      mips32_op = OPC_##prfx##_PS;        \
>                      goto do_fpop;                       \
>                  default:                                \
> @@ -19149,8 +19160,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
>                                  (rt >> 2) & 0x7, imm << 2);
>              break;
>          case OPC_PS_FMT:
> -            check_cp1_enabled(ctx);
> -            check_insn_opc_removed(ctx, ISA_MIPS32R6);
> +            check_ps(ctx);
>              /* fall through */
>          case OPC_S_FMT:
>          case OPC_D_FMT:
> @@ -19459,6 +19469,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
>      /* Restore delay slot state from the tb context.  */
>      ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
>      ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
> +    ctx.ps = (env->active_fpu.fcr0 >> FCR0_PS) & 1;
>      restore_cpu_state(env, &ctx);
>  #ifdef CONFIG_USER_ONLY
>          ctx.mem_idx = MIPS_HFLAG_UM;

This change means that the PS instructions are now enabled only when
FCR0_PS is set, instead of being enabled when the FPU in 64-bit mode.
Have you checked if we need to update a few CPU definitions for it to
work? I am thinking for example about all the CPU with FCR0_F64, but
without FCR0_PS.

Otherwise the patch looks fine to me.

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

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

* Re: [Qemu-devel] [PATCH v3 04/15] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP
  2015-06-24 11:04   ` Aurelien Jarno
@ 2015-06-24 12:31     ` Leon Alrae
  2015-06-24 13:16       ` Aurelien Jarno
  0 siblings, 1 reply; 36+ messages in thread
From: Leon Alrae @ 2015-06-24 12:31 UTC (permalink / raw)
  To: Aurelien Jarno, Yongbok Kim; +Cc: qemu-devel

On 24/06/2015 12:04, Aurelien Jarno wrote:
>> +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));
>> +                gen_move_low32(cpu_gpr[rd], t2);
>> +                tcg_temp_free_i64(t2);
>> +            }
>> +            break;
> 
> Not a problem in your patch (you basically just moved code), but I
> think this implementation is incorrect. It should be the same code as
> for DALIGN, but with the input operands zero extended to 32 bits, and
> the result sign extended to 32 bits. Something like that should work:
> 
> tcg_gen_ext32u_tl(t0, t0);
> tcg_gen_shli_tl(t0, t0, 8 * bp);
> tcg_gen_ext32u_tl(t1, t1);
> tcg_gen_shri_tl(t1, t1, 8 * (4 - bp));
> tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
> tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
> 
> In practice we can drop the zero extension on t0 (rt) as the bits there
> will be dropped by the sign extension on the result. Note that on
> 32-bit, the zero and sign extension will be dropped, so there is no need
> for #ifdef TARGET_MIPS64.

I believe existing implementation is correct and does the same thing, but it
operates on the whole 64-bit temp containing merged rs and rt rather than
shifting 32-bit registers separately. We discussed this last year, and the
potential benefit is that it could be slightly faster on 64-bit host.

Thanks,
Leon

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

* Re: [Qemu-devel] [PATCH v3 07/15] target-mips: signal RI for removed instructions in microMIPS R6
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 07/15] target-mips: signal RI for removed instructions in microMIPS R6 Yongbok Kim
@ 2015-06-24 12:32   ` Aurelien Jarno
  0 siblings, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 12:32 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, 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>
> Reviewed-by: Leon Alrae <leon.alrae@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 1688bd5..7ab9440 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -13254,15 +13254,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:
> @@ -13270,15 +13274,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);
> @@ -13311,6 +13319,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;
> @@ -13443,6 +13452,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);
> @@ -13715,6 +13725,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):
> @@ -13725,6 +13736,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:
> @@ -13795,6 +13807,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);
> @@ -13926,47 +13939,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;
> @@ -13985,6 +14012,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;
> @@ -14021,6 +14049,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);
> @@ -14033,21 +14062,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);
> @@ -14058,6 +14093,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:
> @@ -14140,6 +14176,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;
> @@ -14216,31 +14253,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;
>  
> @@ -14252,15 +14297,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);
> @@ -14268,6 +14316,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
> @@ -14275,28 +14324,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);
> @@ -14325,36 +14381,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:
> @@ -14428,6 +14492,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;
> @@ -14444,10 +14509,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;
> @@ -14626,6 +14693,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 {

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

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

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

* Re: [Qemu-devel] [PATCH v3 04/15] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP
  2015-06-24 12:31     ` Leon Alrae
@ 2015-06-24 13:16       ` Aurelien Jarno
  0 siblings, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 13:16 UTC (permalink / raw)
  To: Leon Alrae; +Cc: Yongbok Kim, qemu-devel

On 2015-06-24 13:31, Leon Alrae wrote:
> On 24/06/2015 12:04, Aurelien Jarno wrote:
> >> +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));
> >> +                gen_move_low32(cpu_gpr[rd], t2);
> >> +                tcg_temp_free_i64(t2);
> >> +            }
> >> +            break;
> > 
> > Not a problem in your patch (you basically just moved code), but I
> > think this implementation is incorrect. It should be the same code as
> > for DALIGN, but with the input operands zero extended to 32 bits, and
> > the result sign extended to 32 bits. Something like that should work:
> > 
> > tcg_gen_ext32u_tl(t0, t0);
> > tcg_gen_shli_tl(t0, t0, 8 * bp);
> > tcg_gen_ext32u_tl(t1, t1);
> > tcg_gen_shri_tl(t1, t1, 8 * (4 - bp));
> > tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
> > tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
> > 
> > In practice we can drop the zero extension on t0 (rt) as the bits there
> > will be dropped by the sign extension on the result. Note that on
> > 32-bit, the zero and sign extension will be dropped, so there is no need
> > for #ifdef TARGET_MIPS64.
> 
> I believe existing implementation is correct and does the same thing, but it
> operates on the whole 64-bit temp containing merged rs and rt rather than
> shifting 32-bit registers separately. We discussed this last year, and the
> potential benefit is that it could be slightly faster on 64-bit host.

If it is has already been discussed, then:

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

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

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

* Re: [Qemu-devel] [PATCH v3 08/15] target-mips: add microMIPS32 R6 opcode enum
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 08/15] target-mips: add microMIPS32 R6 opcode enum Yongbok Kim
@ 2015-06-24 13:23   ` Aurelien Jarno
  0 siblings, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 13:23 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, Yongbok Kim wrote:
> 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 |  119 ++++++++++++++++++++++++++++++++++++++++------
>  1 files changed, 103 insertions(+), 16 deletions(-)

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

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

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

* Re: [Qemu-devel] [PATCH v3 09/15] target-mips: microMIPS32 R6 branches and jumps
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 09/15] target-mips: microMIPS32 R6 branches and jumps Yongbok Kim
@ 2015-06-24 13:24   ` Aurelien Jarno
  0 siblings, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 13:24 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, Yongbok Kim wrote:
> add new microMIPS32 Release 6 branch and jump instructions.
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
>  target-mips/translate.c |  242 +++++++++++++++++++++++++++++++++++++++--------
>  1 files changed, 202 insertions(+), 40 deletions(-)

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

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

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

* Re: [Qemu-devel] [PATCH v3 10/15] target-mips: microMIPS32 R6 POOL32A{XF} instructions
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 10/15] target-mips: microMIPS32 R6 POOL32A{XF} instructions Yongbok Kim
@ 2015-06-24 13:24   ` Aurelien Jarno
  0 siblings, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 13:24 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, Yongbok Kim wrote:
> add new microMIPS32 Release 6 pool32a/pool32axf instructions.
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
>  target-mips/translate.c |   80 ++++++++++++++++++++++++++++++++++++++++------
>  1 files changed, 69 insertions(+), 11 deletions(-)

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

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

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

* Re: [Qemu-devel] [PATCH v3 12/15] target-mips: microMIPS32 R6 POOL32{I, C} instructions
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 12/15] target-mips: microMIPS32 R6 POOL32{I, C} instructions Yongbok Kim
  2015-06-23 16:16   ` Leon Alrae
@ 2015-06-24 13:29   ` Aurelien Jarno
  1 sibling, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 13:29 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, 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 |   27 +++++++++++++++++++++------
>  1 files changed, 21 insertions(+), 6 deletions(-)

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

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

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

* Re: [Qemu-devel] [PATCH v3 13/15] target-mips: microMIPS32 R6 Major instructions
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 13/15] target-mips: microMIPS32 R6 Major instructions Yongbok Kim
@ 2015-06-24 13:33   ` Aurelien Jarno
  0 siblings, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 13:33 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, Yongbok Kim wrote:
> add new microMIPS32 Release 6 Major opcode instructions
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |   62 ++++++++++++++++++++++++++++++++++-------------
>  1 files changed, 45 insertions(+), 17 deletions(-)

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

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

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

* Re: [Qemu-devel] [PATCH v3 14/15] target-mips: microMIPS32 R6 POOL16{A, C} instructions
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 14/15] target-mips: microMIPS32 R6 POOL16{A, C} instructions Yongbok Kim
  2015-06-23 16:16   ` Leon Alrae
@ 2015-06-24 13:43   ` Aurelien Jarno
  1 sibling, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 13:43 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, Yongbok Kim wrote:
> microMIPS32 Release 6 POOL16A/ POOL16C instructions
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> ---
>  target-mips/translate.c |  122 +++++++++++++++++++++++++++++++++++++++++------
>  1 files changed, 107 insertions(+), 15 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 4bce6e8..82764e7 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -13163,6 +13163,102 @@ static void gen_pool16c_insn(DisasContext *ctx)
>      }
>  }
>  
> +static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
> +                             int enc_rs)
> +{
> +    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);

Do we really want to call ADDU here? This could be as simple as:

    if (rs) {
        tcg_gen_mov_tl(rd, rs);
    } else {
        tcg_gen_movi_tl(rd, 0);
    }

    if (rt) {
        tcg_gen_mov_tl(re, rt);
    } else {
        tcg_gen_movi_tl(re, 0);
    }

> +}
> +
> +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:
> +        {
> +            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
> +            int offset = extract32(ctx->opcode, 4, 4);
> +            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
> +        }
> +        break;
> +    case R6_JRC16: /* JRCADDIUSP */
> +        if ((ctx->opcode >> 4) & 1) {
> +            /* JRCADDIUSP */
> +            int imm = extract32(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);
> +        } else {
> +            /* JRC16 */
> +            int rs = extract32(ctx->opcode, 5, 5);
> +            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
> +        }
> +        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);
> +            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
> +        }
> +        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:
> +        {
> +            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
> +            int offset = extract32(ctx->opcode, 4, 4);
> +            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
> +        }
> +        break;
> +    case JALRC16: /* BREAK16, SDBBP16 */
> +        switch (ctx->opcode & 0x3f) {
> +        case JALRC16:
> +        case JALRC16 + 0x20:
> +            /* JALRC16 */
> +            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
> +                               31, 0, 0);
> +            break;
> +        case R6_BREAK16:
> +            /* BREAK16 */
> +            generate_exception(ctx, EXCP_BREAK);
> +            break;
> +        case R6_SDBBP16:
> +            /* SDBBP16 */
> +            if (ctx->hflags & MIPS_HFLAG_SBRI) {
> +                generate_exception(ctx, EXCP_RI);
> +            } else {
> +                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();
> @@ -15168,8 +15264,11 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
>                  opc = OPC_SUBU;
>                  break;
>              }
> -
> -            gen_arith(ctx, opc, rd, rs1, rs2);
> +            if (ctx->insn_flags & ISA_MIPS32R6) {
> +                gen_arith(ctx, opc, rs1, rd, rs2);
> +            } else {
> +                gen_arith(ctx, opc, rd, rs1, rs2);
> +            }

That change is correct, but it would be nice to add a comment saying
that while the manual still describe the instruction as rd = rs + rt,
the register number location in the instruction encoding has changed.

>          }
>          break;
>      case POOL16B:
> @@ -15193,7 +15292,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:
>          {
> @@ -15213,18 +15316,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
>              int enc_dest = uMIPS_RD(ctx->opcode);
>              int enc_rt = uMIPS_RS2(ctx->opcode);
>              int enc_rs = uMIPS_RS1(ctx->opcode);
> -            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);
> +            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
>          }
>          break;
>      case LBU16:

Besides the comments above, this all looks correct.

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

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

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

* Re: [Qemu-devel] [PATCH v3 15/15] target-mips: add mips32r6-generic CPU definition
  2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 15/15] target-mips: add mips32r6-generic CPU definition Yongbok Kim
@ 2015-06-24 13:44   ` Aurelien Jarno
  0 siblings, 0 replies; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 13:44 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-23 16:38, Yongbok Kim wrote:
> 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 30605da..ddfaff8 100644
> --- a/target-mips/translate_init.c
> +++ b/target-mips/translate_init.c
> @@ -424,6 +424,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",

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

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

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

* Re: [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0
  2015-06-24 12:28   ` Aurelien Jarno
@ 2015-06-24 14:24     ` Yongbok Kim
  2015-06-24 14:59       ` Aurelien Jarno
  0 siblings, 1 reply; 36+ messages in thread
From: Yongbok Kim @ 2015-06-24 14:24 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: leon.alrae, qemu-devel

On 24/06/2015 13:28, Aurelien Jarno wrote:
> On 2015-06-23 16:38, Yongbok Kim wrote:
>> 64-bit paired-single (PS) floating point data type is optional in the
>> pre-Release 6.
>> It has to raise RI exception when PS type is not implemented. (FIR.PS = 0)
>> (The PS data type is removed in the Release 6.)
>>
>> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
>> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
>> ---

> 
> This change means that the PS instructions are now enabled only when
> FCR0_PS is set, instead of being enabled when the FPU in 64-bit mode.
> Have you checked if we need to update a few CPU definitions for it to
> work? I am thinking for example about all the CPU with FCR0_F64, but
> without FCR0_PS.
> 
> Otherwise the patch looks fine to me.
> 

I just checked all the core definitions. All other cores are OK and even
the patch brought some corrections of behaviour like 24Kf shouldn't support
PS data type but it was wrongly enabled.
However Loongson-2E and Loongson-2F might be broken because of the patch.
The question is that how to allow ps data type for these Loongson cores as
in the MIPS III architecture all the those FCR0 field is reserved apart
from implementation and revision numbers.
(1) I could add few more line in check_ps() to allow Loongson according to
the Implementation and Revision numbers. (2) Otherwise updating the
reserved fields against later architectures - F64/PS/D/S. Perhaps that
would cause another problem if an application is expecting all zeroes on
the field.
What do you think?

Regards,
Yongbok

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

* Re: [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0
  2015-06-24 14:24     ` Yongbok Kim
@ 2015-06-24 14:59       ` Aurelien Jarno
  2015-06-24 15:24         ` Aurelien Jarno
  0 siblings, 1 reply; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 14:59 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-24 15:24, Yongbok Kim wrote:
> On 24/06/2015 13:28, Aurelien Jarno wrote:
> > On 2015-06-23 16:38, Yongbok Kim wrote:
> >> 64-bit paired-single (PS) floating point data type is optional in the
> >> pre-Release 6.
> >> It has to raise RI exception when PS type is not implemented. (FIR.PS = 0)
> >> (The PS data type is removed in the Release 6.)
> >>
> >> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> >> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
> >> ---
> 
> > 
> > This change means that the PS instructions are now enabled only when
> > FCR0_PS is set, instead of being enabled when the FPU in 64-bit mode.
> > Have you checked if we need to update a few CPU definitions for it to
> > work? I am thinking for example about all the CPU with FCR0_F64, but
> > without FCR0_PS.
> > 
> > Otherwise the patch looks fine to me.
> > 
> 
> I just checked all the core definitions. All other cores are OK and even
> the patch brought some corrections of behaviour like 24Kf shouldn't support
> PS data type but it was wrongly enabled.

Great.

> However Loongson-2E and Loongson-2F might be broken because of the patch.
> The question is that how to allow ps data type for these Loongson cores as
> in the MIPS III architecture all the those FCR0 field is reserved apart
> from implementation and revision numbers.
> (1) I could add few more line in check_ps() to allow Loongson according to
> the Implementation and Revision numbers. (2) Otherwise updating the
> reserved fields against later architectures - F64/PS/D/S. Perhaps that
> would cause another problem if an application is expecting all zeroes on
> the field.

I think the best would be to add a line in check_ps(). I guess the
easiest is to check if the CPU supports the LOONGSON ISA, that is
testing (ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)).

Aurelien

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

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

* Re: [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0
  2015-06-24 14:59       ` Aurelien Jarno
@ 2015-06-24 15:24         ` Aurelien Jarno
  2015-06-24 15:53           ` Yongbok Kim
  0 siblings, 1 reply; 36+ messages in thread
From: Aurelien Jarno @ 2015-06-24 15:24 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: leon.alrae, qemu-devel

On 2015-06-24 16:59, Aurelien Jarno wrote:
> On 2015-06-24 15:24, Yongbok Kim wrote:
> > On 24/06/2015 13:28, Aurelien Jarno wrote:
> > > On 2015-06-23 16:38, Yongbok Kim wrote:
> > >> 64-bit paired-single (PS) floating point data type is optional in the
> > >> pre-Release 6.
> > >> It has to raise RI exception when PS type is not implemented. (FIR.PS = 0)
> > >> (The PS data type is removed in the Release 6.)
> > >>
> > >> Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
> > >> Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
> > >> ---
> > 
> > > 
> > > This change means that the PS instructions are now enabled only when
> > > FCR0_PS is set, instead of being enabled when the FPU in 64-bit mode.
> > > Have you checked if we need to update a few CPU definitions for it to
> > > work? I am thinking for example about all the CPU with FCR0_F64, but
> > > without FCR0_PS.
> > > 
> > > Otherwise the patch looks fine to me.
> > > 
> > 
> > I just checked all the core definitions. All other cores are OK and even
> > the patch brought some corrections of behaviour like 24Kf shouldn't support
> > PS data type but it was wrongly enabled.
> 
> Great.
> 
> > However Loongson-2E and Loongson-2F might be broken because of the patch.
> > The question is that how to allow ps data type for these Loongson cores as
> > in the MIPS III architecture all the those FCR0 field is reserved apart
> > from implementation and revision numbers.
> > (1) I could add few more line in check_ps() to allow Loongson according to
> > the Implementation and Revision numbers. (2) Otherwise updating the
> > reserved fields against later architectures - F64/PS/D/S. Perhaps that
> > would cause another problem if an application is expecting all zeroes on
> > the field.
> 
> I think the best would be to add a line in check_ps(). I guess the
> easiest is to check if the CPU supports the LOONGSON ISA, that is
> testing (ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)).

Or probably even better:

ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
         (ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F))

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

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

* Re: [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0
  2015-06-24 15:24         ` Aurelien Jarno
@ 2015-06-24 15:53           ` Yongbok Kim
  0 siblings, 0 replies; 36+ messages in thread
From: Yongbok Kim @ 2015-06-24 15:53 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: leon.alrae, qemu-devel


> Or probably even better:
> 
> ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
>          (ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F))
> 

Yes that is good.
I will send updated version soon.

Regards,
Yongbok

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

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

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-23 15:38 [Qemu-devel] [PATCH v3 00/15] target-mips: add microMIPS32 R6 Instruction Set support Yongbok Kim
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 01/15] target-mips: fix {RD, WR}PGPR in microMIPS Yongbok Kim
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 02/15] target-mips: add microMIPS TLBINV, TLBINVF Yongbok Kim
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 03/15] target-mips: remove an unused argument Yongbok Kim
2015-06-23 23:35   ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 04/15] target-mips: refactor {D}LSA, {D}ALIGN, {D}BITSWAP Yongbok Kim
2015-06-24 11:04   ` Aurelien Jarno
2015-06-24 12:31     ` Leon Alrae
2015-06-24 13:16       ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 05/15] target-mips: rearrange gen_compute_compact_branch Yongbok Kim
2015-06-24 11:15   ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0 Yongbok Kim
2015-06-24 12:28   ` Aurelien Jarno
2015-06-24 14:24     ` Yongbok Kim
2015-06-24 14:59       ` Aurelien Jarno
2015-06-24 15:24         ` Aurelien Jarno
2015-06-24 15:53           ` Yongbok Kim
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 07/15] target-mips: signal RI for removed instructions in microMIPS R6 Yongbok Kim
2015-06-24 12:32   ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 08/15] target-mips: add microMIPS32 R6 opcode enum Yongbok Kim
2015-06-24 13:23   ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 09/15] target-mips: microMIPS32 R6 branches and jumps Yongbok Kim
2015-06-24 13:24   ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 10/15] target-mips: microMIPS32 R6 POOL32A{XF} instructions Yongbok Kim
2015-06-24 13:24   ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 11/15] target-mips: microMIPS32 R6 POOL32F instructions Yongbok Kim
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 12/15] target-mips: microMIPS32 R6 POOL32{I, C} instructions Yongbok Kim
2015-06-23 16:16   ` Leon Alrae
2015-06-24 13:29   ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 13/15] target-mips: microMIPS32 R6 Major instructions Yongbok Kim
2015-06-24 13:33   ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 14/15] target-mips: microMIPS32 R6 POOL16{A, C} instructions Yongbok Kim
2015-06-23 16:16   ` Leon Alrae
2015-06-24 13:43   ` Aurelien Jarno
2015-06-23 15:38 ` [Qemu-devel] [PATCH v3 15/15] target-mips: add mips32r6-generic CPU definition Yongbok Kim
2015-06-24 13:44   ` Aurelien Jarno

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.