diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2017-05-01 23:20:43 +0200 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2017-05-13 11:17:29 +0200 |
commit | 47b9f4d5a4013938134ca678c338906e798a61d7 (patch) | |
tree | eb14ff757bc9eb0bbd345ba21d29fa2d41a244e5 /target/sh4/translate.c | |
parent | 24b09d9d8ba589402f9c8e0d8d36bcf5c4a933da (diff) |
target/sh4: move DELAY_SLOT_TRUE flag into a separate global
Instead of using one bit of the env flags to store the condition of the
next delay slot, use a separate global. It simplifies reading and
writing the flags variable and also removes some confusion between
ctx->envflags and env->flags.
Note that the global is first transfered to a temp in order to be
able to discard the global before the brcond.
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target/sh4/translate.c')
-rw-r--r-- | target/sh4/translate.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/target/sh4/translate.c b/target/sh4/translate.c index d84a7a2e6e..2e29936ad8 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -72,7 +72,7 @@ static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst; static TCGv cpu_fregs[32]; /* internal register indexes */ -static TCGv cpu_flags, cpu_delayed_pc; +static TCGv cpu_flags, cpu_delayed_pc, cpu_delayed_cond; #include "exec/gen-icount.h" @@ -147,6 +147,10 @@ void sh4_translate_init(void) cpu_delayed_pc = tcg_global_mem_new_i32(cpu_env, offsetof(CPUSH4State, delayed_pc), "_delayed_pc_"); + cpu_delayed_cond = tcg_global_mem_new_i32(cpu_env, + offsetof(CPUSH4State, + delayed_cond), + "_delayed_cond_"); cpu_ldst = tcg_global_mem_new_i32(cpu_env, offsetof(CPUSH4State, ldst), "_ldst_"); @@ -252,11 +256,12 @@ static void gen_jump(DisasContext * ctx) static inline void gen_branch_slot(uint32_t delayed_pc, int t) { - TCGLabel *label = gen_new_label(); tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc); - tcg_gen_brcondi_i32(t ? TCG_COND_EQ : TCG_COND_NE, cpu_sr_t, 0, label); - tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE); - gen_set_label(label); + if (t) { + tcg_gen_mov_i32(cpu_delayed_cond, cpu_sr_t); + } else { + tcg_gen_xori_i32(cpu_delayed_cond, cpu_sr_t, 1); + } } /* Immediate conditional jump (bt or bf) */ @@ -278,18 +283,17 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) l1 = gen_new_label(); ds = tcg_temp_new(); - tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE); + tcg_gen_mov_i32(ds, cpu_delayed_cond); + tcg_gen_discard_i32(cpu_delayed_cond); tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1); gen_goto_tb(ctx, 1, ctx->pc + 2); gen_set_label(l1); - tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE); gen_jump(ctx); } static inline void gen_store_flags(uint32_t flags) { - tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE); - tcg_gen_ori_i32(cpu_flags, cpu_flags, flags); + tcg_gen_movi_i32(cpu_flags, flags); } static inline void gen_load_fpr64(TCGv_i64 t, int reg) |