@@ -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;
}
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 <rth@twiddle.net> --- target-mips/translate.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-)