summaryrefslogtreecommitdiff
path: root/target/sh4/translate.c
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2017-05-01 23:20:43 +0200
committerAurelien Jarno <aurelien@aurel32.net>2017-05-13 11:17:29 +0200
commit47b9f4d5a4013938134ca678c338906e798a61d7 (patch)
treeeb14ff757bc9eb0bbd345ba21d29fa2d41a244e5 /target/sh4/translate.c
parent24b09d9d8ba589402f9c8e0d8d36bcf5c4a933da (diff)
downloadqemu-47b9f4d5a4013938134ca678c338906e798a61d7.tar.gz
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.c22
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)