mirror of https://github.com/xemu-project/xemu.git
Fix Sparc lda/ldda/sta/stda asi handling, fault on misaligned register ldd/std and illegal cwp on wrpsr (Aurelien Jarno)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2568 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
fcc72045e8
commit
d4218d996d
|
@ -269,7 +269,7 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
|
|||
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
|
||||
|
|
|
@ -615,6 +615,9 @@ void helper_rett()
|
|||
{
|
||||
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)) {
|
||||
|
@ -655,7 +658,10 @@ void helper_debug()
|
|||
#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()
|
||||
|
|
|
@ -2341,6 +2341,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
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;
|
||||
|
@ -2360,6 +2362,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
#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
|
||||
|
@ -2367,6 +2371,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
break;
|
||||
case 0x11: /* load unsigned byte alternate */
|
||||
#ifndef TARGET_SPARC64
|
||||
if (IS_IMM)
|
||||
goto illegal_insn;
|
||||
if (!supervisor(dc))
|
||||
goto priv_insn;
|
||||
#endif
|
||||
|
@ -2374,6 +2380,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
break;
|
||||
case 0x12: /* load unsigned halfword alternate */
|
||||
#ifndef TARGET_SPARC64
|
||||
if (IS_IMM)
|
||||
goto illegal_insn;
|
||||
if (!supervisor(dc))
|
||||
goto priv_insn;
|
||||
#endif
|
||||
|
@ -2381,14 +2389,20 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
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
|
||||
|
@ -2396,6 +2410,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
break;
|
||||
case 0x1a: /* load signed halfword alternate */
|
||||
#ifndef TARGET_SPARC64
|
||||
if (IS_IMM)
|
||||
goto illegal_insn;
|
||||
if (!supervisor(dc))
|
||||
goto priv_insn;
|
||||
#endif
|
||||
|
@ -2403,6 +2419,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
break;
|
||||
case 0x1d: /* ldstuba -- XXX: should be atomically */
|
||||
#ifndef TARGET_SPARC64
|
||||
if (IS_IMM)
|
||||
goto illegal_insn;
|
||||
if (!supervisor(dc))
|
||||
goto priv_insn;
|
||||
#endif
|
||||
|
@ -2410,6 +2428,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
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
|
||||
|
@ -2508,6 +2528,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
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);
|
||||
|
@ -2515,6 +2537,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
#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
|
||||
|
@ -2522,6 +2546,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
break;
|
||||
case 0x15:
|
||||
#ifndef TARGET_SPARC64
|
||||
if (IS_IMM)
|
||||
goto illegal_insn;
|
||||
if (!supervisor(dc))
|
||||
goto priv_insn;
|
||||
#endif
|
||||
|
@ -2529,6 +2555,8 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
break;
|
||||
case 0x16:
|
||||
#ifndef TARGET_SPARC64
|
||||
if (IS_IMM)
|
||||
goto illegal_insn;
|
||||
if (!supervisor(dc))
|
||||
goto priv_insn;
|
||||
#endif
|
||||
|
@ -2536,9 +2564,13 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue