diff options
author | Igor Kovalenko <igor.v.kovalenko@gmail.com> | 2009-08-03 23:15:02 +0400 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2009-08-04 20:22:10 +0000 |
commit | 8194f35a0c71a3bf169459bf715bea53b7bbc904 (patch) | |
tree | 46db943bff1e3129cbf61e3065dd27530f34022d /target-sparc/op_helper.c | |
parent | a16aae0ca427f117c51d80e5d72e18b141595496 (diff) |
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/op_helper.c')
-rw-r--r-- | target-sparc/op_helper.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 0234e519ec..a9558dad85 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -3311,26 +3311,28 @@ void helper_wrpstate(target_ulong new_state) void helper_done(void) { - env->pc = env->tsptr->tpc; - env->npc = env->tsptr->tnpc + 4; - PUT_CCR(env, env->tsptr->tstate >> 32); - env->asi = (env->tsptr->tstate >> 24) & 0xff; - change_pstate((env->tsptr->tstate >> 8) & 0xf3f); - PUT_CWP64(env, env->tsptr->tstate & 0xff); + trap_state* tsptr = cpu_tsptr(env); + + env->pc = tsptr->tpc; + env->npc = tsptr->tnpc + 4; + PUT_CCR(env, tsptr->tstate >> 32); + env->asi = (tsptr->tstate >> 24) & 0xff; + change_pstate((tsptr->tstate >> 8) & 0xf3f); + PUT_CWP64(env, tsptr->tstate & 0xff); env->tl--; - env->tsptr = &env->ts[env->tl & MAXTL_MASK]; } void helper_retry(void) { - env->pc = env->tsptr->tpc; - env->npc = env->tsptr->tnpc; - PUT_CCR(env, env->tsptr->tstate >> 32); - env->asi = (env->tsptr->tstate >> 24) & 0xff; - change_pstate((env->tsptr->tstate >> 8) & 0xf3f); - PUT_CWP64(env, env->tsptr->tstate & 0xff); + trap_state* tsptr = cpu_tsptr(env); + + env->pc = tsptr->tpc; + env->npc = tsptr->tnpc; + PUT_CCR(env, tsptr->tstate >> 32); + env->asi = (tsptr->tstate >> 24) & 0xff; + change_pstate((tsptr->tstate >> 8) & 0xf3f); + PUT_CWP64(env, tsptr->tstate & 0xff); env->tl--; - env->tsptr = &env->ts[env->tl & MAXTL_MASK]; } void helper_set_softint(uint64_t value) @@ -3392,9 +3394,15 @@ static const char * const excp_names[0x80] = { }; #endif +trap_state* cpu_tsptr(CPUState* env) +{ + return &env->ts[env->tl & MAXTL_MASK]; +} + void do_interrupt(CPUState *env) { int intno = env->exception_index; + trap_state* tsptr; #ifdef DEBUG_PCALL if (qemu_loglevel_mask(CPU_LOG_INT)) { @@ -3451,13 +3459,14 @@ void do_interrupt(CPUState *env) if (env->tl < env->maxtl) env->tl++; } - env->tsptr = &env->ts[env->tl & MAXTL_MASK]; - env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) | + tsptr = cpu_tsptr(env); + + tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) | GET_CWP64(env); - env->tsptr->tpc = env->pc; - env->tsptr->tnpc = env->npc; - env->tsptr->tt = intno; + tsptr->tpc = env->pc; + tsptr->tnpc = env->npc; + tsptr->tt = intno; switch (intno) { case TT_IVEC: |