mirror of
https://github.com/xemu-project/xemu.git
synced 2025-01-05 19:19:53 +00:00
target/arm: [tcg,a64] Port to tb_stop
Incrementally paves the way towards using the generic instruction translation loop. Reviewed-by: Emilio G. Cota <cota@braap.org> Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> Message-Id: <150002558503.22386.1149037590886263349.stgit@frigg.lan> Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
70d3c035ae
commit
be4079641f
@ -11327,6 +11327,72 @@ 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);
|
||||
|
||||
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->pc);
|
||||
/* fall through */
|
||||
case DISAS_JUMP:
|
||||
if (dc->base.singlestep_enabled) {
|
||||
gen_exception_internal(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->pc);
|
||||
/* fall through */
|
||||
case DISAS_JUMP:
|
||||
tcg_gen_lookup_and_goto_ptr(cpu_pc);
|
||||
break;
|
||||
case DISAS_EXIT:
|
||||
tcg_gen_exit_tb(0);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
case DISAS_SWI:
|
||||
break;
|
||||
case DISAS_WFE:
|
||||
gen_a64_set_pc_im(dc->pc);
|
||||
gen_helper_wfe(cpu_env);
|
||||
break;
|
||||
case DISAS_YIELD:
|
||||
gen_a64_set_pc_im(dc->pc);
|
||||
gen_helper_yield(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->pc);
|
||||
gen_helper_wfi(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(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
|
||||
TranslationBlock *tb)
|
||||
{
|
||||
@ -11398,66 +11464,7 @@ void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
|
||||
gen_io_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->pc);
|
||||
/* fall through */
|
||||
case DISAS_JUMP:
|
||||
if (cs->singlestep_enabled) {
|
||||
gen_exception_internal(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(cpu_pc);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
case DISAS_SWI:
|
||||
break;
|
||||
case DISAS_WFE:
|
||||
gen_a64_set_pc_im(dc->pc);
|
||||
gen_helper_wfe(cpu_env);
|
||||
break;
|
||||
case DISAS_YIELD:
|
||||
gen_a64_set_pc_im(dc->pc);
|
||||
gen_helper_yield(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->pc);
|
||||
gen_helper_wfi(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(0);
|
||||
break;
|
||||
case DISAS_UPDATE:
|
||||
gen_a64_set_pc_im(dc->pc);
|
||||
/* fall through */
|
||||
case DISAS_EXIT:
|
||||
default:
|
||||
tcg_gen_exit_tb(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
aarch64_tr_tb_stop(&dc->base, cs);
|
||||
|
||||
gen_tb_end(tb, dc->base.num_insns);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user