This avoids having to keep merging and extracting the flag from SR. Reviewed-by: Bastian Koppelmann <kbast...@mail.uni-paderborn.de> Signed-off-by: Richard Henderson <r...@twiddle.net> --- target-openrisc/cpu.h | 15 +++++- target-openrisc/gdbstub.c | 4 +- target-openrisc/interrupt.c | 2 +- target-openrisc/interrupt_helper.c | 2 +- target-openrisc/sys_helper.c | 5 +- target-openrisc/translate.c | 96 +++++++++++++++----------------------- 6 files changed, 56 insertions(+), 68 deletions(-)
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 810a280..1ea7607 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -286,7 +286,8 @@ typedef struct CPUOpenRISCState { target_ulong epcr; /* Exception PC register */ target_ulong eear; /* Exception EA register */ - uint32_t sr; /* Supervisor register */ + target_ulong sr_f; /* the SR_F bit, values 0, 1. */ + uint32_t sr; /* Supervisor register, without SR_F */ uint32_t vr; /* Version register */ uint32_t upr; /* Unit presence register */ uint32_t cpucfgr; /* CPU configure register */ @@ -298,7 +299,6 @@ typedef struct CPUOpenRISCState { uint32_t flags; /* cpu_flags, we only use it for exception in solt so far. */ - uint32_t btaken; /* the SR_F bit */ CPU_COMMON @@ -408,6 +408,17 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch) return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX; } +static inline uint32_t cpu_get_sr(CPUOpenRISCState *env) +{ + return env->sr + env->sr_f * SR_F; +} + +static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val) +{ + env->sr_f = (val & SR_F) != 0; + env->sr = (val & ~SR_F) | SR_FO; +} + #define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_INT_0 #endif /* CPU_OPENRISC_H */ diff --git a/target-openrisc/gdbstub.c b/target-openrisc/gdbstub.c index cb16e76..31ea013 100644 --- a/target-openrisc/gdbstub.c +++ b/target-openrisc/gdbstub.c @@ -38,7 +38,7 @@ int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return gdb_get_reg32(mem_buf, env->npc); case 34: /* SR */ - return gdb_get_reg32(mem_buf, env->sr); + return gdb_get_reg32(mem_buf, cpu_get_sr(env)); default: break; @@ -73,7 +73,7 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) break; case 34: /* SR */ - env->sr = tmp; + cpu_set_sr(env, tmp); break; default: diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c index 5fe3f11..36ca131 100644 --- a/target-openrisc/interrupt.c +++ b/target-openrisc/interrupt.c @@ -47,7 +47,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs) we need flush TLB when we enter&exit EXCP. */ tlb_flush(cs, 1); - env->esr = env->sr; + env->esr = cpu_get_sr(env); env->sr &= ~SR_DME; env->sr &= ~SR_IME; env->sr |= SR_SM; diff --git a/target-openrisc/interrupt_helper.c b/target-openrisc/interrupt_helper.c index 116f910..71e14ce 100644 --- a/target-openrisc/interrupt_helper.c +++ b/target-openrisc/interrupt_helper.c @@ -33,7 +33,7 @@ void HELPER(rfe)(CPUOpenRISCState *env) #endif cpu->env.pc = cpu->env.epcr; cpu->env.npc = cpu->env.epcr; - cpu->env.sr = cpu->env.esr; + cpu_set_sr(&cpu->env, cpu->env.esr); #ifndef CONFIG_USER_ONLY if (cpu->env.sr & SR_DME) { diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c index a719e45..8584ad0 100644 --- a/target-openrisc/sys_helper.c +++ b/target-openrisc/sys_helper.c @@ -49,8 +49,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, (rb & (SR_IME | SR_DME | SR_SM))) { tlb_flush(cs, 1); } - env->sr = rb; - env->sr |= SR_FO; /* FO is const equal to 1 */ + cpu_set_sr(env, rb); if (env->sr & SR_DME) { env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_data; @@ -200,7 +199,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, return env->npc; case TO_SPR(0, 17): /* SR */ - return env->sr; + return cpu_get_sr(env); case TO_SPR(0, 18): /* PPC */ return env->ppc; diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index 8ccacc7..2421b92 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -55,7 +55,7 @@ static TCGv cpu_pc; static TCGv jmp_pc; /* l.jr/l.jalr temp pc */ static TCGv cpu_npc; static TCGv cpu_ppc; -static TCGv_i32 env_btaken; /* bf/bnf , F flag taken */ +static TCGv cpu_sr_f; /* bf/bnf, F flag taken */ static TCGv_i32 fpcsr; static TCGv machi, maclo; static TCGv fpmaddhi, fpmaddlo; @@ -86,9 +86,8 @@ void openrisc_translate_init(void) offsetof(CPUOpenRISCState, ppc), "ppc"); jmp_pc = tcg_global_mem_new(cpu_env, offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc"); - env_btaken = tcg_global_mem_new_i32(cpu_env, - offsetof(CPUOpenRISCState, btaken), - "btaken"); + cpu_sr_f = tcg_global_mem_new(cpu_env, + offsetof(CPUOpenRISCState, sr_f), "sr_f"); fpcsr = tcg_global_mem_new_i32(cpu_env, offsetof(CPUOpenRISCState, fpcsr), "fpcsr"); @@ -111,16 +110,6 @@ void openrisc_translate_init(void) } } -/* Writeback SR_F translation space to execution space. */ -static inline void wb_SR_F(void) -{ - TCGLabel *label = gen_new_label(); - tcg_gen_andi_tl(cpu_sr, cpu_sr, ~SR_F); - tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, label); - tcg_gen_ori_tl(cpu_sr, cpu_sr, SR_F); - gen_set_label(label); -} - static inline int zero_extend(unsigned int val, int width) { return val & ((1 << width) - 1); @@ -231,14 +220,11 @@ static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0) case 0x04: /* l.bf */ { TCGLabel *lab = gen_new_label(); - TCGv sr_f = tcg_temp_new(); tcg_gen_movi_tl(jmp_pc, dc->pc+8); - tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE, - sr_f, SR_F, lab); + cpu_sr_f, SR_F, lab); tcg_gen_movi_tl(jmp_pc, tmp_pc); gen_set_label(lab); - tcg_temp_free(sr_f); } break; case 0x11: /* l.jr */ @@ -523,14 +509,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn) { TCGLabel *lab = gen_new_label(); TCGv res = tcg_temp_local_new(); - TCGv sr_f = tcg_temp_new(); - tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); tcg_gen_mov_tl(res, cpu_R[rb]); - tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_sr_f, SR_F, lab); tcg_gen_mov_tl(res, cpu_R[ra]); gen_set_label(lab); tcg_gen_mov_tl(cpu_R[rd], res); - tcg_temp_free(sr_f); tcg_temp_free(res); } return; @@ -997,7 +980,6 @@ static void dec_comp(DisasContext *dc, uint32_t insn) ra = extract32(insn, 16, 5); rb = extract32(insn, 11, 5); - tcg_gen_movi_i32(env_btaken, 0x0); /* unsigned integers */ tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]); tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]); @@ -1005,59 +987,58 @@ static void dec_comp(DisasContext *dc, uint32_t insn) switch (op0) { case 0x0: /* l.sfeq */ LOG_DIS("l.sfeq r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; case 0x1: /* l.sfne */ LOG_DIS("l.sfne r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_NE, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; case 0x2: /* l.sfgtu */ LOG_DIS("l.sfgtu r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; case 0x3: /* l.sfgeu */ LOG_DIS("l.sfgeu r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; case 0x4: /* l.sfltu */ LOG_DIS("l.sfltu r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; case 0x5: /* l.sfleu */ LOG_DIS("l.sfleu r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; case 0xa: /* l.sfgts */ LOG_DIS("l.sfgts r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_GT, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; case 0xb: /* l.sfges */ LOG_DIS("l.sfges r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_GE, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; case 0xc: /* l.sflts */ LOG_DIS("l.sflts r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_LT, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; case 0xd: /* l.sfles */ LOG_DIS("l.sfles r%d, r%d\n", ra, rb); - tcg_gen_setcond_tl(TCG_COND_LE, env_btaken, cpu_R[ra], cpu_R[rb]); + tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], cpu_R[rb]); break; default: gen_illegal_exception(dc); break; } - wb_SR_F(); } static void dec_compi(DisasContext *dc, uint32_t insn) @@ -1069,65 +1050,63 @@ static void dec_compi(DisasContext *dc, uint32_t insn) ra = extract32(insn, 16, 5); I16 = extract32(insn, 0, 16); - tcg_gen_movi_i32(env_btaken, 0x0); I16 = sign_extend(I16, 16); switch (op0) { case 0x0: /* l.sfeqi */ LOG_DIS("l.sfeqi r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], I16); break; case 0x1: /* l.sfnei */ LOG_DIS("l.sfnei r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_NE, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], I16); break; case 0x2: /* l.sfgtui */ LOG_DIS("l.sfgtui r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], I16); break; case 0x3: /* l.sfgeui */ LOG_DIS("l.sfgeui r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], I16); break; case 0x4: /* l.sfltui */ LOG_DIS("l.sfltui r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], I16); break; case 0x5: /* l.sfleui */ LOG_DIS("l.sfleui r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], I16); break; case 0xa: /* l.sfgtsi */ LOG_DIS("l.sfgtsi r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_GT, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], I16); break; case 0xb: /* l.sfgesi */ LOG_DIS("l.sfgesi r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_GE, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], I16); break; case 0xc: /* l.sfltsi */ LOG_DIS("l.sfltsi r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_LT, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], I16); break; case 0xd: /* l.sflesi */ LOG_DIS("l.sflesi r%d, %d\n", ra, I16); - tcg_gen_setcondi_tl(TCG_COND_LE, env_btaken, cpu_R[ra], I16); + tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], I16); break; default: gen_illegal_exception(dc); break; } - wb_SR_F(); } static void dec_sys(DisasContext *dc, uint32_t insn) @@ -1260,32 +1239,32 @@ static void dec_float(DisasContext *dc, uint32_t insn) case 0x08: /* lf.sfeq.s */ LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb); - gen_helper_float_eq_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x09: /* lf.sfne.s */ LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb); - gen_helper_float_ne_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_ne_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x0a: /* lf.sfgt.s */ LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb); - gen_helper_float_gt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_gt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x0b: /* lf.sfge.s */ LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb); - gen_helper_float_ge_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_ge_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x0c: /* lf.sflt.s */ LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb); - gen_helper_float_lt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x0d: /* lf.sfle.s */ LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb); - gen_helper_float_le_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; /* not used yet, open it when we need or64. */ @@ -1346,37 +1325,37 @@ static void dec_float(DisasContext *dc, uint32_t insn) case 0x18: lf.sfeq.d LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb); check_of64s(dc); - gen_helper_float_eq_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x1a: lf.sfgt.d LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb); check_of64s(dc); - gen_helper_float_gt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_gt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x1b: lf.sfge.d LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb); check_of64s(dc); - gen_helper_float_ge_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_ge_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x19: lf.sfne.d LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb); check_of64s(dc); - gen_helper_float_ne_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_ne_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x1c: lf.sflt.d LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb); check_of64s(dc); - gen_helper_float_lt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; case 0x1d: lf.sfle.d LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb); check_of64s(dc); - gen_helper_float_le_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); + gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]); break; #endif*/ @@ -1384,7 +1363,6 @@ static void dec_float(DisasContext *dc, uint32_t insn) gen_illegal_exception(dc); break; } - wb_SR_F(); } static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu) -- 2.5.5