[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 22/25] target-openrisc: Tidy handling of delayed bra
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 22/25] target-openrisc: Tidy handling of delayed branches |
Date: |
Mon, 13 Jun 2016 16:58:22 -0700 |
Signed-off-by: Richard Henderson <address@hidden>
---
target-openrisc/cpu.h | 12 +++++-------
target-openrisc/gdbstub.c | 2 +-
target-openrisc/interrupt.c | 4 ++--
target-openrisc/sys_helper.c | 2 +-
target-openrisc/translate.c | 40 ++++++++++++++++------------------------
5 files changed, 25 insertions(+), 35 deletions(-)
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 70ac481..ca5181d 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -83,9 +83,6 @@ enum {
/* Version Register */
#define SPR_VR 0xFFFF003F
-/* Internal flags, delay slot flag */
-#define D_FLAG 1
-
/* Interrupt */
#define NR_IRQS 32
@@ -304,8 +301,7 @@ typedef struct CPUOpenRISCState {
target_ulong lock_st_value;
#endif
- uint32_t flags; /* cpu_flags, we only use it for exception
- in solt so far. */
+ uint32_t dflag; /* In delay slot (boolean) */
CPU_COMMON
@@ -397,14 +393,16 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
#include "exec/cpu-all.h"
+#define TB_FLAGS_DFLAG 1
+#define TB_FLAGS_OVE SR_OVE
+
static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
target_ulong *pc,
target_ulong *cs_base, uint32_t *flags)
{
*pc = env->pc;
*cs_base = 0;
- /* D_FLAG -- branch instruction exception, OVE overflow trap enable. */
- *flags = (env->flags & D_FLAG) | (env->sr & SR_OVE);
+ *flags = env->dflag | (env->sr & SR_OVE);
}
static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
diff --git a/target-openrisc/gdbstub.c b/target-openrisc/gdbstub.c
index 2a4821f..b18c7e9 100644
--- a/target-openrisc/gdbstub.c
+++ b/target-openrisc/gdbstub.c
@@ -73,7 +73,7 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t
*mem_buf, int n)
also clear delayed branch status. */
if (env->pc != tmp) {
env->pc = tmp;
- env->flags = 0;
+ env->dflag = 0;
}
break;
diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
index 77c2d00..cfd501d 100644
--- a/target-openrisc/interrupt.c
+++ b/target-openrisc/interrupt.c
@@ -34,8 +34,8 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
CPUOpenRISCState *env = &cpu->env;
env->epcr = env->pc;
- if (env->flags & D_FLAG) {
- env->flags &= ~D_FLAG;
+ if (env->dflag) {
+ env->dflag = 0;
env->sr |= SR_DSX;
env->epcr -= 4;
}
diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c
index 1103a7b..6cccc82 100644
--- a/target-openrisc/sys_helper.c
+++ b/target-openrisc/sys_helper.c
@@ -44,7 +44,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, uint32_t spr,
target_ulong rb)
when "jumping" to the current instruction. */
if (env->pc != rb) {
env->pc = rb;
- env->flags = 0;
+ env->dflag = 0;
cpu_loop_exit(cs);
}
break;
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 3102190..95e12ef 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -42,11 +42,11 @@
typedef struct DisasContext {
TranslationBlock *tb;
target_ulong pc;
- uint32_t tb_flags, synced_flags, flags;
uint32_t is_jmp;
uint32_t mem_idx;
- int singlestep_enabled;
+ uint32_t tb_flags;
uint32_t delayed_branch;
+ bool singlestep_enabled;
} DisasContext;
static TCGv_env cpu_env;
@@ -62,7 +62,7 @@ static TCGv cpu_lock_addr;
static TCGv cpu_lock_value;
static TCGv_i32 fpcsr;
static TCGv_i64 cpu_mac; /* MACHI:MACLO */
-static TCGv_i32 env_flags;
+static TCGv_i32 cpu_dflag;
#include "exec/gen-icount.h"
void openrisc_translate_init(void)
@@ -78,9 +78,9 @@ void openrisc_translate_init(void)
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
cpu_sr = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, sr), "sr");
- env_flags = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUOpenRISCState, flags),
- "flags");
+ cpu_dflag = tcg_global_mem_new_i32(cpu_env,
+ offsetof(CPUOpenRISCState, dflag),
+ "dflag");
cpu_pc = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, pc), "pc");
cpu_ppc = tcg_global_mem_new(cpu_env,
@@ -112,15 +112,6 @@ void openrisc_translate_init(void)
}
}
-static inline void gen_sync_flags(DisasContext *dc)
-{
- /* Sync the tb dependent flag between translate and runtime. */
- if ((dc->tb_flags ^ dc->synced_flags) & D_FLAG) {
- tcg_gen_movi_tl(env_flags, dc->tb_flags & D_FLAG);
- dc->synced_flags = dc->tb_flags;
- }
-}
-
static void gen_exception(DisasContext *dc, unsigned int excp)
{
TCGv_i32 tmp = tcg_const_i32(excp);
@@ -225,8 +216,6 @@ static void gen_jump(DisasContext *dc, int32_t n26,
uint32_t reg, uint32_t op0)
}
dc->delayed_branch = 2;
- dc->tb_flags |= D_FLAG;
- gen_sync_flags(dc);
}
static void gen_ove_cy(DisasContext *dc)
@@ -1507,10 +1496,9 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct
TranslationBlock *tb)
dc->is_jmp = DISAS_NEXT;
dc->pc = pc_start;
- dc->flags = cpu->env.cpucfgr;
dc->mem_idx = cpu_mmu_index(&cpu->env, false);
- dc->synced_flags = dc->tb_flags = tb->flags;
- dc->delayed_branch = (dc->tb_flags & D_FLAG) != 0;
+ dc->tb_flags = tb->flags;
+ dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
dc->singlestep_enabled = cs->singlestep_enabled;
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
@@ -1531,7 +1519,8 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct
TranslationBlock *tb)
gen_tb_start(tb);
do {
- tcg_gen_insn_start(dc->pc, num_insns != 0);
+ tcg_gen_insn_start(dc->pc, (dc->delayed_branch ? 1 : 0)
+ | (num_insns ? 2 : 0));
num_insns++;
if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
@@ -1556,8 +1545,6 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct
TranslationBlock *tb)
if (dc->delayed_branch) {
dc->delayed_branch--;
if (!dc->delayed_branch) {
- dc->tb_flags &= ~D_FLAG;
- gen_sync_flags(dc);
tcg_gen_mov_tl(cpu_pc, jmp_pc);
tcg_gen_discard_tl(jmp_pc);
dc->is_jmp = DISAS_UPDATE;
@@ -1575,6 +1562,10 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct
TranslationBlock *tb)
gen_io_end();
}
+ if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
+ tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
+ }
+
tcg_gen_movi_tl(cpu_ppc, dc->pc - 4);
if (dc->is_jmp == DISAS_NEXT) {
dc->is_jmp = DISAS_UPDATE;
@@ -1636,7 +1627,8 @@ void restore_state_to_opc(CPUOpenRISCState *env,
TranslationBlock *tb,
target_ulong *data)
{
env->pc = data[0];
- if (data[1]) {
+ env->dflag = data[1] & 1;
+ if (data[1] & 2) {
env->ppc = env->pc - 4;
}
}
--
2.5.5
- [Qemu-devel] [PATCH 09/25] target-openrisc: Implement ff1 and fl1 for 64-bit, (continued)
- [Qemu-devel] [PATCH 09/25] target-openrisc: Implement ff1 and fl1 for 64-bit, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 21/25] target-openrisc: Tidy insn dumping, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 16/25] target-openrisc: Write back result before FPE exception, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 18/25] target-openrisc: Implement l.adrp, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 20/25] target-openrisc: Optimize l.jal to next, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 10/25] target-openrisc: Represent MACHI:MACLO as a single unit, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 17/25] target-openrisc: Implement lwa, swa, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 15/25] target-openrisc: Fix madd, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 24/25] target-openrisc: Generate goto_tb for direct branches, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 25/25] target-openrisc: Generate goto_tb for conditional branches, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 22/25] target-openrisc: Tidy handling of delayed branches,
Richard Henderson <=
- [Qemu-devel] [PATCH 23/25] target-openrisc: Optimize for r0 being zero, Richard Henderson, 2016/06/13