summaryrefslogtreecommitdiffstats
path: root/target-sparc/translate.c
diff options
context:
space:
mode:
authorIgor Kovalenko <igor.v.kovalenko@gmail.com>2009-08-03 23:15:02 +0400
committerBlue Swirl <blauwirbel@gmail.com>2009-08-04 20:22:10 +0000
commit8194f35a0c71a3bf169459bf715bea53b7bbc904 (patch)
tree46db943bff1e3129cbf61e3065dd27530f34022d /target-sparc/translate.c
parenta16aae0ca427f117c51d80e5d72e18b141595496 (diff)
downloadhqemu-8194f35a0c71a3bf169459bf715bea53b7bbc904.zip
hqemu-8194f35a0c71a3bf169459bf715bea53b7bbc904.tar.gz
Sparc64: replace tsptr with helper routine
tl and tsptr of members sparc64 cpu state must be changed simultaneously to keep trap state window in sync with current trap level. Currently translation of store to tl does not change tsptr, which leads to corrupt trap state on corresponding trap level. This patch removes tsptr from sparc64 cpu state and replaces all uses with call to helper routine. Changes v0->v1: - reimplemented helper routine with tcg generator - on cpu reset trap type and pstate are populated with power-on reset values, including tl=maxtl Signed-off-by: igor.v.kovalenko@gmail.com Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-sparc/translate.c')
-rw-r--r--target-sparc/translate.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index d7894f1..5ef543a 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));
OpenPOWER on IntegriCloud