summaryrefslogtreecommitdiff
path: root/target/arm/translate-a64.c
diff options
context:
space:
mode:
authorLluís Vilanova <vilanova@ac.upc.edu>2017-07-14 12:46:25 +0300
committerRichard Henderson <richard.henderson@linaro.org>2017-09-06 08:06:48 -0700
commitbe4079641f1bc755fc5d3ff194cf505c506227d8 (patch)
tree915ca05b62e18a10dbd23dc3a98d77d741adf9d4 /target/arm/translate-a64.c
parent70d3c035ae36a2c5c0f991ba958526127c92bb67 (diff)
downloadqemu-be4079641f1bc755fc5d3ff194cf505c506227d8.zip
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>
Diffstat (limited to 'target/arm/translate-a64.c')
-rw-r--r--target/arm/translate-a64.c127
1 files changed, 67 insertions, 60 deletions
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index f959f4469a..723e86c976 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -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);