aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-user/main.c2
-rw-r--r--target-sparc/cpu.h12
-rw-r--r--target-sparc/op.c40
-rw-r--r--target-sparc/op_helper.c38
-rw-r--r--target-sparc/translate.c81
5 files changed, 103 insertions, 70 deletions
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);