diff options
author | Sergey Fedorov <serge.fdrv@gmail.com> | 2016-04-09 01:00:23 +0300 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2016-05-12 14:06:42 -1000 |
commit | 90aa39a1cc4837360889f0e033ca25cc82100308 (patch) | |
tree | b8f857f456fec4ecd5b5931f41c7b17b52a353eb /target-sparc | |
parent | 5b053a4a28278bca606eeff7d1c0730df1b047e9 (diff) |
tcg: Allow goto_tb to any target PC in user mode
In user mode, there's only a static address translation, TBs are always
invalidated properly and direct jumps are reset when mapping change.
Thus the destination address is always valid for direct jumps and
there's no need to restrict it to the pages the TB resides in.
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Cc: Riku Voipio <riku.voipio@iki.fi>
Cc: Blue Swirl <blauwirbel@gmail.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-sparc')
-rw-r--r-- | target-sparc/translate.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 7998ff57bf..d154e3f7b6 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -303,20 +303,30 @@ static inline TCGv gen_dest_gpr(DisasContext *dc, int reg) } } +static inline bool use_goto_tb(DisasContext *s, target_ulong pc, + target_ulong npc) +{ + if (unlikely(s->singlestep)) { + return false; + } + +#ifndef CONFIG_USER_ONLY + return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) && + (npc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK); +#else + return true; +#endif +} + static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong pc, target_ulong npc) { - TranslationBlock *tb; - - tb = s->tb; - if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) && - (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) && - !s->singlestep) { + if (use_goto_tb(s, pc, npc)) { /* jump to same page: we can use a direct jump */ tcg_gen_goto_tb(tb_num); tcg_gen_movi_tl(cpu_pc, pc); tcg_gen_movi_tl(cpu_npc, npc); - tcg_gen_exit_tb((uintptr_t)tb + tb_num); + tcg_gen_exit_tb((uintptr_t)s->tb + tb_num); } else { /* jump to another page: currently not optimized */ tcg_gen_movi_tl(cpu_pc, pc); |