mirror of https://github.com/xemu-project/xemu.git
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;
|
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,
|
void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
|
||||||
TranslationBlock *tb)
|
TranslationBlock *tb)
|
||||||
{
|
{
|
||||||
|
@ -11398,66 +11464,7 @@ void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
|
||||||
gen_io_end();
|
gen_io_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->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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gen_tb_end(tb, dc->base.num_insns);
|
gen_tb_end(tb, dc->base.num_insns);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue