{
env->exception_index = tt;
cpu_loop_exit();
-}
+}
void check_ieee_exceptions()
{
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
#endif
-#if defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
void helper_ld_asi(int asi, int size, int sign)
{
}
case 4: /* read MMU regs */
{
int reg = (T0 >> 8) & 0xf;
-
+
ret = env->mmuregs[reg];
if (reg == 3) /* Fault status cleared on read */
env->mmuregs[reg] = 0;
{
int reg = (T0 >> 8) & 0xf;
uint32_t oldreg;
-
+
oldreg = env->mmuregs[reg];
switch(reg) {
case 0:
// copy 32 bytes
unsigned int i;
uint32_t src = T1 & ~3, dst = T0 & ~3, temp;
-
+
for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
temp = ldl_kernel(src);
stl_kernel(dst, temp);
case 0x56: // I-MMU tag read
{
unsigned int i;
-
+
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
case 0x5e: // D-MMU tag read
{
unsigned int i;
-
+
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
{
int reg = (T0 >> 3) & 0xf;
uint64_t oldreg;
-
+
oldreg = env->immuregs[reg];
switch(reg) {
case 0: // RO
{
int reg = (T0 >> 3) & 0xf;
uint64_t oldreg;
-
+
oldreg = env->dmmuregs[reg];
switch(reg) {
case 0: // RO
raise_exception(TT_ILL_INSN);
env->psret = 1;
- cwp = (env->cwp + 1) & (NWINDOWS - 1);
+ cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->wim & (1 << cwp)) {
raise_exception(TT_WIN_UNF);
}
}
}
-void do_wrpstate()
+static inline void change_pstate(uint64_t new_pstate)
{
- uint64_t new_pstate, pstate_regs, new_pstate_regs;
+ uint64_t pstate_regs, new_pstate_regs;
uint64_t *src, *dst;
- new_pstate = T0 & 0xf3f;
pstate_regs = env->pstate & 0xc01;
new_pstate_regs = new_pstate & 0xc01;
if (new_pstate_regs != pstate_regs) {
env->pstate = new_pstate;
}
+void do_wrpstate(void)
+{
+ change_pstate(T0 & 0xf3f);
+}
+
void do_done(void)
{
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;
- env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;
- set_cwp(env->tstate[env->tl] & 0xff);
+ change_pstate((env->tstate[env->tl] >> 8) & 0xf3f);
+ PUT_CWP64(env, env->tstate[env->tl] & 0xff);
}
void do_retry(void)
env->npc = env->tnpc[env->tl];
PUT_CCR(env, env->tstate[env->tl] >> 32);
env->asi = (env->tstate[env->tl] >> 24) & 0xff;
- env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;
- set_cwp(env->tstate[env->tl] & 0xff);
+ change_pstate((env->tstate[env->tl] >> 8) & 0xf3f);
+ PUT_CWP64(env, env->tstate[env->tl] & 0xff);
}
#endif
count++;
}
#endif
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
if (env->tl == MAXTL) {
cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
return;
}
#endif
env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
- ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
+ ((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->pstate = PS_PEF | PS_PRIV | PS_AG;
+ change_pstate(PS_PEF | PS_PRIV | PS_AG);
+
+ if (intno == TT_CLRWIN)
+ set_cwp((env->cwp - 1) & (NWINDOWS - 1));
+ else if ((intno & 0x1c0) == TT_SPILL)
+ set_cwp((env->cwp - env->cansave - 2) & (NWINDOWS - 1));
+ else if ((intno & 0x1c0) == TT_FILL)
+ set_cwp((env->cwp + 1) & (NWINDOWS - 1));
env->tbr &= ~0x7fffULL;
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
if (env->tl < MAXTL - 1) {
count++;
}
#endif
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
if (env->psret == 0) {
cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
return;
}
#endif
env->psret = 0;
- cwp = (env->cwp - 1) & (NWINDOWS - 1);
+ cwp = (env->cwp - 1) & (NWINDOWS - 1);
set_cwp(cwp);
env->regwptr[9] = env->pc;
env->regwptr[10] = env->npc;
}
#endif
-#if !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
void *retaddr);