Add an option that writes back the PC, like DISAS_UPDATE_EXIT, but does not exit back to the main loop.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/arm/translate.h | 2 ++ target/arm/translate-a64.c | 3 +++ target/arm/translate.c | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/target/arm/translate.h b/target/arm/translate.h index 41d6cc8db5..dbbb167174 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -173,6 +173,8 @@ static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn) * return from cpu_tb_exec. */ #define DISAS_EXIT DISAS_TARGET_9 +/* CPU state was modified dynamically; no need to exit, but do not chain. */ +#define DISAS_UPDATE_NOCHAIN DISAS_TARGET_10 #ifdef TARGET_AARCH64 void a64_translate_init(void); diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index a793ec9ee1..943d6034de 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -14462,6 +14462,9 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_EXIT: tcg_gen_exit_tb(NULL, 0); break; + case DISAS_UPDATE_NOCHAIN: + gen_a64_set_pc_im(dc->base.pc_next); + /* fall through */ case DISAS_JUMP: tcg_gen_lookup_and_goto_ptr(); break; diff --git a/target/arm/translate.c b/target/arm/translate.c index 5a21766cce..33a26287f7 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -11420,6 +11420,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_NEXT: case DISAS_TOO_MANY: case DISAS_UPDATE_EXIT: + case DISAS_UPDATE_NOCHAIN: gen_set_pc_im(dc, dc->base.pc_next); /* fall through */ default: @@ -11443,6 +11444,9 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_TOO_MANY: gen_goto_tb(dc, 1, dc->base.pc_next); break; + case DISAS_UPDATE_NOCHAIN: + gen_set_pc_im(dc, dc->base.pc_next); + /* fall through */ case DISAS_JUMP: gen_goto_ptr(); break; -- 2.20.1