@@ -362,7 +362,7 @@ DEF_HELPER_3(lra, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(per_check_exception, TCG_CALL_NO_WG, void, env, i64, i32)
DEF_HELPER_FLAGS_3(per_branch, TCG_CALL_NO_WG, void, env, i64, i32)
DEF_HELPER_FLAGS_2(per_ifetch, TCG_CALL_NO_RWG, void, env, i64)
-DEF_HELPER_FLAGS_1(per_store_real, TCG_CALL_NO_RWG, void, env)
+DEF_HELPER_FLAGS_2(per_store_real, TCG_CALL_NO_WG, noreturn, env, i32)
DEF_HELPER_FLAGS_1(stfl, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_2(xsch, void, env, i64)
@@ -660,11 +660,13 @@ void HELPER(per_ifetch)(CPUS390XState *env, uint64_t addr)
}
}
-void HELPER(per_store_real)(CPUS390XState *env)
+void HELPER(per_store_real)(CPUS390XState *env, uint32_t ilen)
{
/* PSW is saved just before calling the helper. */
env->per_address = env->psw.addr;
+ env->int_pgm_ilen = ilen;
env->per_perc_atmid = PER_CODE_EVENT_STORE_REAL | get_per_atmid(env);
+ per_raise_exception_log(env);
}
#endif
@@ -4344,8 +4344,10 @@ static DisasJumpType op_stura(DisasContext *s, DisasOps *o)
tcg_gen_qemu_st_tl(o->in1, o->in2, MMU_REAL_IDX, s->insn->data);
if (s->base.tb->flags & FLAG_MASK_PER_STORE_REAL) {
+ update_cc_op(s);
update_psw_addr(s);
- gen_helper_per_store_real(tcg_env);
+ gen_helper_per_store_real(tcg_env, tcg_constant_i32(s->ilen));
+ return DISAS_NORETURN;
}
return DISAS_NEXT;
}
@@ -6357,8 +6359,7 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
}
#ifndef CONFIG_USER_ONLY
- if (s->base.tb->flags & (FLAG_MASK_PER_STORE_REAL |
- FLAG_MASK_PER_IFETCH)) {
+ if (s->base.tb->flags & FLAG_MASK_PER_IFETCH) {
TCGv_i64 next_pc = psw_addr;
if (ret == DISAS_NEXT || ret == DISAS_TOO_MANY) {
At this point the instruction is complete and there's nothing left to do but raise the exception. With this change we need not make two helper calls for this event. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/s390x/helper.h | 2 +- target/s390x/tcg/misc_helper.c | 4 +++- target/s390x/tcg/translate.c | 7 ++++--- 3 files changed, 8 insertions(+), 5 deletions(-)