提交 be407964 编写于 作者: L Lluís Vilanova 提交者: Richard Henderson

target/arm: [tcg,a64] Port to tb_stop

Incrementally paves the way towards using the generic instruction translation
loop.
Reviewed-by: NEmilio G. Cota <cota@braap.org>
Reviewed-by: NRichard Henderson <rth@twiddle.net>
Signed-off-by: NLluís Vilanova <vilanova@ac.upc.edu>
Message-Id: <150002558503.22386.1149037590886263349.stgit@frigg.lan>
Signed-off-by: NRichard Henderson <rth@twiddle.net>
上级 70d3c035
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册