From 62ef344824bc62889c8f4aa7ece0841b2294666c Mon Sep 17 00:00:00 2001 From: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> Date: Mon, 29 Sep 2025 17:54:16 +0800 Subject: [PATCH 1/5] add arm standardization for uc_stop in tb trans Signed-off-by: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> --- qemu/aarch64.h | 1 + qemu/arm.h | 1 + qemu/include/exec/translator.h | 1 + qemu/target/arm/helper.h | 1 + qemu/target/arm/op_helper.c | 28 ++++++++++++++++++++++++++++ qemu/target/arm/translate-a64.c | 18 +++++++++++++++++- qemu/target/arm/translate.c | 21 ++++++++++++++++++--- symbols.sh | 2 ++ 8 files changed, 69 insertions(+), 4 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index ad096574a4..1df19d526e 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1820,6 +1820,7 @@ #define helper_usat16 helper_usat16_aarch64 #define helper_setend helper_setend_aarch64 #define helper_wfi helper_wfi_aarch64 +#define helper_uc_exit helper_uc_exit_aarch64 #define helper_wfe helper_wfe_aarch64 #define helper_yield helper_yield_aarch64 #define helper_exception_internal helper_exception_internal_aarch64 diff --git a/qemu/arm.h b/qemu/arm.h index cd81f540f0..fee7b05790 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1746,6 +1746,7 @@ #define helper_usat16 helper_usat16_arm #define helper_setend helper_setend_arm #define helper_wfi helper_wfi_arm +#define helper_uc_exit helper_uc_exit_arm #define helper_wfe helper_wfe_arm #define helper_yield helper_yield_arm #define helper_exception_internal helper_exception_internal_arm diff --git a/qemu/include/exec/translator.h b/qemu/include/exec/translator.h index a86cd75977..d342817301 100644 --- a/qemu/include/exec/translator.h +++ b/qemu/include/exec/translator.h @@ -37,6 +37,7 @@ typedef enum DisasJumpType { DISAS_NEXT, DISAS_TOO_MANY, + DISAS_UC_EXIT, DISAS_NORETURN, DISAS_TARGET_0, DISAS_TARGET_1, diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index 616d032c84..8274389437 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -52,6 +52,7 @@ DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32) DEF_HELPER_2(exception_bkpt_insn, void, env, i32) DEF_HELPER_1(setend, void, env) DEF_HELPER_2(wfi, void, env, i32) +DEF_HELPER_2(uc_exit, void, env, i32) DEF_HELPER_1(wfe, void, env) DEF_HELPER_1(yield, void, env) DEF_HELPER_1(pre_hvc, void, env) diff --git a/qemu/target/arm/op_helper.c b/qemu/target/arm/op_helper.c index af4e1089c4..a976e7e5f8 100644 --- a/qemu/target/arm/op_helper.c +++ b/qemu/target/arm/op_helper.c @@ -336,6 +336,34 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len) cpu_loop_exit(cs); } +void HELPER(uc_exit)(CPUARMState *env, uint32_t insn_len) +{ + CPUState *cs = env_cpu(env); + int target_el = check_wfx_trap(env, false); + + if (cpu_has_work(cs)) { + /* Don't bother to go into our "low power state" if + * we would just wake up immediately. + */ + return; + } + + if (target_el) { + if (env->aarch64) { + env->pc -= insn_len; + } else { + env->regs[15] -= insn_len; + } + + raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2), + target_el); + } + + cs->exception_index = EXCP_HLT; + cs->halted = 1; + cpu_loop_exit(cs); +} + void HELPER(wfe)(CPUARMState *env) { /* This is a hint instruction that is semantically different diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 922976536e..11992236d4 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -14737,7 +14737,7 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) // Unicorn: end address tells us to stop emulation if (uc_addr_is_exit(dc->uc, dcbase->pc_next)) { // imitate WFI instruction to halt emulation - dcbase->is_jmp = DISAS_WFI; + dcbase->is_jmp = DISAS_UC_EXIT; } else { if (dc->ss_active && !dc->pstate_ss) { /* Singlestep state is Active-pending. @@ -14830,6 +14830,22 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) tcg_gen_exit_tb(tcg_ctx, NULL, 0); break; } + case DISAS_UC_EXIT: + { + /* This is a special case because we don't want to just halt the CPU + * if trying to debug across a WFI. + */ + TCGv_i32 tmp = tcg_const_i32(tcg_ctx, 4); + + gen_a64_set_pc_im(tcg_ctx, dc->base.pc_next); + gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env, tmp); + tcg_temp_free_i32(tcg_ctx, tmp); + /* The helper doesn't necessarily throw an exception, but we + * must go back to the main loop to check for interrupts anyway. + */ + tcg_gen_exit_tb(tcg_ctx, NULL, 0); + break; + } } } } diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 744d8ff709..df7c91ea3c 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -11462,7 +11462,7 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) // Unicorn: end address tells us to stop emulation if (uc_addr_is_exit(dc->uc, dcbase->pc_next)) { // imitate WFI instruction to halt emulation - dcbase->is_jmp = DISAS_WFI; + dcbase->is_jmp = DISAS_UC_EXIT; } else { dc->pc_curr = dc->base.pc_next; insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b); @@ -11478,7 +11478,7 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) // // See discussion here: https://github.com/unicorn-engine/unicorn/issues/1536 if (dc->uc->invalid_error) { - dcbase->is_jmp = DISAS_WFI; + dcbase->is_jmp = DISAS_UC_EXIT; return; } @@ -11555,7 +11555,7 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) // Unicorn: end address tells us to stop emulation if (uc_addr_is_exit(uc, dcbase->pc_next)) { // imitate WFI instruction to halt emulation - dcbase->is_jmp = DISAS_WFI; + dcbase->is_jmp = DISAS_UC_EXIT; return; } @@ -11753,6 +11753,21 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_SMC: gen_exception(tcg_ctx, EXCP_SMC, syn_aa32_smc(), 3); break; + case DISAS_UC_EXIT: + { + gen_set_pc_im(dc, dc->base.pc_next); + + TCGv_i32 tmp = tcg_const_i32(tcg_ctx, (dc->thumb && + !(dc->insn & (1U << 31))) ? 2 : 4); + + gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env, tmp); + tcg_temp_free_i32(tcg_ctx, tmp); + /* The helper doesn't necessarily throw an exception, but we + * must go back to the main loop to check for interrupts anyway. + */ + tcg_gen_exit_tb(tcg_ctx, NULL, 0); + break; + } } } diff --git a/symbols.sh b/symbols.sh index bcedaea983..a68ece0d09 100755 --- a/symbols.sh +++ b/symbols.sh @@ -2353,6 +2353,7 @@ helper_usat \ helper_usat16 \ helper_setend \ helper_wfi \ +helper_uc_exit \ helper_wfe \ helper_yield \ helper_exception_internal \ @@ -3135,6 +3136,7 @@ helper_usat \ helper_usat16 \ helper_setend \ helper_wfi \ +helper_uc_exit \ helper_wfe \ helper_yield \ helper_exception_internal \ From 1806cf887c628494d8c5bbb9a6266c1079d7be0a Mon Sep 17 00:00:00 2001 From: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> Date: Mon, 29 Sep 2025 17:54:39 +0800 Subject: [PATCH 2/5] completely add tb translation Signed-off-by: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> --- qemu/aarch64.h | 2 +- qemu/arm.h | 2 +- qemu/include/exec/translator.h | 2 +- qemu/m68k.h | 1 + qemu/mips.h | 1 + qemu/mips64.h | 1 + qemu/mips64el.h | 1 + qemu/mipsel.h | 1 + qemu/ppc.h | 1 + qemu/ppc64.h | 1 + qemu/riscv32.h | 2 +- qemu/riscv64.h | 2 +- qemu/s390x.h | 2 +- qemu/sparc.h | 1 + qemu/sparc64.h | 1 + qemu/target/arm/helper.h | 2 +- qemu/target/arm/op_helper.c | 37 +++++--------------- qemu/target/arm/translate-a64.c | 12 +------ qemu/target/arm/translate.c | 60 ++++++++++++++------------------- qemu/target/i386/helper.h | 1 + qemu/target/i386/misc_helper.c | 9 +++++ qemu/target/i386/translate.c | 29 ++++++++++------ qemu/target/m68k/translate.c | 5 ++- qemu/target/mips/helper.h | 1 + qemu/target/mips/op_helper.c | 13 +++++++ qemu/target/mips/translate.c | 9 ++--- qemu/target/ppc/translate.c | 23 +++++++++++-- qemu/target/riscv/helper.h | 2 +- qemu/target/riscv/op_helper.c | 2 +- qemu/target/riscv/translate.c | 7 +--- qemu/target/s390x/excp_helper.c | 2 +- qemu/target/s390x/helper.h | 2 +- qemu/target/s390x/translate.c | 9 +++-- qemu/target/sparc/helper.c | 9 +++++ qemu/target/sparc/helper.h | 1 + qemu/target/sparc/translate.c | 9 ++--- qemu/target/tricore/helper.h | 2 +- qemu/target/tricore/op_helper.c | 2 +- qemu/target/tricore/translate.c | 8 +---- qemu/tricore.h | 2 +- qemu/x86_64.h | 1 + symbols.sh | 8 ++--- 42 files changed, 155 insertions(+), 133 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 1df19d526e..3204f7be65 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_aarch64 #define helper_stqcx_le_parallel helper_stqcx_le_parallel_aarch64 #define helper_stqcx_be_parallel helper_stqcx_be_parallel_aarch64 +#define helper_uc_exit helper_uc_exit_aarch64 #define cpu_aarch64_init cpu_aarch64_init_aarch64 #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_aarch64 #define arm_cpu_update_virq arm_cpu_update_virq_aarch64 @@ -1820,7 +1821,6 @@ #define helper_usat16 helper_usat16_aarch64 #define helper_setend helper_setend_aarch64 #define helper_wfi helper_wfi_aarch64 -#define helper_uc_exit helper_uc_exit_aarch64 #define helper_wfe helper_wfe_aarch64 #define helper_yield helper_yield_aarch64 #define helper_exception_internal helper_exception_internal_aarch64 diff --git a/qemu/arm.h b/qemu/arm.h index fee7b05790..c43816bc59 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_arm #define helper_stqcx_le_parallel helper_stqcx_le_parallel_arm #define helper_stqcx_be_parallel helper_stqcx_be_parallel_arm +#define helper_uc_exit helper_uc_exit_arm #define arm_cpu_exec_interrupt arm_cpu_exec_interrupt_arm #define arm_cpu_update_virq arm_cpu_update_virq_arm #define arm_cpu_update_vfiq arm_cpu_update_vfiq_arm @@ -1746,7 +1747,6 @@ #define helper_usat16 helper_usat16_arm #define helper_setend helper_setend_arm #define helper_wfi helper_wfi_arm -#define helper_uc_exit helper_uc_exit_arm #define helper_wfe helper_wfe_arm #define helper_yield helper_yield_arm #define helper_exception_internal helper_exception_internal_arm diff --git a/qemu/include/exec/translator.h b/qemu/include/exec/translator.h index d342817301..47cc0f575d 100644 --- a/qemu/include/exec/translator.h +++ b/qemu/include/exec/translator.h @@ -37,7 +37,7 @@ typedef enum DisasJumpType { DISAS_NEXT, DISAS_TOO_MANY, - DISAS_UC_EXIT, + DISAS_UC_EXIT, // Unicorn: Special disas state for exiting in the middle of tb. DISAS_NORETURN, DISAS_TARGET_0, DISAS_TARGET_1, diff --git a/qemu/m68k.h b/qemu/m68k.h index 67f94364d2..8d5281c494 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_m68k #define helper_stqcx_le_parallel helper_stqcx_le_parallel_m68k #define helper_stqcx_be_parallel helper_stqcx_be_parallel_m68k +#define helper_uc_exit helper_uc_exit_m68k #define cpu_m68k_init cpu_m68k_init_m68k #define helper_reds32 helper_reds32_m68k #define helper_redf32 helper_redf32_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 9b0fa37cd0..95b52b731e 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_mips #define helper_stqcx_le_parallel helper_stqcx_le_parallel_mips #define helper_stqcx_be_parallel helper_stqcx_be_parallel_mips +#define helper_uc_exit helper_uc_exit_mips #define helper_mfc0_mvpcontrol helper_mfc0_mvpcontrol_mips #define helper_mfc0_mvpconf0 helper_mfc0_mvpconf0_mips #define helper_mfc0_mvpconf1 helper_mfc0_mvpconf1_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index ec030ff261..14d8f2c370 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_mips64 #define helper_stqcx_le_parallel helper_stqcx_le_parallel_mips64 #define helper_stqcx_be_parallel helper_stqcx_be_parallel_mips64 +#define helper_uc_exit helper_uc_exit_mips64 #define helper_mfc0_mvpcontrol helper_mfc0_mvpcontrol_mips64 #define helper_mfc0_mvpconf0 helper_mfc0_mvpconf0_mips64 #define helper_mfc0_mvpconf1 helper_mfc0_mvpconf1_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index ea8c92739c..451d3d203a 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_mips64el #define helper_stqcx_le_parallel helper_stqcx_le_parallel_mips64el #define helper_stqcx_be_parallel helper_stqcx_be_parallel_mips64el +#define helper_uc_exit helper_uc_exit_mips64el #define helper_mfc0_mvpcontrol helper_mfc0_mvpcontrol_mips64el #define helper_mfc0_mvpconf0 helper_mfc0_mvpconf0_mips64el #define helper_mfc0_mvpconf1 helper_mfc0_mvpconf1_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 1b30cbc229..fce7c63306 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_mipsel #define helper_stqcx_le_parallel helper_stqcx_le_parallel_mipsel #define helper_stqcx_be_parallel helper_stqcx_be_parallel_mipsel +#define helper_uc_exit helper_uc_exit_mipsel #define helper_mfc0_mvpcontrol helper_mfc0_mvpcontrol_mipsel #define helper_mfc0_mvpconf0 helper_mfc0_mvpconf0_mipsel #define helper_mfc0_mvpconf1 helper_mfc0_mvpconf1_mipsel diff --git a/qemu/ppc.h b/qemu/ppc.h index 9648fd2fe5..758fd4d702 100644 --- a/qemu/ppc.h +++ b/qemu/ppc.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_ppc #define helper_stqcx_le_parallel helper_stqcx_le_parallel_ppc #define helper_stqcx_be_parallel helper_stqcx_be_parallel_ppc +#define helper_uc_exit helper_uc_exit_ppc #define ppc_cpu_unrealize ppc_cpu_unrealize_ppc #define ppc_cpu_instance_finalize ppc_cpu_instance_finalize_ppc #define ppc_cpu_do_interrupt ppc_cpu_do_interrupt_ppc diff --git a/qemu/ppc64.h b/qemu/ppc64.h index 2d995d5ece..cb00e53d03 100644 --- a/qemu/ppc64.h +++ b/qemu/ppc64.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_ppc64 #define helper_stqcx_le_parallel helper_stqcx_le_parallel_ppc64 #define helper_stqcx_be_parallel helper_stqcx_be_parallel_ppc64 +#define helper_uc_exit helper_uc_exit_ppc64 #define ppc_cpu_unrealize ppc_cpu_unrealize_ppc64 #define ppc_cpu_instance_finalize ppc_cpu_instance_finalize_ppc64 #define ppc_cpu_do_interrupt ppc_cpu_do_interrupt_ppc64 diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 26c798b413..edacb77758 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_riscv32 #define helper_stqcx_le_parallel helper_stqcx_le_parallel_riscv32 #define helper_stqcx_be_parallel helper_stqcx_be_parallel_riscv32 +#define helper_uc_exit helper_uc_exit_riscv32 #define riscv_cpu_mmu_index riscv_cpu_mmu_index_riscv32 #define riscv_cpu_exec_interrupt riscv_cpu_exec_interrupt_riscv32 #define riscv_cpu_fp_enabled riscv_cpu_fp_enabled_riscv32 @@ -1360,7 +1361,6 @@ #define helper_fclass_d helper_fclass_d_riscv32 #define riscv_raise_exception riscv_raise_exception_riscv32 #define helper_raise_exception helper_raise_exception_riscv32 -#define helper_uc_riscv_exit helper_uc_riscv_exit_riscv32 #define helper_csrrw helper_csrrw_riscv32 #define helper_csrrs helper_csrrs_riscv32 #define helper_csrrc helper_csrrc_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index 8332ce6dab..ec9c1f814f 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_riscv64 #define helper_stqcx_le_parallel helper_stqcx_le_parallel_riscv64 #define helper_stqcx_be_parallel helper_stqcx_be_parallel_riscv64 +#define helper_uc_exit helper_uc_exit_riscv64 #define riscv_cpu_mmu_index riscv_cpu_mmu_index_riscv64 #define riscv_cpu_exec_interrupt riscv_cpu_exec_interrupt_riscv64 #define riscv_cpu_fp_enabled riscv_cpu_fp_enabled_riscv64 @@ -1360,7 +1361,6 @@ #define helper_fclass_d helper_fclass_d_riscv64 #define riscv_raise_exception riscv_raise_exception_riscv64 #define helper_raise_exception helper_raise_exception_riscv64 -#define helper_uc_riscv_exit helper_uc_riscv_exit_riscv64 #define helper_csrrw helper_csrrw_riscv64 #define helper_csrrs helper_csrrs_riscv64 #define helper_csrrc helper_csrrc_riscv64 diff --git a/qemu/s390x.h b/qemu/s390x.h index 5daa819afa..22811e0d7a 100644 --- a/qemu/s390x.h +++ b/qemu/s390x.h @@ -1294,7 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_s390x #define helper_stqcx_le_parallel helper_stqcx_le_parallel_s390x #define helper_stqcx_be_parallel helper_stqcx_be_parallel_s390x -#define helper_uc_s390x_exit helper_uc_s390x_exit_s390x +#define helper_uc_exit helper_uc_exit_s390x #define tcg_s390_tod_updated tcg_s390_tod_updated_s390x #define tcg_s390_program_interrupt tcg_s390_program_interrupt_s390x #define tcg_s390_data_exception tcg_s390_data_exception_s390x diff --git a/qemu/sparc.h b/qemu/sparc.h index 5f7c4689b7..8aac8b2bc3 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_sparc #define helper_stqcx_le_parallel helper_stqcx_le_parallel_sparc #define helper_stqcx_be_parallel helper_stqcx_be_parallel_sparc +#define helper_uc_exit helper_uc_exit_sparc #define helper_compute_psr helper_compute_psr_sparc #define helper_compute_C_icc helper_compute_C_icc_sparc #define cpu_sparc_set_id cpu_sparc_set_id_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 33003493db..cb99c50f86 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_sparc64 #define helper_stqcx_le_parallel helper_stqcx_le_parallel_sparc64 #define helper_stqcx_be_parallel helper_stqcx_be_parallel_sparc64 +#define helper_uc_exit helper_uc_exit_sparc64 #define helper_compute_psr helper_compute_psr_sparc64 #define helper_compute_C_icc helper_compute_C_icc_sparc64 #define cpu_sparc_set_id cpu_sparc_set_id_sparc64 diff --git a/qemu/target/arm/helper.h b/qemu/target/arm/helper.h index 8274389437..8b91b6d2cf 100644 --- a/qemu/target/arm/helper.h +++ b/qemu/target/arm/helper.h @@ -1,5 +1,6 @@ DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64) +DEF_HELPER_1(uc_exit, void, env) DEF_HELPER_FLAGS_1(sxtb16, TCG_CALL_NO_RWG_SE, i32, i32) DEF_HELPER_FLAGS_1(uxtb16, TCG_CALL_NO_RWG_SE, i32, i32) @@ -52,7 +53,6 @@ DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32) DEF_HELPER_2(exception_bkpt_insn, void, env, i32) DEF_HELPER_1(setend, void, env) DEF_HELPER_2(wfi, void, env, i32) -DEF_HELPER_2(uc_exit, void, env, i32) DEF_HELPER_1(wfe, void, env) DEF_HELPER_1(yield, void, env) DEF_HELPER_1(pre_hvc, void, env) diff --git a/qemu/target/arm/op_helper.c b/qemu/target/arm/op_helper.c index a976e7e5f8..18fa56250b 100644 --- a/qemu/target/arm/op_helper.c +++ b/qemu/target/arm/op_helper.c @@ -336,34 +336,6 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len) cpu_loop_exit(cs); } -void HELPER(uc_exit)(CPUARMState *env, uint32_t insn_len) -{ - CPUState *cs = env_cpu(env); - int target_el = check_wfx_trap(env, false); - - if (cpu_has_work(cs)) { - /* Don't bother to go into our "low power state" if - * we would just wake up immediately. - */ - return; - } - - if (target_el) { - if (env->aarch64) { - env->pc -= insn_len; - } else { - env->regs[15] -= insn_len; - } - - raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2), - target_el); - } - - cs->exception_index = EXCP_HLT; - cs->halted = 1; - cpu_loop_exit(cs); -} - void HELPER(wfe)(CPUARMState *env) { /* This is a hint instruction that is semantically different @@ -1026,3 +998,12 @@ uint32_t HELPER(uc_hooksys64)(CPUARMState *env, uint32_t insn, void *hk) JIT_CALLBACK_GUARD_VAR(ret, ((uc_cb_insn_sys_t)(hook->callback))(uc, uc_rt, &cp_reg, hook->user_data)); return ret; } + +void HELPER(uc_exit)(CPUARMState *env) +{ + CPUState *cs = env_cpu(env); + + cs->exception_index = EXCP_HLT; + cs->halted = 1; + cpu_loop_exit(cs); +} \ No newline at end of file diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 11992236d4..53a6d87f34 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -14832,18 +14832,8 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) } case DISAS_UC_EXIT: { - /* This is a special case because we don't want to just halt the CPU - * if trying to debug across a WFI. - */ - TCGv_i32 tmp = tcg_const_i32(tcg_ctx, 4); - gen_a64_set_pc_im(tcg_ctx, dc->base.pc_next); - gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env, tmp); - tcg_temp_free_i32(tcg_ctx, tmp); - /* The helper doesn't necessarily throw an exception, but we - * must go back to the main loop to check for interrupts anyway. - */ - tcg_gen_exit_tb(tcg_ctx, NULL, 0); + gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env); break; } } diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index df7c91ea3c..9058895ee0 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -11463,33 +11463,34 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) if (uc_addr_is_exit(dc->uc, dcbase->pc_next)) { // imitate WFI instruction to halt emulation dcbase->is_jmp = DISAS_UC_EXIT; - } else { - dc->pc_curr = dc->base.pc_next; - insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b); - dc->insn = insn; - - // Unicorn: - // - // If we get an error during fetching code, we have to skip the instruction decoding - // to ensure the PC remains unchanged. - // - // This is to keep the same behavior with Unicorn1, though, it's inconsistent with - // official arm documents. - // - // See discussion here: https://github.com/unicorn-engine/unicorn/issues/1536 - if (dc->uc->invalid_error) { - dcbase->is_jmp = DISAS_UC_EXIT; - return; - } + return; + } + + dc->pc_curr = dc->base.pc_next; + insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b); + dc->insn = insn; + + // Unicorn: + // + // If we get an error during fetching code, we have to skip the instruction decoding + // to ensure the PC remains unchanged. + // + // This is to keep the same behavior with Unicorn1, though, it's inconsistent with + // official arm documents. + // + // See discussion here: https://github.com/unicorn-engine/unicorn/issues/1536 + if (dc->uc->invalid_error) { + dcbase->is_jmp = DISAS_UC_EXIT; + return; + } - dc->base.pc_next += 4; - disas_arm_insn(dc, insn); + dc->base.pc_next += 4; + disas_arm_insn(dc, insn); - arm_post_translate_insn(dc); + arm_post_translate_insn(dc); - /* ARM is a fixed-length ISA. We performed the cross-page check - in init_disas_context by adjusting max_insns. */ - } + /* ARM is a fixed-length ISA. We performed the cross-page check + in init_disas_context by adjusting max_insns. */ } static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn) @@ -11756,16 +11757,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_UC_EXIT: { gen_set_pc_im(dc, dc->base.pc_next); - - TCGv_i32 tmp = tcg_const_i32(tcg_ctx, (dc->thumb && - !(dc->insn & (1U << 31))) ? 2 : 4); - - gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env, tmp); - tcg_temp_free_i32(tcg_ctx, tmp); - /* The helper doesn't necessarily throw an exception, but we - * must go back to the main loop to check for interrupts anyway. - */ - tcg_gen_exit_tb(tcg_ctx, NULL, 0); + gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env); break; } } diff --git a/qemu/target/i386/helper.h b/qemu/target/i386/helper.h index 399cc0df99..7237b0b448 100644 --- a/qemu/target/i386/helper.h +++ b/qemu/target/i386/helper.h @@ -1,5 +1,6 @@ DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64) +DEF_HELPER_1(uc_exit, void, env) DEF_HELPER_FLAGS_4(cc_compute_all, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int) DEF_HELPER_FLAGS_4(cc_compute_c, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int) diff --git a/qemu/target/i386/misc_helper.c b/qemu/target/i386/misc_helper.c index ccc12c8192..a96f397c5c 100644 --- a/qemu/target/i386/misc_helper.c +++ b/qemu/target/i386/misc_helper.c @@ -732,3 +732,12 @@ void helper_wrpkru(CPUX86State *env, uint32_t ecx, uint64_t val) env->pkru = val; tlb_flush(cs); } + +void helper_uc_exit(CPUX86State *env) +{ + X86CPU *cpu = env_archcpu(env); + + cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC()); + + do_hlt(cpu); +} \ No newline at end of file diff --git a/qemu/target/i386/translate.c b/qemu/target/i386/translate.c index 8278774a58..d6232c4c7c 100644 --- a/qemu/target/i386/translate.c +++ b/qemu/target/i386/translate.c @@ -4803,16 +4803,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) s->uc = env->uc; - // Unicorn: end address tells us to stop emulation - if (uc_addr_is_exit(env->uc, s->pc)) { - // imitate the HLT instruction - gen_update_cc_op(s); - gen_sync_pc(tcg_ctx, pc_start - s->cs_base); - gen_helper_hlt(tcg_ctx, tcg_ctx->cpu_env, tcg_const_i32(tcg_ctx, s->pc - pc_start)); - s->base.is_jmp = DISAS_NORETURN; - return s->pc; - } - // Unicorn: callback might need to access to EFLAGS, // or want to stop emulation immediately if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, pc_start)) { @@ -9385,6 +9375,12 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) DisasContext *dc = container_of(dcbase, DisasContext, base); target_ulong pc_next; + // Unicorn: end address tells us to stop emulation + if (uc_addr_is_exit(((CPUX86State *)cpu->env_ptr)->uc, dcbase->pc_next)) { + dc->base.is_jmp = DISAS_UC_EXIT; + return; + } + pc_next = disas_insn(dc, cpu); if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) { @@ -9416,10 +9412,21 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) { DisasContext *dc = container_of(dcbase, DisasContext, base); + TCGContext *tcg_ctx = dc->uc->tcg_ctx; - if (dc->base.is_jmp == DISAS_TOO_MANY) { + switch (dc->base.is_jmp) { + case DISAS_TOO_MANY: gen_jmp_im(dc, dc->base.pc_next - dc->cs_base); gen_eob(dc); + break; + case DISAS_UC_EXIT: + // imitate the HLT instruction + gen_update_cc_op(dc); + gen_jmp_im(dc, dc->base.pc_next - dc->cs_base); + gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env); + break; + default: + break; // suppress compiler warnings } } diff --git a/qemu/target/m68k/translate.c b/qemu/target/m68k/translate.c index 5b9a74ce2b..d1948f3ed0 100644 --- a/qemu/target/m68k/translate.c +++ b/qemu/target/m68k/translate.c @@ -6325,7 +6325,7 @@ static void m68k_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) // Unicorn: end address tells us to stop emulation if (uc_addr_is_exit(uc, dc->pc)) { - gen_exception(dc, dc->pc, EXCP_HLT); + dc->base.is_jmp = DISAS_UC_EXIT; return; } @@ -6407,6 +6407,9 @@ static void m68k_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) tcg_gen_exit_tb(tcg_ctx, NULL, 0); } break; + case DISAS_UC_EXIT: + gen_exception(dc, dc->pc, EXCP_HLT); + break; default: g_assert_not_reached(); } diff --git a/qemu/target/mips/helper.h b/qemu/target/mips/helper.h index 221e78257b..d9d31ff6ef 100644 --- a/qemu/target/mips/helper.h +++ b/qemu/target/mips/helper.h @@ -1,5 +1,6 @@ DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64) +DEF_HELPER_1(uc_exit, void, env) DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int) DEF_HELPER_2(raise_exception, noreturn, env, i32) diff --git a/qemu/target/mips/op_helper.c b/qemu/target/mips/op_helper.c index 9802b9cebd..ead23fc1d5 100644 --- a/qemu/target/mips/op_helper.c +++ b/qemu/target/mips/op_helper.c @@ -1076,6 +1076,19 @@ void helper_wait(CPUMIPSState *env) raise_exception(env, EXCP_HLT); } +void helper_uc_exit(CPUMIPSState *env) +{ + CPUState *cs = env_cpu(env); + + cs->halted = 1; + cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); + /* + * Last instruction in the block, PC was updated before + * - no need to recover PC and icount. + */ + raise_exception(env, EXCP_HLT); +} + void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr) diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index 3fab57b251..40b280a44a 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -30942,9 +30942,7 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) // Unicorn: end address tells us to stop emulation if (uc_addr_is_exit(uc, ctx->base.pc_next)) { - // raise a special interrupt to quit - gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env); - ctx->base.is_jmp = DISAS_NORETURN; + ctx->base.is_jmp = DISAS_UC_EXIT; return; } @@ -31053,7 +31051,7 @@ static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) DisasContext *ctx = container_of(dcbase, DisasContext, base); TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) { + if (ctx->base.singlestep_enabled && (ctx->base.is_jmp == DISAS_NORETURN || ctx->base.is_jmp == DISAS_UC_EXIT)) { save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT); gen_helper_raise_exception_debug(tcg_ctx, tcg_ctx->cpu_env); } else { @@ -31072,6 +31070,9 @@ static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) break; case DISAS_NORETURN: break; + case DISAS_UC_EXIT: + gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env); + break; default: g_assert_not_reached(); } diff --git a/qemu/target/ppc/translate.c b/qemu/target/ppc/translate.c index 0b3e5c8c08..cac155fe33 100644 --- a/qemu/target/ppc/translate.c +++ b/qemu/target/ppc/translate.c @@ -3727,6 +3727,22 @@ static void gen_wait(DisasContext *ctx) gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); } +static void gen_uc_exit(DisasContext *ctx) +{ + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + TCGv_i32 t0 = tcg_const_i32(tcg_ctx, 1); +#ifdef _MSC_VER + tcg_gen_st_i32(tcg_ctx, t0, tcg_ctx->cpu_env, + 0 - offsetof(PowerPCCPU, env) + offsetof(CPUState, halted)); +#else + tcg_gen_st_i32(tcg_ctx, t0, tcg_ctx->cpu_env, + -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted)); +#endif + tcg_temp_free_i32(tcg_ctx, t0); + /* Stop translation, as the CPU is supposed to sleep from now */ + gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next); +} + #if defined(TARGET_PPC64) static void gen_doze(DisasContext *ctx) { @@ -7627,8 +7643,7 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) // Unicorn: end address tells us to stop emulation if (uc_addr_is_exit(uc, ctx->base.pc_next)) { - gen_wait(ctx); - dcbase->is_jmp = DISAS_NORETURN; + dcbase->is_jmp = DISAS_UC_EXIT; return; } @@ -7720,6 +7735,10 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) DisasContext *ctx = container_of(dcbase, DisasContext, base); TCGContext *tcg_ctx = cs->uc->tcg_ctx; + if (dcbase->is_jmp == DISAS_UC_EXIT) { + gen_uc_exit(ctx); + return; + } if (ctx->exception == POWERPC_EXCP_NONE) { gen_goto_tb(ctx, 0, ctx->base.pc_next); diff --git a/qemu/target/riscv/helper.h b/qemu/target/riscv/helper.h index 32e483860f..87e3c20b4c 100644 --- a/qemu/target/riscv/helper.h +++ b/qemu/target/riscv/helper.h @@ -1,6 +1,6 @@ DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64) -DEF_HELPER_1(uc_riscv_exit, void, env) +DEF_HELPER_1(uc_exit, void, env) /* Exceptions */ DEF_HELPER_2(raise_exception, noreturn, env, i32) diff --git a/qemu/target/riscv/op_helper.c b/qemu/target/riscv/op_helper.c index 5afb2ce881..ea149482d6 100644 --- a/qemu/target/riscv/op_helper.c +++ b/qemu/target/riscv/op_helper.c @@ -202,7 +202,7 @@ void helper_tlb_flush(CPURISCVState *env) } } -void helper_uc_riscv_exit(CPURISCVState *env) +void helper_uc_exit(CPURISCVState *env) { CPUState *cs = env_cpu(env); diff --git a/qemu/target/riscv/translate.c b/qemu/target/riscv/translate.c index 792bc12fd0..e7e8c80238 100644 --- a/qemu/target/riscv/translate.c +++ b/qemu/target/riscv/translate.c @@ -34,11 +34,6 @@ #include "exec/gen-icount.h" -/* - * Unicorn: Special disas state for exiting in the middle of tb. - */ -#define DISAS_UC_EXIT DISAS_TARGET_6 - typedef struct DisasContext { DisasContextBase base; /* pc_succ_insn points to the instruction following base.pc_next */ @@ -912,7 +907,7 @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) break; case DISAS_UC_EXIT: tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc, ctx->base.pc_next); - gen_helper_uc_riscv_exit(ctx->uc->tcg_ctx, ctx->uc->tcg_ctx->cpu_env); + gen_helper_uc_exit(ctx->uc->tcg_ctx, ctx->uc->tcg_ctx->cpu_env); break; default: g_assert_not_reached(); diff --git a/qemu/target/s390x/excp_helper.c b/qemu/target/s390x/excp_helper.c index a91c407c9e..917505eed7 100644 --- a/qemu/target/s390x/excp_helper.c +++ b/qemu/target/s390x/excp_helper.c @@ -599,7 +599,7 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr, tcg_s390_program_interrupt(env, PGM_SPECIFICATION, retaddr); } -void helper_uc_s390x_exit(CPUS390XState *env) +void helper_uc_exit(CPUS390XState *env) { CPUState *cs = env_cpu(env); diff --git a/qemu/target/s390x/helper.h b/qemu/target/s390x/helper.h index abd8dd2a97..0549a2b5aa 100644 --- a/qemu/target/s390x/helper.h +++ b/qemu/target/s390x/helper.h @@ -1,6 +1,6 @@ DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64) -DEF_HELPER_1(uc_s390x_exit, void, env) +DEF_HELPER_1(uc_exit, void, env) DEF_HELPER_2(exception, noreturn, env, i32) DEF_HELPER_2(data_exception, noreturn, env, i32) diff --git a/qemu/target/s390x/translate.c b/qemu/target/s390x/translate.c index e41a3b73b0..b0834f3ec9 100644 --- a/qemu/target/s390x/translate.c +++ b/qemu/target/s390x/translate.c @@ -1203,8 +1203,6 @@ typedef struct { /* We are exiting the TB to the main loop. */ #define DISAS_PC_STALE_NOCHAIN DISAS_TARGET_4 -#define DISAS_UNICORN_HALT DISAS_TARGET_11 - /* Instruction flags */ #define IF_AFP1 0x0001 /* r1 is a fp reg for HFP/FPS instructions */ #define IF_AFP2 0x0002 /* r2 is a fp reg for HFP/FPS instructions */ @@ -6882,7 +6880,8 @@ static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) // Unicorn: end address tells us to stop emulation if (uc_addr_is_exit(dc->uc, dcbase->pc_next)) { // imitate PGM exception to halt emulation - dcbase->is_jmp = DISAS_UNICORN_HALT; + dcbase->is_jmp = DISAS_UC_EXIT; + return; } else { dc->base.is_jmp = translate_one(env, dc); if (dc->base.is_jmp == DISAS_NEXT) { @@ -6902,11 +6901,11 @@ static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) TCGContext *tcg_ctx = dc->uc->tcg_ctx; switch (dc->base.is_jmp) { - case DISAS_UNICORN_HALT: + case DISAS_UC_EXIT: tcg_gen_insn_start(tcg_ctx, dc->base.pc_next, 0, 0); update_psw_addr(dc); update_cc_op(dc); - gen_helper_uc_s390x_exit(tcg_ctx, tcg_ctx->cpu_env); + gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env); break; case DISAS_GOTO_TB: case DISAS_NORETURN: diff --git a/qemu/target/sparc/helper.c b/qemu/target/sparc/helper.c index bb8687437a..224769c084 100644 --- a/qemu/target/sparc/helper.c +++ b/qemu/target/sparc/helper.c @@ -245,3 +245,12 @@ void helper_power_down(CPUSPARCState *env) cpu_loop_exit(cs); } #endif + +void helper_uc_exit(CPUSPARCState *env) +{ + CPUState *cs = env_cpu(env); + + cs->halted = 1; + cs->exception_index = EXCP_HLT; + cpu_loop_exit(cs); +} diff --git a/qemu/target/sparc/helper.h b/qemu/target/sparc/helper.h index 69924307ee..8cf226c491 100644 --- a/qemu/target/sparc/helper.h +++ b/qemu/target/sparc/helper.h @@ -1,5 +1,6 @@ DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64) +DEF_HELPER_1(uc_exit, void, env) #ifndef TARGET_SPARC64 DEF_HELPER_1(rett, void, env) diff --git a/qemu/target/sparc/translate.c b/qemu/target/sparc/translate.c index 95b24ab649..143958bb44 100644 --- a/qemu/target/sparc/translate.c +++ b/qemu/target/sparc/translate.c @@ -5952,10 +5952,7 @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) // Unicorn: end address tells us to stop emulation if (uc_addr_is_exit(uc, dc->pc)) { -#ifndef TARGET_SPARC64 - gen_helper_power_down(tcg_ctx, tcg_ctx->cpu_env); -#endif - dcbase->is_jmp = DISAS_NORETURN; + dcbase->is_jmp = DISAS_UC_EXIT; return; } @@ -6012,6 +6009,10 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) save_state(dc); tcg_gen_exit_tb(tcg_ctx, NULL, 0); break; + + case DISAS_UC_EXIT: + gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env); + break; default: g_assert_not_reached(); diff --git a/qemu/target/tricore/helper.h b/qemu/target/tricore/helper.h index e0712597d9..efc20c06ae 100644 --- a/qemu/target/tricore/helper.h +++ b/qemu/target/tricore/helper.h @@ -22,7 +22,7 @@ DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64) -DEF_HELPER_1(uc_tricore_exit,void, env) +DEF_HELPER_1(uc_exit, void, env) /* Arithmetic */ DEF_HELPER_3(add_ssov, i32, env, i32, i32) diff --git a/qemu/target/tricore/op_helper.c b/qemu/target/tricore/op_helper.c index 6bb7b3a028..dc1d56c0aa 100644 --- a/qemu/target/tricore/op_helper.c +++ b/qemu/target/tricore/op_helper.c @@ -2794,7 +2794,7 @@ uint32_t helper_psw_read(CPUTriCoreState *env) return psw_read(env); } -void helper_uc_tricore_exit(CPUTriCoreState *env) +void helper_uc_exit(CPUTriCoreState *env) { CPUState *cs = env_cpu(env); diff --git a/qemu/target/tricore/translate.c b/qemu/target/tricore/translate.c index 75188b8be6..d26842372c 100644 --- a/qemu/target/tricore/translate.c +++ b/qemu/target/tricore/translate.c @@ -33,11 +33,6 @@ #include "exec/translator.h" #include "exec/gen-icount.h" -/* - * Unicorn: Special disas state for exiting in the middle of tb. - */ -#define DISAS_UC_EXIT DISAS_TARGET_6 - static const char *regnames_a[] = { "a0" , "a1" , "a2" , "a3" , "a4" , "a5" , "a6" , "a7" , "a8" , "a9" , "sp" , "a11" , @@ -9287,8 +9282,7 @@ static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) gen_goto_tb(ctx, 0, ctx->base.pc_next); break; case DISAS_UC_EXIT: - gen_save_pc(ctx, ctx->base.pc_next); - gen_helper_uc_tricore_exit(ctx->uc->tcg_ctx, ctx->uc->tcg_ctx->cpu_env); + gen_helper_uc_exit(ctx->uc->tcg_ctx, ctx->uc->tcg_ctx->cpu_env); break; case DISAS_NORETURN: break; diff --git a/qemu/tricore.h b/qemu/tricore.h index 937eb5d257..4cfcf7708b 100644 --- a/qemu/tricore.h +++ b/qemu/tricore.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_tricore #define helper_stqcx_le_parallel helper_stqcx_le_parallel_tricore #define helper_stqcx_be_parallel helper_stqcx_be_parallel_tricore +#define helper_uc_exit helper_uc_exit_tricore #define helper_fadd helper_fadd_tricore #define helper_fsub helper_fsub_tricore #define helper_fmul helper_fmul_tricore @@ -1303,5 +1304,4 @@ #define helper_pack helper_pack_tricore #define gen_intermediate_code gen_intermediate_code_tricore #define restore_state_to_opc restore_state_to_opc_tricore -#define helper_uc_tricore_exit helper_uc_tricore_exit_tricore #endif diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 637b88524a..ff8ad359e7 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -1294,6 +1294,7 @@ #define tlb_reset_dirty_by_vaddr tlb_reset_dirty_by_vaddr_x86_64 #define helper_stqcx_le_parallel helper_stqcx_le_parallel_x86_64 #define helper_stqcx_be_parallel helper_stqcx_be_parallel_x86_64 +#define helper_uc_exit helper_uc_exit_x86_64 #define cpu_get_tsc cpu_get_tsc_x86_64 #define x86_cpu_get_memory_mapping x86_cpu_get_memory_mapping_x86_64 #define cpu_x86_update_dr7 cpu_x86_update_dr7_x86_64 diff --git a/symbols.sh b/symbols.sh index a68ece0d09..f896ef72fd 100755 --- a/symbols.sh +++ b/symbols.sh @@ -1294,6 +1294,7 @@ gen_helper_cpsr_write \ tlb_reset_dirty_by_vaddr \ helper_stqcx_le_parallel \ helper_stqcx_be_parallel \ +helper_uc_exit \ " x86_64_SYMBOLS=" @@ -2353,7 +2354,6 @@ helper_usat \ helper_usat16 \ helper_setend \ helper_wfi \ -helper_uc_exit \ helper_wfe \ helper_yield \ helper_exception_internal \ @@ -3136,7 +3136,6 @@ helper_usat \ helper_usat16 \ helper_setend \ helper_wfi \ -helper_uc_exit \ helper_wfe \ helper_yield \ helper_exception_internal \ @@ -4377,7 +4376,6 @@ helper_fcvt_d_wu \ helper_fclass_d \ riscv_raise_exception \ helper_raise_exception \ -helper_uc_riscv_exit \ helper_csrrw \ helper_csrrs \ helper_csrrc \ @@ -6535,8 +6533,7 @@ do_store_fpscr ppc64_SYMBOLS=${ppc_SYMBOLS} -s390x_SYMBOLS="helper_uc_s390x_exit \ -tcg_s390_tod_updated \ +s390x_SYMBOLS="tcg_s390_tod_updated \ tcg_s390_program_interrupt \ tcg_s390_data_exception \ " @@ -6551,7 +6548,6 @@ helper_fmsub \ helper_pack \ gen_intermediate_code \ restore_state_to_opc \ -helper_uc_tricore_exit \ " ARCHS="x86_64 arm aarch64 riscv32 riscv64 mips mipsel mips64 mips64el sparc sparc64 m68k ppc ppc64 s390x tricore" From 30d6f3781141aaf741b8bdae5b208ae5eb38e114 Mon Sep 17 00:00:00 2001 From: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> Date: Mon, 29 Sep 2025 18:05:37 +0800 Subject: [PATCH 3/5] weird sparc behavior, but it was like this previously. keep it for now Signed-off-by: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> --- qemu/target/sparc/helper.c | 4 +++- qemu/target/sparc/translate.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/qemu/target/sparc/helper.c b/qemu/target/sparc/helper.c index 224769c084..fd838cb25b 100644 --- a/qemu/target/sparc/helper.c +++ b/qemu/target/sparc/helper.c @@ -244,7 +244,6 @@ void helper_power_down(CPUSPARCState *env) env->npc = env->pc + 4; cpu_loop_exit(cs); } -#endif void helper_uc_exit(CPUSPARCState *env) { @@ -252,5 +251,8 @@ void helper_uc_exit(CPUSPARCState *env) cs->halted = 1; cs->exception_index = EXCP_HLT; + env->pc = env->npc; + env->npc = env->pc + 4; cpu_loop_exit(cs); } +#endif \ No newline at end of file diff --git a/qemu/target/sparc/translate.c b/qemu/target/sparc/translate.c index 143958bb44..ce51193130 100644 --- a/qemu/target/sparc/translate.c +++ b/qemu/target/sparc/translate.c @@ -6011,8 +6011,10 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) break; case DISAS_UC_EXIT: + #ifndef TARGET_SPARC64 gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env); break; + #endif default: g_assert_not_reached(); From 6956204f1e92c99b45c69fc58796a59ce3a612dc Mon Sep 17 00:00:00 2001 From: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> Date: Mon, 29 Sep 2025 18:06:39 +0800 Subject: [PATCH 4/5] oops Signed-off-by: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> --- qemu/target/sparc/helper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/target/sparc/helper.h b/qemu/target/sparc/helper.h index 8cf226c491..4179da45bd 100644 --- a/qemu/target/sparc/helper.h +++ b/qemu/target/sparc/helper.h @@ -1,12 +1,12 @@ DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64) -DEF_HELPER_1(uc_exit, void, env) #ifndef TARGET_SPARC64 DEF_HELPER_1(rett, void, env) DEF_HELPER_2(wrpsr, void, env, tl) DEF_HELPER_1(rdpsr, tl, env) DEF_HELPER_1(power_down, void, env) +DEF_HELPER_1(uc_exit, void, env) #else DEF_HELPER_FLAGS_2(wrpil, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_2(wrgl, void, env, tl) From 02ba76a0c8fdc1e36f827929dc3bee5ca0a8f341 Mon Sep 17 00:00:00 2001 From: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> Date: Mon, 29 Sep 2025 18:21:13 +0800 Subject: [PATCH 5/5] fix sparc again Signed-off-by: appleflyerv3 <164886846+appleflyerv3@users.noreply.github.com> --- qemu/target/sparc/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/target/sparc/translate.c b/qemu/target/sparc/translate.c index ce51193130..5dc5c6760d 100644 --- a/qemu/target/sparc/translate.c +++ b/qemu/target/sparc/translate.c @@ -6013,8 +6013,8 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) case DISAS_UC_EXIT: #ifndef TARGET_SPARC64 gen_helper_uc_exit(tcg_ctx, tcg_ctx->cpu_env); - break; #endif + break; default: g_assert_not_reached();