Store yield_needed = 0 when raising YIELD, then call gen_helper_raise_excp with restore 0. Drop TCG exception. Keep exception_cause helpers. C callers use xtensa_exception for the old helper_exception body.
Signed-off-by: Yonggang Luo <[email protected]> --- target/xtensa/cpu.h | 1 + target/xtensa/exc_helper.c | 13 +++++-------- target/xtensa/helper.h | 1 - target/xtensa/translate.c | 7 ++++++- target/xtensa/win_helper.c | 12 ++++++------ 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index 49d6ad9083d..0b2cb5a250d 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -601,6 +601,7 @@ int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); G_NORETURN void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); +G_NORETURN void xtensa_exception(CPUXtensaState *env, uint32_t excp); #define CPU_RESOLVING_TYPE TYPE_XTENSA_CPU diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c index 7cb67d179a8..3049432f4c4 100644 --- a/target/xtensa/exc_helper.c +++ b/target/xtensa/exc_helper.c @@ -35,15 +35,12 @@ #include "qemu/atomic.h" #include "qemu/plugin.h" -void HELPER(exception)(CPUXtensaState *env, uint32_t excp) +void xtensa_exception(CPUXtensaState *env, uint32_t excp) { - CPUState *cs = env_cpu(env); - - cs->exception_index = excp; if (excp == EXCP_YIELD) { env->yield_needed = 0; } - cpu_loop_exit(cs); + cpu_loop_exit_excp(env_cpu(env), excp, 0); } void HELPER(exception_cause)(CPUXtensaState *env, uint32_t pc, uint32_t cause) @@ -66,7 +63,7 @@ void HELPER(exception_cause)(CPUXtensaState *env, uint32_t pc, uint32_t cause) env->sregs[EXCCAUSE] = cause; env->sregs[PS] |= PS_EXCM; - HELPER(exception)(env, vector); + xtensa_exception(env, vector); } void HELPER(exception_cause_vaddr)(CPUXtensaState *env, @@ -93,7 +90,7 @@ void HELPER(debug_exception)(CPUXtensaState *env, uint32_t pc, uint32_t cause) env->sregs[EPS2 + level - 2] = env->sregs[PS]; env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) | PS_EXCM | (level << PS_INTLEVEL_SHIFT); - HELPER(exception)(env, EXC_DEBUG); + xtensa_exception(env, EXC_DEBUG); } #ifndef CONFIG_USER_ONLY @@ -116,7 +113,7 @@ void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel) } cpu->halted = 1; - HELPER(exception)(env, EXCP_HLT); + xtensa_exception(env, EXCP_HLT); } void HELPER(check_interrupts)(CPUXtensaState *env) diff --git a/target/xtensa/helper.h b/target/xtensa/helper.h index ae938ceedb8..4640d0da59a 100644 --- a/target/xtensa/helper.h +++ b/target/xtensa/helper.h @@ -1,4 +1,3 @@ -DEF_HELPER_2(exception, noreturn, env, i32) DEF_HELPER_3(exception_cause, noreturn, env, i32, i32) DEF_HELPER_4(exception_cause_vaddr, noreturn, env, i32, i32, i32) DEF_HELPER_3(debug_exception, noreturn, env, i32, i32) diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 175fd4b5cfc..58fbe8496aa 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -305,7 +305,12 @@ static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa) static void gen_exception(DisasContext *dc, int excp) { - gen_helper_exception(tcg_env, tcg_constant_i32(excp)); + if (excp == EXCP_YIELD) { + tcg_gen_st_i32(tcg_constant_i32(0), tcg_env, + offsetof(CPUXtensaState, yield_needed)); + } + gen_helper_raise_excp(tcg_env, tcg_constant_i32(excp), + tcg_constant_i32(0)); } static void gen_exception_cause(DisasContext *dc, uint32_t cause) diff --git a/target/xtensa/win_helper.c b/target/xtensa/win_helper.c index 4b25f8f4de7..3e4d7c0f768 100644 --- a/target/xtensa/win_helper.c +++ b/target/xtensa/win_helper.c @@ -125,13 +125,13 @@ void HELPER(window_check)(CPUXtensaState *env, uint32_t pc, uint32_t w) switch (ctz32(windowstart >> n)) { case 0: - HELPER(exception)(env, EXC_WINDOW_OVERFLOW4); + xtensa_exception(env, EXC_WINDOW_OVERFLOW4); break; case 1: - HELPER(exception)(env, EXC_WINDOW_OVERFLOW8); + xtensa_exception(env, EXC_WINDOW_OVERFLOW8); break; default: - HELPER(exception)(env, EXC_WINDOW_OVERFLOW12); + xtensa_exception(env, EXC_WINDOW_OVERFLOW12); break; } } @@ -174,11 +174,11 @@ void HELPER(test_underflow_retw)(CPUXtensaState *env, uint32_t pc) env->sregs[EPC1] = env->pc = pc; if (n == 1) { - HELPER(exception)(env, EXC_WINDOW_UNDERFLOW4); + xtensa_exception(env, EXC_WINDOW_UNDERFLOW4); } else if (n == 2) { - HELPER(exception)(env, EXC_WINDOW_UNDERFLOW8); + xtensa_exception(env, EXC_WINDOW_UNDERFLOW8); } else if (n == 3) { - HELPER(exception)(env, EXC_WINDOW_UNDERFLOW12); + xtensa_exception(env, EXC_WINDOW_UNDERFLOW12); } } } -- 2.52.0.windows.1
