mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-11 06:05:38 +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;
|
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,
|
void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
|
||||||
TranslationBlock *tb)
|
TranslationBlock *tb)
|
||||||
{
|
{
|
||||||
|
@ -11676,66 +11743,7 @@ void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
|
||||||
//}
|
//}
|
||||||
|
|
||||||
tb_end:
|
tb_end:
|
||||||
if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
|
aarch64_tr_tb_stop(&dc->base, cs);
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gen_tb_end(tcg_ctx, tb, dc->base.num_insns);
|
gen_tb_end(tcg_ctx, tb, dc->base.num_insns);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue