diff options
Diffstat (limited to 'target-sparc/translate.c')
-rw-r--r-- | target-sparc/translate.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/target-sparc/translate.c b/target-sparc/translate.c index d7894f1644..5ef543a1e9 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1653,6 +1653,33 @@ static inline TCGv get_src2(unsigned int insn, TCGv def) return r_rs2; } +#ifdef TARGET_SPARC64 +static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env) +{ + TCGv r_tl = tcg_temp_new(); + + /* load env->tl into r_tl */ + { + TCGv_i32 r_tl_tmp = tcg_temp_new_i32(); + tcg_gen_ld_i32(r_tl_tmp, cpu_env, offsetof(CPUSPARCState, tl)); + tcg_gen_ext_i32_tl(r_tl, r_tl_tmp); + tcg_temp_free_i32(r_tl_tmp); + } + + /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */ + tcg_gen_andi_tl(r_tl, r_tl, MAXTL_MASK); + + /* calculate offset to current trap state from env->ts, reuse r_tl */ + tcg_gen_muli_tl(r_tl, r_tl, sizeof (trap_state)); + tcg_gen_addi_ptr(r_tsptr, cpu_env, offsetof(CPUState, ts)); + + /* tsptr = env->ts[env->tl & MAXTL_MASK] */ + tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl); + + tcg_temp_free(r_tl); +} +#endif + #define CHECK_IU_FEATURE(dc, FEATURE) \ if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \ goto illegal_insn; @@ -1978,8 +2005,7 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_ptr r_tsptr; r_tsptr = tcg_temp_new_ptr(); - tcg_gen_ld_ptr(r_tsptr, cpu_env, - offsetof(CPUState, tsptr)); + gen_load_trap_state_at_tl(r_tsptr, cpu_env); tcg_gen_ld_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tpc)); tcg_temp_free_ptr(r_tsptr); @@ -1990,8 +2016,7 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_ptr r_tsptr; r_tsptr = tcg_temp_new_ptr(); - tcg_gen_ld_ptr(r_tsptr, cpu_env, - offsetof(CPUState, tsptr)); + gen_load_trap_state_at_tl(r_tsptr, cpu_env); tcg_gen_ld_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tnpc)); tcg_temp_free_ptr(r_tsptr); @@ -2002,8 +2027,7 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_ptr r_tsptr; r_tsptr = tcg_temp_new_ptr(); - tcg_gen_ld_ptr(r_tsptr, cpu_env, - offsetof(CPUState, tsptr)); + gen_load_trap_state_at_tl(r_tsptr, cpu_env); tcg_gen_ld_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tstate)); tcg_temp_free_ptr(r_tsptr); @@ -2014,8 +2038,7 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_ptr r_tsptr; r_tsptr = tcg_temp_new_ptr(); - tcg_gen_ld_ptr(r_tsptr, cpu_env, - offsetof(CPUState, tsptr)); + gen_load_trap_state_at_tl(r_tsptr, cpu_env); tcg_gen_ld_i32(cpu_tmp32, r_tsptr, offsetof(trap_state, tt)); tcg_temp_free_ptr(r_tsptr); @@ -3271,8 +3294,7 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_ptr r_tsptr; r_tsptr = tcg_temp_new_ptr(); - tcg_gen_ld_ptr(r_tsptr, cpu_env, - offsetof(CPUState, tsptr)); + gen_load_trap_state_at_tl(r_tsptr, cpu_env); tcg_gen_st_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tpc)); tcg_temp_free_ptr(r_tsptr); @@ -3283,8 +3305,7 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_ptr r_tsptr; r_tsptr = tcg_temp_new_ptr(); - tcg_gen_ld_ptr(r_tsptr, cpu_env, - offsetof(CPUState, tsptr)); + gen_load_trap_state_at_tl(r_tsptr, cpu_env); tcg_gen_st_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tnpc)); tcg_temp_free_ptr(r_tsptr); @@ -3295,8 +3316,7 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_ptr r_tsptr; r_tsptr = tcg_temp_new_ptr(); - tcg_gen_ld_ptr(r_tsptr, cpu_env, - offsetof(CPUState, tsptr)); + gen_load_trap_state_at_tl(r_tsptr, cpu_env); tcg_gen_st_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tstate)); @@ -3308,8 +3328,7 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_ptr r_tsptr; r_tsptr = tcg_temp_new_ptr(); - tcg_gen_ld_ptr(r_tsptr, cpu_env, - offsetof(CPUState, tsptr)); + gen_load_trap_state_at_tl(r_tsptr, cpu_env); tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, r_tsptr, offsetof(trap_state, tt)); |