diff mbox

[05/13] target-mips: signal RI for removed instructions in microMIPS R6

Message ID 1434117743-53520-6-git-send-email-yongbok.kim@imgtec.com
State New
Headers show

Commit Message

Yongbok Kim June 12, 2015, 2:02 p.m. UTC
Signal a Reserved Instruction exception for removed instruction encoding
in microMIPS Release 6.

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

Comments

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

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

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

AFAICT you missed *.PS instructions.

Leon
diff mbox

Patch

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