diff --git a/linux-user/main.c b/linux-user/main.c index 0079c7a7e1..44af787d66 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -680,7 +680,7 @@ void cpu_loop (CPUSPARCState *env) if (trapnr == TT_DFAULT) info._sifields._sigfault._addr = env->dmmuregs[4]; else - info._sifields._sigfault._addr = env->tpc[env->tl]; + info._sifields._sigfault._addr = env->tsptr->tpc; queue_signal(info.si_signo, &info); } break; diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 9b9d85687b..79870f561d 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -169,6 +169,12 @@ #define NB_MMU_MODES 2 #else #define NB_MMU_MODES 3 +typedef struct trap_state { + uint64_t tpc; + uint64_t tnpc; + uint64_t tstate; + uint32_t tt; +} trap_state; #endif typedef struct CPUSPARCState { @@ -234,10 +240,8 @@ typedef struct CPUSPARCState { #if defined(TARGET_SPARC64) #define MAXTL 4 uint64_t t0, t1, t2; - uint64_t tpc[MAXTL]; - uint64_t tnpc[MAXTL]; - uint64_t tstate[MAXTL]; - uint32_t tt[MAXTL]; + trap_state *tsptr; + trap_state ts[MAXTL]; uint32_t xcc; /* Extended integer condition codes */ uint32_t asi; uint32_t pstate; diff --git a/target-sparc/op.c b/target-sparc/op.c index 0fd6cfd4eb..0e1423b547 100644 --- a/target-sparc/op.c +++ b/target-sparc/op.c @@ -805,46 +805,6 @@ void OPPROTO op_wrccr(void) PUT_CCR(env, T0); } -void OPPROTO op_rdtpc(void) -{ - T0 = env->tpc[env->tl]; -} - -void OPPROTO op_wrtpc(void) -{ - env->tpc[env->tl] = T0; -} - -void OPPROTO op_rdtnpc(void) -{ - T0 = env->tnpc[env->tl]; -} - -void OPPROTO op_wrtnpc(void) -{ - env->tnpc[env->tl] = T0; -} - -void OPPROTO op_rdtstate(void) -{ - T0 = env->tstate[env->tl]; -} - -void OPPROTO op_wrtstate(void) -{ - env->tstate[env->tl] = T0; -} - -void OPPROTO op_rdtt(void) -{ - T0 = env->tt[env->tl]; -} - -void OPPROTO op_wrtt(void) -{ - env->tt[env->tl] = T0; -} - // CWP handling is reversed in V9, but we still use the V8 register // order. void OPPROTO op_rdcwp(void) diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index bf46b9875d..76af753fb8 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -1675,23 +1675,25 @@ void helper_wrpstate(target_ulong new_state) void helper_done(void) { env->tl--; - env->pc = env->tnpc[env->tl]; - env->npc = env->tnpc[env->tl] + 4; - PUT_CCR(env, env->tstate[env->tl] >> 32); - env->asi = (env->tstate[env->tl] >> 24) & 0xff; - change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); - PUT_CWP64(env, env->tstate[env->tl] & 0xff); + env->tsptr = &env->ts[env->tl]; + 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); } void helper_retry(void) { env->tl--; - env->pc = env->tpc[env->tl]; - env->npc = env->tnpc[env->tl]; - PUT_CCR(env, env->tstate[env->tl] >> 32); - env->asi = (env->tstate[env->tl] >> 24) & 0xff; - change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); - PUT_CWP64(env, env->tstate[env->tl] & 0xff); + env->tsptr = &env->ts[env->tl]; + 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); } #endif @@ -1813,11 +1815,12 @@ void do_interrupt(int intno) return; } #endif - env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) | - ((env->pstate & 0xf3f) << 8) | GET_CWP64(env); - env->tpc[env->tl] = env->pc; - env->tnpc[env->tl] = env->npc; - env->tt[env->tl] = intno; + 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; change_pstate(PS_PEF | PS_PRIV | PS_AG); if (intno == TT_CLRWIN) @@ -1835,6 +1838,7 @@ void do_interrupt(int intno) if (env->tl != MAXTL) env->tl++; } + env->tsptr = &env->ts[env->tl]; env->pc = env->tbr; env->npc = env->pc + 4; env->exception_index = 0; diff --git a/target-sparc/translate.c b/target-sparc/translate.c index cefb848721..2546195fef 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1386,16 +1386,48 @@ static void disas_sparc_insn(DisasContext * dc) rs1 = GET_FIELD(insn, 13, 17); switch (rs1) { case 0: // tpc - gen_op_rdtpc(); + { + TCGv r_tsptr; + + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); + tcg_gen_ld_ptr(r_tsptr, cpu_env, + offsetof(CPUState, tsptr)); + tcg_gen_ld_tl(cpu_T[0], r_tsptr, + offsetof(trap_state, tpc)); + } break; case 1: // tnpc - gen_op_rdtnpc(); + { + TCGv r_tsptr; + + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); + tcg_gen_ld_ptr(r_tsptr, cpu_env, + offsetof(CPUState, tsptr)); + tcg_gen_ld_tl(cpu_T[0], r_tsptr, + offsetof(trap_state, tnpc)); + } break; case 2: // tstate - gen_op_rdtstate(); + { + TCGv r_tsptr; + + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); + tcg_gen_ld_ptr(r_tsptr, cpu_env, + offsetof(CPUState, tsptr)); + tcg_gen_ld_tl(cpu_T[0], r_tsptr, + offsetof(trap_state, tstate)); + } break; case 3: // tt - gen_op_rdtt(); + { + TCGv r_tsptr; + + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); + tcg_gen_ld_ptr(r_tsptr, cpu_env, + offsetof(CPUState, tsptr)); + tcg_gen_ld_i32(cpu_T[0], r_tsptr, + offsetof(trap_state, tt)); + } break; case 4: // tick { @@ -2536,16 +2568,48 @@ static void disas_sparc_insn(DisasContext * dc) #ifdef TARGET_SPARC64 switch (rd) { case 0: // tpc - gen_op_wrtpc(); + { + TCGv r_tsptr; + + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); + tcg_gen_ld_ptr(r_tsptr, cpu_env, + offsetof(CPUState, tsptr)); + tcg_gen_st_tl(cpu_T[0], r_tsptr, + offsetof(trap_state, tpc)); + } break; case 1: // tnpc - gen_op_wrtnpc(); + { + TCGv r_tsptr; + + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); + tcg_gen_ld_ptr(r_tsptr, cpu_env, + offsetof(CPUState, tsptr)); + tcg_gen_st_tl(cpu_T[0], r_tsptr, + offsetof(trap_state, tnpc)); + } break; case 2: // tstate - gen_op_wrtstate(); + { + TCGv r_tsptr; + + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); + tcg_gen_ld_ptr(r_tsptr, cpu_env, + offsetof(CPUState, tsptr)); + tcg_gen_st_tl(cpu_T[0], r_tsptr, + offsetof(trap_state, tstate)); + } break; case 3: // tt - gen_op_wrtt(); + { + TCGv r_tsptr; + + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); + tcg_gen_ld_ptr(r_tsptr, cpu_env, + offsetof(CPUState, tsptr)); + tcg_gen_st_i32(cpu_T[0], r_tsptr, + offsetof(trap_state, tt)); + } break; case 4: // tick { @@ -3921,6 +3985,7 @@ void cpu_reset(CPUSPARCState *env) env->pstate = PS_PRIV; env->hpstate = HS_PRIV; env->pc = 0x1fff0000000ULL; + env->tsptr = &env->ts[env->tl]; #else env->pc = 0; env->mmuregs[0] &= ~(MMU_E | MMU_NF);