target/hppa: Use delay_excp for conditional trap on overflow

Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2024-03-26 13:54:01 -10:00
parent 269ca0a9cc
commit a0ea4becca
4 changed files with 14 additions and 17 deletions

View file

@ -1,5 +1,4 @@
DEF_HELPER_2(excp, noreturn, env, int) DEF_HELPER_2(excp, noreturn, env, int)
DEF_HELPER_FLAGS_2(tsv, TCG_CALL_NO_WG, void, env, tl)
DEF_HELPER_FLAGS_3(stby_b, TCG_CALL_NO_WG, void, env, tl, tl) DEF_HELPER_FLAGS_3(stby_b, TCG_CALL_NO_WG, void, env, tl, tl)
DEF_HELPER_FLAGS_3(stby_b_parallel, TCG_CALL_NO_WG, void, env, tl, tl) DEF_HELPER_FLAGS_3(stby_b_parallel, TCG_CALL_NO_WG, void, env, tl, tl)

View file

@ -134,13 +134,13 @@ void hppa_cpu_do_interrupt(CPUState *cs)
switch (i) { switch (i) {
case EXCP_ILL: case EXCP_ILL:
case EXCP_BREAK: case EXCP_BREAK:
case EXCP_OVERFLOW:
case EXCP_COND: case EXCP_COND:
case EXCP_PRIV_REG: case EXCP_PRIV_REG:
case EXCP_PRIV_OPR: case EXCP_PRIV_OPR:
/* IIR set via translate.c. */ /* IIR set via translate.c. */
break; break;
case EXCP_OVERFLOW:
case EXCP_ASSIST: case EXCP_ASSIST:
case EXCP_DTLB_MISS: case EXCP_DTLB_MISS:
case EXCP_NA_ITLB_MISS: case EXCP_NA_ITLB_MISS:

View file

@ -42,13 +42,6 @@ G_NORETURN void hppa_dynamic_excp(CPUHPPAState *env, int excp, uintptr_t ra)
cpu_loop_exit_restore(cs, ra); cpu_loop_exit_restore(cs, ra);
} }
void HELPER(tsv)(CPUHPPAState *env, target_ulong cond)
{
if (unlikely((target_long)cond < 0)) {
hppa_dynamic_excp(env, EXCP_OVERFLOW, GETPC());
}
}
static void atomic_store_mask32(CPUHPPAState *env, target_ulong addr, static void atomic_store_mask32(CPUHPPAState *env, target_ulong addr,
uint32_t val, uint32_t mask, uintptr_t ra) uint32_t val, uint32_t mask, uintptr_t ra)
{ {

View file

@ -1136,6 +1136,17 @@ static void gen_tc(DisasContext *ctx, DisasCond *cond)
} }
} }
static void gen_tsv(DisasContext *ctx, TCGv_i64 *sv, bool d)
{
DisasCond cond = do_cond(ctx, /* SV */ 12, d, NULL, NULL, *sv);
DisasDelayException *e = delay_excp(ctx, EXCP_OVERFLOW);
tcg_gen_brcond_i64(cond.c, cond.a0, cond.a1, e->lab);
/* In the non-trap path, V is known zero. */
*sv = tcg_constant_i64(0);
}
static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 orig_in1, static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 orig_in1,
TCGv_i64 in2, unsigned shift, bool is_l, TCGv_i64 in2, unsigned shift, bool is_l,
bool is_tsv, bool is_tc, bool is_c, unsigned cf, bool d) bool is_tsv, bool is_tc, bool is_c, unsigned cf, bool d)
@ -1178,10 +1189,7 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 orig_in1,
if (is_tsv || cond_need_sv(c)) { if (is_tsv || cond_need_sv(c)) {
sv = do_add_sv(ctx, dest, in1, in2, orig_in1, shift, d); sv = do_add_sv(ctx, dest, in1, in2, orig_in1, shift, d);
if (is_tsv) { if (is_tsv) {
if (!d) { gen_tsv(ctx, &sv, d);
tcg_gen_ext32s_i64(sv, sv);
}
gen_helper_tsv(tcg_env, sv);
} }
} }
@ -1282,10 +1290,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
if (is_tsv || cond_need_sv(c)) { if (is_tsv || cond_need_sv(c)) {
sv = do_sub_sv(ctx, dest, in1, in2); sv = do_sub_sv(ctx, dest, in1, in2);
if (is_tsv) { if (is_tsv) {
if (!d) { gen_tsv(ctx, &sv, d);
tcg_gen_ext32s_i64(sv, sv);
}
gen_helper_tsv(tcg_env, sv);
} }
} }