diff options
Diffstat (limited to 'target/arm')
-rw-r--r-- | target/arm/translate-a64.c | 5 | ||||
-rw-r--r-- | target/arm/translate.c | 21 | ||||
-rw-r--r-- | target/arm/translate.h | 4 |
3 files changed, 22 insertions, 8 deletions
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index a82ab49c94..860e279658 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -379,7 +379,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest) } else if (s->singlestep_enabled) { gen_exception_internal(EXCP_DEBUG); } else { - tcg_gen_exit_tb(0); + tcg_gen_lookup_and_goto_ptr(cpu_pc); s->is_jmp = DISAS_TB_JUMP; } } @@ -11367,8 +11367,7 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb) gen_a64_set_pc_im(dc->pc); /* fall through */ case DISAS_JUMP: - /* indicate that the hash table must be used to find the next TB */ - tcg_gen_exit_tb(0); + tcg_gen_lookup_and_goto_ptr(cpu_pc); break; case DISAS_TB_JUMP: case DISAS_EXC: diff --git a/target/arm/translate.c b/target/arm/translate.c index ae6646c05b..0862f9e4aa 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -1182,7 +1182,7 @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp) gen_set_condexec(s); gen_set_pc_im(s, s->pc - offset); gen_exception_internal(excp); - s->is_jmp = DISAS_JUMP; + s->is_jmp = DISAS_EXC; } static void gen_exception_insn(DisasContext *s, int offset, int excp, @@ -1191,14 +1191,14 @@ static void gen_exception_insn(DisasContext *s, int offset, int excp, gen_set_condexec(s); gen_set_pc_im(s, s->pc - offset); gen_exception(excp, syn, target_el); - s->is_jmp = DISAS_JUMP; + s->is_jmp = DISAS_EXC; } /* Force a TB lookup after an instruction that changes the CPU state. */ static inline void gen_lookup_tb(DisasContext *s) { tcg_gen_movi_i32(cpu_R[15], s->pc & ~1); - s->is_jmp = DISAS_JUMP; + s->is_jmp = DISAS_EXIT; } static inline void gen_hlt(DisasContext *s, int imm) @@ -4150,7 +4150,15 @@ static inline bool use_goto_tb(DisasContext *s, target_ulong dest) #endif } -static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest) +static void gen_goto_ptr(void) +{ + TCGv addr = tcg_temp_new(); + tcg_gen_extu_i32_tl(addr, cpu_R[15]); + tcg_gen_lookup_and_goto_ptr(addr); + tcg_temp_free(addr); +} + +static void gen_goto_tb(DisasContext *s, int n, target_ulong dest) { if (use_goto_tb(s, dest)) { tcg_gen_goto_tb(n); @@ -4158,7 +4166,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest) tcg_gen_exit_tb((uintptr_t)s->tb + n); } else { gen_set_pc_im(s, dest); - tcg_gen_exit_tb(0); + gen_goto_ptr(); } } @@ -12091,11 +12099,14 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) gen_set_pc_im(dc, dc->pc); /* fall through */ case DISAS_JUMP: + gen_goto_ptr(); + break; default: /* indicate that the hash table must be used to find the next TB */ tcg_gen_exit_tb(0); break; case DISAS_TB_JUMP: + case DISAS_EXC: /* nothing more to generate */ break; case DISAS_WFI: diff --git a/target/arm/translate.h b/target/arm/translate.h index 6b2cc34c33..15d383d9af 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -139,6 +139,10 @@ static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn) * custom end-of-TB code) */ #define DISAS_BX_EXCRET 11 +/* For instructions which want an immediate exit to the main loop, + * as opposed to attempting to use lookup_and_goto_ptr. + */ +#define DISAS_EXIT 12 #ifdef TARGET_AARCH64 void a64_translate_init(void); |