diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2020-08-31 09:34:01 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2020-09-07 12:58:08 -0700 |
commit | f6278ca9699dfd5df21a3f844945ec1e3122c44c (patch) | |
tree | f54f6f31acbc78fac61f9a330fe212a3b0e8fcca /target | |
parent | 17e777965257e19b17dfbf7c08c495f05303a860 (diff) |
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 <edgar.iglesias@xilinx.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/microblaze/translate.c | 29 |
1 files 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) |