Since there are many more unconditional exceptions than conditional, introduce a new generate_exception_cond to mark conditionals. Also delete those few cases where we did attempt to stop translation after an exception, as these are now subsumed in the change.
Signed-off-by: Richard Henderson <r...@twiddle.net> --- target-mips/translate.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 2a91565..7d9eb91 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1615,14 +1615,21 @@ static inline void generate_exception_err(DisasContext *ctx, int excp, int err) gen_helper_raise_exception_err(cpu_env, texcp, terr); tcg_temp_free_i32(terr); tcg_temp_free_i32(texcp); + ctx->bstate = BS_EXCP; } -static inline void generate_exception(DisasContext *ctx, int excp) +static inline void generate_exception_cond(DisasContext *ctx, int excp) { save_cpu_state(ctx, 1); gen_helper_0e0i(raise_exception, excp); } +static inline void generate_exception(DisasContext *ctx, int excp) +{ + generate_exception_cond(ctx, excp); + ctx->bstate = BS_EXCP; +} + /* Floating point register moves. */ static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) { @@ -2044,14 +2051,14 @@ static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \ tcg_gen_andi_tl(t0, arg2, almask); \ tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \ - tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \ - generate_exception(ctx, EXCP_AdES); \ + tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \ + generate_exception_cond(ctx, EXCP_AdES); \ gen_set_label(l1); \ - tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \ tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \ tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \ - tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \ - tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \ + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \ + tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \ gen_helper_0e0i(raise_exception, EXCP_SC); \ gen_set_label(l2); \ tcg_gen_movi_tl(t0, 0); \ @@ -2506,7 +2513,7 @@ static void gen_arith_imm(DisasContext *ctx, uint32_t opc, tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); tcg_temp_free(t1); /* operands of same sign, result different sign */ - generate_exception(ctx, EXCP_OVERFLOW); + generate_exception_cond(ctx, EXCP_OVERFLOW); gen_set_label(l1); tcg_gen_ext32s_tl(t0, t0); gen_store_gpr(t0, rt); @@ -2541,7 +2548,7 @@ static void gen_arith_imm(DisasContext *ctx, uint32_t opc, tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); tcg_temp_free(t1); /* operands of same sign, result different sign */ - generate_exception(ctx, EXCP_OVERFLOW); + generate_exception_cond(ctx, EXCP_OVERFLOW); gen_set_label(l1); gen_store_gpr(t0, rt); tcg_temp_free(t0); @@ -2772,7 +2779,7 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); tcg_temp_free(t1); /* operands of same sign, result different sign */ - generate_exception(ctx, EXCP_OVERFLOW); + generate_exception_cond(ctx, EXCP_OVERFLOW); gen_set_label(l1); gen_store_gpr(t0, rd); tcg_temp_free(t0); @@ -2810,7 +2817,7 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); tcg_temp_free(t1); /* operands of different sign, first operand and result different sign */ - generate_exception(ctx, EXCP_OVERFLOW); + generate_exception_cond(ctx, EXCP_OVERFLOW); gen_set_label(l1); gen_store_gpr(t0, rd); tcg_temp_free(t0); @@ -2849,7 +2856,7 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); tcg_temp_free(t1); /* operands of same sign, result different sign */ - generate_exception(ctx, EXCP_OVERFLOW); + generate_exception_cond(ctx, EXCP_OVERFLOW); gen_set_label(l1); gen_store_gpr(t0, rd); tcg_temp_free(t0); @@ -2885,7 +2892,7 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); tcg_temp_free(t1); /* operands of different sign, first operand and result different sign */ - generate_exception(ctx, EXCP_OVERFLOW); + generate_exception_cond(ctx, EXCP_OVERFLOW); gen_set_label(l1); gen_store_gpr(t0, rd); tcg_temp_free(t0); @@ -4282,7 +4289,7 @@ static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) tcg_gen_andc_i64(t1, t2, t1); tcg_temp_free_i64(t2); tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); - generate_exception(ctx, EXCP_OVERFLOW); + generate_exception_cond(ctx, EXCP_OVERFLOW); gen_set_label(lab); opn = (opc == OPC_ADD_CP2 ? "add" : "dadd"); @@ -4305,7 +4312,7 @@ static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) tcg_gen_and_i64(t1, t1, t2); tcg_temp_free_i64(t2); tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab); - generate_exception(ctx, EXCP_OVERFLOW); + generate_exception_cond(ctx, EXCP_OVERFLOW); gen_set_label(lab); opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub"); @@ -4432,7 +4439,7 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1); break; } - generate_exception(ctx, EXCP_TRAP); + generate_exception_cond(ctx, EXCP_TRAP); gen_set_label(l1); } tcg_temp_free(t0); @@ -13664,7 +13671,6 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs) break; case SYSCALL: generate_exception(ctx, EXCP_SYSCALL); - ctx->bstate = BS_STOP; break; case SDBBP: if (is_uhi(extract32(ctx->opcode, 16, 10))) { @@ -15248,7 +15254,6 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx) if (ctx->pc & 0x1) { env->CP0_BadVAddr = ctx->pc; generate_exception(ctx, EXCP_AdEL); - ctx->bstate = BS_STOP; return 2; } @@ -15268,8 +15273,6 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx) /* LB32, LH32, LWC132, LDC132, LW32 */ if (ctx->hflags & MIPS_HFLAG_BDS16) { generate_exception(ctx, EXCP_RI); - /* Just stop translation; the user is confused. */ - ctx->bstate = BS_STOP; return 2; } break; @@ -15281,8 +15284,6 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx) /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */ if (ctx->hflags & MIPS_HFLAG_BDS32) { generate_exception(ctx, EXCP_RI); - /* Just stop translation; the user is confused. */ - ctx->bstate = BS_STOP; return 2; } break; @@ -17510,7 +17511,6 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SYSCALL: generate_exception(ctx, EXCP_SYSCALL); - ctx->bstate = BS_STOP; break; case OPC_BREAK: generate_exception(ctx, EXCP_BREAK); @@ -18885,6 +18885,7 @@ static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx) case OPC_HSUB_U_df: if (df == DF_BYTE) { generate_exception(ctx, EXCP_RI); + break; } switch (MASK_MSA_3R(ctx->opcode)) { case OPC_DOTP_S_df: @@ -19497,7 +19498,6 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) if (ctx->pc & 0x3) { env->CP0_BadVAddr = ctx->pc; generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL); - ctx->bstate = BS_STOP; return; } @@ -20247,7 +20247,6 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, insn_bytes = decode_mips16_opc(env, &ctx); } else { generate_exception(&ctx, EXCP_RI); - ctx.bstate = BS_STOP; break; } -- 2.4.3