mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-11 03:25:33 +00:00
target/arm: [tcg,a64] Port to tb_stop
Incrementally paves the way towards using the generic instruction translation loop. Backports commit be4079641f1bc755fc5d3ff194cf505c506227d8 from qemu
This commit is contained in:
parent
d8def0cdb5
commit
7a02cb360c
|
@ -11576,6 +11576,73 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
|
|||
dc->base.pc_next = dc->pc;
|
||||
}
|
||||
|
||||
static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
||||
{
|
||||
DisasContext *dc = container_of(dcbase, DisasContext, base);
|
||||
TCGContext *tcg_ctx = cpu->uc->tcg_ctx;
|
||||
|
||||
if (unlikely(dc->base.singlestep_enabled || dc->ss_active)) {
|
||||
/* Note that this means single stepping WFI doesn't halt the CPU.
|
||||
* For conditional branch insns this is harmless unreachable code as
|
||||
* gen_goto_tb() has already handled emitting the debug exception
|
||||
* (and thus a tb-jump is not possible when singlestepping).
|
||||
*/
|
||||
switch (dc->base.is_jmp) {
|
||||
default:
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
/* fall through */
|
||||
case DISAS_JUMP:
|
||||
if (dc->base.singlestep_enabled) {
|
||||
gen_exception_internal(dc, EXCP_DEBUG);
|
||||
} else {
|
||||
gen_step_complete_exception(dc);
|
||||
}
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (dc->base.is_jmp) {
|
||||
case DISAS_NEXT:
|
||||
case DISAS_TOO_MANY:
|
||||
gen_goto_tb(dc, 1, dc->pc);
|
||||
break;
|
||||
default:
|
||||
case DISAS_UPDATE:
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
/* fall through */
|
||||
case DISAS_JUMP:
|
||||
tcg_gen_lookup_and_goto_ptr(tcg_ctx, tcg_ctx->cpu_pc);
|
||||
break;
|
||||
case DISAS_EXIT:
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
case DISAS_SWI:
|
||||
break;
|
||||
case DISAS_WFE:
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
gen_helper_wfe(tcg_ctx, tcg_ctx->cpu_env);
|
||||
break;
|
||||
case DISAS_YIELD:
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
gen_helper_yield(tcg_ctx, tcg_ctx->cpu_env);
|
||||
break;
|
||||
case DISAS_WFI:
|
||||
/* This is a special case because we don't want to just halt the CPU
|
||||
* if trying to debug across a WFI.
|
||||
*/
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
gen_helper_wfi(tcg_ctx, tcg_ctx->cpu_env);
|
||||
/* 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, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
|
||||
TranslationBlock *tb)
|
||||
{
|
||||
|
@ -11676,66 +11743,7 @@ void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
|
|||
//}
|
||||
|
||||
tb_end:
|
||||
if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
|
||||
/* Note that this means single stepping WFI doesn't halt the CPU.
|
||||
* For conditional branch insns this is harmless unreachable code as
|
||||
* gen_goto_tb() has already handled emitting the debug exception
|
||||
* (and thus a tb-jump is not possible when singlestepping).
|
||||
*/
|
||||
switch (dc->base.is_jmp) {
|
||||
default:
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
/* fall through */
|
||||
case DISAS_JUMP:
|
||||
if (cs->singlestep_enabled) {
|
||||
gen_exception_internal(dc, EXCP_DEBUG);
|
||||
} else {
|
||||
gen_step_complete_exception(dc);
|
||||
}
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (dc->base.is_jmp) {
|
||||
case DISAS_NEXT:
|
||||
case DISAS_TOO_MANY:
|
||||
gen_goto_tb(dc, 1, dc->pc);
|
||||
break;
|
||||
case DISAS_JUMP:
|
||||
tcg_gen_lookup_and_goto_ptr(tcg_ctx, tcg_ctx->cpu_pc);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
case DISAS_SWI:
|
||||
break;
|
||||
case DISAS_WFE:
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
gen_helper_wfe(tcg_ctx, tcg_ctx->cpu_env);
|
||||
break;
|
||||
case DISAS_YIELD:
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
gen_helper_yield(tcg_ctx, tcg_ctx->cpu_env);
|
||||
break;
|
||||
case DISAS_WFI:
|
||||
/* This is a special case because we don't want to just halt the CPU
|
||||
* if trying to debug across a WFI.
|
||||
*/
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
gen_helper_wfi(tcg_ctx, tcg_ctx->cpu_env);
|
||||
/* 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, 0);
|
||||
break;
|
||||
case DISAS_UPDATE:
|
||||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
/* fall through */
|
||||
case DISAS_EXIT:
|
||||
default:
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
aarch64_tr_tb_stop(&dc->base, cs);
|
||||
|
||||
gen_tb_end(tcg_ctx, tb, dc->base.num_insns);
|
||||
|
||||
|
|
Loading…
Reference in a new issue