Convert Sparc64 trap state ops to TCG

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4018 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
blueswir1 2008-03-05 17:59:48 +00:00
parent 21fc3cfc10
commit 375ee38b4b
5 changed files with 103 additions and 70 deletions

View File

@ -680,7 +680,7 @@ void cpu_loop (CPUSPARCState *env)
if (trapnr == TT_DFAULT) if (trapnr == TT_DFAULT)
info._sifields._sigfault._addr = env->dmmuregs[4]; info._sifields._sigfault._addr = env->dmmuregs[4];
else else
info._sifields._sigfault._addr = env->tpc[env->tl]; info._sifields._sigfault._addr = env->tsptr->tpc;
queue_signal(info.si_signo, &info); queue_signal(info.si_signo, &info);
} }
break; break;

View File

@ -169,6 +169,12 @@
#define NB_MMU_MODES 2 #define NB_MMU_MODES 2
#else #else
#define NB_MMU_MODES 3 #define NB_MMU_MODES 3
typedef struct trap_state {
uint64_t tpc;
uint64_t tnpc;
uint64_t tstate;
uint32_t tt;
} trap_state;
#endif #endif
typedef struct CPUSPARCState { typedef struct CPUSPARCState {
@ -234,10 +240,8 @@ typedef struct CPUSPARCState {
#if defined(TARGET_SPARC64) #if defined(TARGET_SPARC64)
#define MAXTL 4 #define MAXTL 4
uint64_t t0, t1, t2; uint64_t t0, t1, t2;
uint64_t tpc[MAXTL]; trap_state *tsptr;
uint64_t tnpc[MAXTL]; trap_state ts[MAXTL];
uint64_t tstate[MAXTL];
uint32_t tt[MAXTL];
uint32_t xcc; /* Extended integer condition codes */ uint32_t xcc; /* Extended integer condition codes */
uint32_t asi; uint32_t asi;
uint32_t pstate; uint32_t pstate;

View File

@ -805,46 +805,6 @@ void OPPROTO op_wrccr(void)
PUT_CCR(env, T0); 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 // CWP handling is reversed in V9, but we still use the V8 register
// order. // order.
void OPPROTO op_rdcwp(void) void OPPROTO op_rdcwp(void)

View File

@ -1675,23 +1675,25 @@ void helper_wrpstate(target_ulong new_state)
void helper_done(void) void helper_done(void)
{ {
env->tl--; env->tl--;
env->pc = env->tnpc[env->tl]; env->tsptr = &env->ts[env->tl];
env->npc = env->tnpc[env->tl] + 4; env->pc = env->tsptr->tpc;
PUT_CCR(env, env->tstate[env->tl] >> 32); env->npc = env->tsptr->tnpc + 4;
env->asi = (env->tstate[env->tl] >> 24) & 0xff; PUT_CCR(env, env->tsptr->tstate >> 32);
change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); env->asi = (env->tsptr->tstate >> 24) & 0xff;
PUT_CWP64(env, env->tstate[env->tl] & 0xff); change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
PUT_CWP64(env, env->tsptr->tstate & 0xff);
} }
void helper_retry(void) void helper_retry(void)
{ {
env->tl--; env->tl--;
env->pc = env->tpc[env->tl]; env->tsptr = &env->ts[env->tl];
env->npc = env->tnpc[env->tl]; env->pc = env->tsptr->tpc;
PUT_CCR(env, env->tstate[env->tl] >> 32); env->npc = env->tsptr->tnpc;
env->asi = (env->tstate[env->tl] >> 24) & 0xff; PUT_CCR(env, env->tsptr->tstate >> 32);
change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); env->asi = (env->tsptr->tstate >> 24) & 0xff;
PUT_CWP64(env, env->tstate[env->tl] & 0xff); change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
PUT_CWP64(env, env->tsptr->tstate & 0xff);
} }
#endif #endif
@ -1813,11 +1815,12 @@ void do_interrupt(int intno)
return; return;
} }
#endif #endif
env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) | env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
((env->pstate & 0xf3f) << 8) | GET_CWP64(env); ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
env->tpc[env->tl] = env->pc; GET_CWP64(env);
env->tnpc[env->tl] = env->npc; env->tsptr->tpc = env->pc;
env->tt[env->tl] = intno; env->tsptr->tnpc = env->npc;
env->tsptr->tt = intno;
change_pstate(PS_PEF | PS_PRIV | PS_AG); change_pstate(PS_PEF | PS_PRIV | PS_AG);
if (intno == TT_CLRWIN) if (intno == TT_CLRWIN)
@ -1835,6 +1838,7 @@ void do_interrupt(int intno)
if (env->tl != MAXTL) if (env->tl != MAXTL)
env->tl++; env->tl++;
} }
env->tsptr = &env->ts[env->tl];
env->pc = env->tbr; env->pc = env->tbr;
env->npc = env->pc + 4; env->npc = env->pc + 4;
env->exception_index = 0; env->exception_index = 0;

View File

@ -1386,16 +1386,48 @@ static void disas_sparc_insn(DisasContext * dc)
rs1 = GET_FIELD(insn, 13, 17); rs1 = GET_FIELD(insn, 13, 17);
switch (rs1) { switch (rs1) {
case 0: // tpc 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; break;
case 1: // tnpc 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; break;
case 2: // tstate 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; break;
case 3: // tt 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; break;
case 4: // tick case 4: // tick
{ {
@ -2536,16 +2568,48 @@ static void disas_sparc_insn(DisasContext * dc)
#ifdef TARGET_SPARC64 #ifdef TARGET_SPARC64
switch (rd) { switch (rd) {
case 0: // tpc 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; break;
case 1: // tnpc 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; break;
case 2: // tstate 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; break;
case 3: // tt 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; break;
case 4: // tick case 4: // tick
{ {
@ -3921,6 +3985,7 @@ void cpu_reset(CPUSPARCState *env)
env->pstate = PS_PRIV; env->pstate = PS_PRIV;
env->hpstate = HS_PRIV; env->hpstate = HS_PRIV;
env->pc = 0x1fff0000000ULL; env->pc = 0x1fff0000000ULL;
env->tsptr = &env->ts[env->tl];
#else #else
env->pc = 0; env->pc = 0;
env->mmuregs[0] &= ~(MMU_E | MMU_NF); env->mmuregs[0] &= ~(MMU_E | MMU_NF);