From f6278ca9699dfd5df21a3f844945ec1e3122c44c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 31 Aug 2020 09:34:01 -0700 Subject: [PATCH] target/microblaze: Introduce DISAS_EXIT_NEXT, DISAS_EXIT_JUMP Like DISAS_EXIT, except we need to update cpu_pc, either to pc_next or to btarget respectively. Reviewed-by: Edgar E. Iglesias Tested-by: Edgar E. Iglesias Signed-off-by: Richard Henderson --- target/microblaze/translate.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index 8ceb04f4f0..2abef328a3 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -39,6 +39,11 @@ #define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */ #define DISAS_EXIT DISAS_TARGET_1 /* all cpu state modified dynamically */ +/* cpu state besides pc was modified dynamically; update pc to next */ +#define DISAS_EXIT_NEXT DISAS_TARGET_2 +/* cpu state besides pc was modified dynamically; update pc to btarget */ +#define DISAS_EXIT_JUMP DISAS_TARGET_3 + static TCGv_i32 cpu_R[32]; static TCGv_i32 cpu_pc; static TCGv_i32 cpu_msr; @@ -1712,8 +1717,7 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs) /* Force an exit if the per-tb cpu state has changed. */ if (dc->base.is_jmp == DISAS_NEXT && dc->cpustate_changed) { - dc->base.is_jmp = DISAS_EXIT; - tcg_gen_movi_i32(cpu_pc, dc->base.pc_next); + dc->base.is_jmp = DISAS_EXIT_NEXT; } } @@ -1734,12 +1738,14 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs) return; case DISAS_EXIT: - if (unlikely(cs->singlestep_enabled)) { - gen_raise_exception(dc, EXCP_DEBUG); - } else { - tcg_gen_exit_tb(NULL, 0); - } - return; + break; + case DISAS_EXIT_NEXT: + tcg_gen_movi_i32(cpu_pc, dc->base.pc_next); + break; + case DISAS_EXIT_JUMP: + tcg_gen_mov_i32(cpu_pc, cpu_btarget); + tcg_gen_discard_i32(cpu_btarget); + break; case DISAS_JUMP: if (dc->jmp_dest != -1 && !cs->singlestep_enabled) { @@ -1781,6 +1787,13 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs) default: g_assert_not_reached(); } + + /* Finish DISAS_EXIT_* */ + if (unlikely(cs->singlestep_enabled)) { + gen_raise_exception(dc, EXCP_DEBUG); + } else { + tcg_gen_exit_tb(NULL, 0); + } } static void mb_tr_disas_log(const DisasContextBase *dcb, CPUState *cs)