Signed-off-by: Richard Henderson <r...@twiddle.net> --- 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