[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 04/14] target/sh4: move DELAY_SLOT_TRUE flag into
From: |
Aurelien Jarno |
Subject: |
[Qemu-devel] [PATCH v2 04/14] target/sh4: move DELAY_SLOT_TRUE flag into a separate global |
Date: |
Sat, 6 May 2017 13:14:21 +0200 |
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.
Signed-off-by: Aurelien Jarno <address@hidden>
---
target/sh4/cpu.h | 10 ++--------
target/sh4/helper.c | 2 +-
target/sh4/translate.c | 22 +++++++++++++---------
3 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index da8d15f1b9..faab3012f9 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -92,13 +92,6 @@
#define DELAY_SLOT (1 << 0)
#define DELAY_SLOT_CONDITIONAL (1 << 1)
-#define DELAY_SLOT_TRUE (1 << 2)
-/* The dynamic value of the DELAY_SLOT_TRUE flag determines whether the jump
- * after the delay slot should be taken or not. It is calculated from SR_T.
- *
- * It is unclear if it is permitted to modify the SR_T flag in a delay slot.
- * The use of DELAY_SLOT_TRUE flag makes us accept such SR_T modification.
- */
typedef struct tlb_t {
uint32_t vpn; /* virtual page number */
@@ -148,7 +141,8 @@ typedef struct CPUSH4State {
uint32_t sgr; /* saved global register 15 */
uint32_t dbr; /* debug base register */
uint32_t pc; /* program counter */
- uint32_t delayed_pc; /* target of delayed jump */
+ uint32_t delayed_pc; /* target of delayed branch */
+ uint32_t delayed_cond; /* condition of delayed branch */
uint32_t mach; /* multiply and accumulate high */
uint32_t macl; /* multiply and accumulate low */
uint32_t pr; /* procedure register */
diff --git a/target/sh4/helper.c b/target/sh4/helper.c
index 71bb49a670..8f8ce81401 100644
--- a/target/sh4/helper.c
+++ b/target/sh4/helper.c
@@ -168,7 +168,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
/* Branch instruction should be executed again before delay slot. */
env->spc -= 2;
/* Clear flags for exception/interrupt routine. */
- env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL | DELAY_SLOT_TRUE);
+ env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
}
if (do_exp) {
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)
--
2.11.0
- Re: [Qemu-devel] [PATCH v2 08/14] target/sh4: fold ctx->bstate = BS_BRANCH into gen_conditional_jump, (continued)
- [Qemu-devel] [PATCH v2 10/14] target/sh4: optimize gen_write_sr using extract op, Aurelien Jarno, 2017/05/06
- [Qemu-devel] [PATCH v2 12/14] target/sh4: implement tas.b using atomic helper, Aurelien Jarno, 2017/05/06
- [Qemu-devel] [PATCH v2 13/14] target/sh4: movua.l is an SH4-A only instruction, Aurelien Jarno, 2017/05/06
- [Qemu-devel] [PATCH v2 07/14] target/sh4: only save flags state at the end of the TB, Aurelien Jarno, 2017/05/06
- [Qemu-devel] [PATCH v2 04/14] target/sh4: move DELAY_SLOT_TRUE flag into a separate global,
Aurelien Jarno <=
- [Qemu-devel] [PATCH v2 14/14] target/sh4: trap unaligned accesses, Aurelien Jarno, 2017/05/06
- [Qemu-devel] [PATCH v2 01/14] target/sh4: split ctx->flags into ctx->tbflags and ctx->envflags, Aurelien Jarno, 2017/05/06