diff options
Diffstat (limited to 'target/mips/translate.c')
-rw-r--r-- | target/mips/translate.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/target/mips/translate.c b/target/mips/translate.c index 4c400ec0b3..d4d5d294f3 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -30517,30 +30517,13 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) } -static void decode_opc(CPUMIPSState *env, DisasContext *ctx) +static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx) { int32_t offset; int rs, rt, rd, sa; uint32_t op, op1; int16_t imm; - /* make sure instructions are on a word boundary */ - if (ctx->base.pc_next & 0x3) { - env->CP0_BadVAddr = ctx->base.pc_next; - generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); - return; - } - - /* Handle blikely not taken case */ - if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { - TCGLabel *l1 = gen_new_label(); - - tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); - tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); - gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); - gen_set_label(l1); - } - op = MASK_OP_MAJOR(ctx->opcode); rs = (ctx->opcode >> 21) & 0x1f; rt = (ctx->opcode >> 16) & 0x1f; @@ -31268,9 +31251,35 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; default: /* Invalid */ MIPS_INVAL("major opcode"); - gen_reserved_instruction(ctx); - break; + return false; } + return true; +} + +static void decode_opc(CPUMIPSState *env, DisasContext *ctx) +{ + /* make sure instructions are on a word boundary */ + if (ctx->base.pc_next & 0x3) { + env->CP0_BadVAddr = ctx->base.pc_next; + generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); + return; + } + + /* Handle blikely not taken case */ + if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { + TCGLabel *l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); + tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK); + gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); + gen_set_label(l1); + } + + if (decode_opc_legacy(env, ctx)) { + return; + } + + gen_reserved_instruction(ctx); } static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) |