env->psrs = (_tmp & PSR_S)? 1 : 0; \
env->psrps = (_tmp & PSR_PS)? 1 : 0; \
env->psret = (_tmp & PSR_ET)? 1 : 0; \
- cpu_set_cwp(env, _tmp & PSR_CWP & (NWINDOWS - 1)); \
+ cpu_set_cwp(env, _tmp & PSR_CWP); \
} while (0)
#ifdef TARGET_SPARC64
{
unsigned int cwp;
+ if (env->psret == 1)
+ raise_exception(TT_ILL_INSN);
+
env->psret = 1;
cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->wim & (1 << cwp)) {
#ifndef TARGET_SPARC64
void do_wrpsr()
{
- PUT_PSR(env, T0);
+ if ((T0 & PSR_CWP) >= NWINDOWS)
+ raise_exception(TT_ILL_INSN);
+ else
+ PUT_PSR(env, T0);
}
void do_rdpsr()
gen_op_ldst(lduh);
break;
case 0x3: /* load double word */
+ if (rd & 1)
+ goto illegal_insn;
gen_op_ldst(ldd);
gen_movl_T0_reg(rd + 1);
break;
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x10: /* load word alternate */
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
break;
case 0x11: /* load unsigned byte alternate */
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
break;
case 0x12: /* load unsigned halfword alternate */
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
break;
case 0x13: /* load double word alternate */
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
+ if (rd & 1)
+ goto illegal_insn;
gen_op_ldda(insn, 1, 8, 0);
gen_movl_T0_reg(rd + 1);
break;
case 0x19: /* load signed byte alternate */
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
break;
case 0x1a: /* load signed halfword alternate */
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
break;
case 0x1d: /* ldstuba -- XXX: should be atomically */
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
break;
case 0x1f: /* swap reg with alt. memory. Also atomically */
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
gen_op_ldst(sth);
break;
case 0x7:
+ if (rd & 1)
+ goto illegal_insn;
flush_T2(dc);
gen_movl_reg_T2(rd + 1);
gen_op_ldst(std);
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x14:
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
break;
case 0x15:
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
break;
case 0x16:
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
break;
case 0x17:
#ifndef TARGET_SPARC64
+ if (IS_IMM)
+ goto illegal_insn;
if (!supervisor(dc))
goto priv_insn;
#endif
+ if (rd & 1)
+ goto illegal_insn;
flush_T2(dc);
gen_movl_reg_T2(rd + 1);
gen_op_stda(insn, 0, 8, 0);