mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
mips3: Fixed interpreter bug where BADCOP exceptions would execute the faulting opcode twice. [Ryan Holtz]
This commit is contained in:
parent
0b544df0c2
commit
d1f85d60f3
@ -42,11 +42,11 @@
|
||||
#define LFSVALL_FR0 (get_cop1_reg64(FSREG))
|
||||
#define LFDVALL_FR0 (get_cop1_reg64(FDREG))
|
||||
|
||||
#define SFRVALD_FR0(x) (set_cop1_reg64(FRREG,d2u((x))))
|
||||
#define SFTVALD_FR0(x) (set_cop1_reg64(FTREG,d2u((x))))
|
||||
#define SFSVALD_FR0(x) (set_cop1_reg64(FSREG,d2u((x))))
|
||||
//#define SFRVALD_FR0(x) (set_cop1_reg64(FRREG,d2u((x))))
|
||||
//#define SFTVALD_FR0(x) (set_cop1_reg64(FTREG,d2u((x))))
|
||||
//#define SFSVALD_FR0(x) (set_cop1_reg64(FSREG,d2u((x))))
|
||||
#define SFDVALD_FR0(x) (set_cop1_reg64(FDREG,d2u((x))))
|
||||
#define SFSVALL_FR0(x) (set_cop1_reg64(FSREG,(x)))
|
||||
//#define SFSVALL_FR0(x) (set_cop1_reg64(FSREG,(x)))
|
||||
#define SFDVALL_FR0(x) (set_cop1_reg64(FDREG,(x)))
|
||||
|
||||
#define FRVALS_FR1 (((float *)&m_core->cpr[1][FRREG])[BYTE_XOR_LE(0)])
|
||||
@ -1444,6 +1444,7 @@ void mips3_device::handle_cop0(UINT32 op)
|
||||
{
|
||||
m_badcop_value = 0;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (RSREG)
|
||||
@ -1516,10 +1517,7 @@ void mips3_device::handle_cop0(UINT32 op)
|
||||
|
||||
inline UINT32 mips3_device::get_cop1_reg32(int idx)
|
||||
{
|
||||
//if (IS_FR0)
|
||||
// return ((UINT32 *)&m_core->cpr[1][0])[idx];
|
||||
//else
|
||||
return m_core->cpr[1][idx];
|
||||
return m_core->cpr[1][idx];
|
||||
}
|
||||
|
||||
inline UINT64 mips3_device::get_cop1_reg64(int idx)
|
||||
@ -1533,10 +1531,7 @@ inline UINT64 mips3_device::get_cop1_reg64(int idx)
|
||||
|
||||
inline void mips3_device::set_cop1_reg32(int idx, UINT32 val)
|
||||
{
|
||||
//if (IS_FR0)
|
||||
// ((UINT32 *)&m_core->cpr[1][0])[idx] = val;
|
||||
//else
|
||||
m_core->cpr[1][idx] = val;
|
||||
m_core->cpr[1][idx] = val;
|
||||
}
|
||||
|
||||
inline void mips3_device::set_cop1_reg64(int idx, UINT64 val)
|
||||
@ -1547,7 +1542,9 @@ inline void mips3_device::set_cop1_reg64(int idx, UINT64 val)
|
||||
((UINT32 *)&m_core->cpr[1][(idx&0x1E) + 1])[BYTE_XOR_LE(0)] = val >> 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_core->cpr[1][idx] = val;
|
||||
}
|
||||
}
|
||||
inline UINT64 mips3_device::get_cop1_creg(int idx)
|
||||
{
|
||||
@ -1586,6 +1583,7 @@ void mips3_device::handle_cop1_fr0(UINT32 op)
|
||||
{
|
||||
m_badcop_value = 1;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (RSREG)
|
||||
@ -1945,6 +1943,7 @@ void mips3_device::handle_cop1_fr1(UINT32 op)
|
||||
{
|
||||
m_badcop_value = 1;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (RSREG)
|
||||
@ -2308,6 +2307,7 @@ void mips3_device::handle_cop1x_fr0(UINT32 op)
|
||||
{
|
||||
m_badcop_value = 1;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (op & 0x3f)
|
||||
@ -2386,6 +2386,7 @@ void mips3_device::handle_cop1x_fr1(UINT32 op)
|
||||
{
|
||||
m_badcop_value = 1;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (op & 0x3f)
|
||||
@ -2487,6 +2488,7 @@ void mips3_device::handle_cop2(UINT32 op)
|
||||
{
|
||||
m_badcop_value = 2;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (RSREG)
|
||||
@ -2814,9 +2816,19 @@ void mips3_device::execute_run()
|
||||
case 0x0e: /* XORI */ if (RTREG) RTVAL64 = RSVAL64 ^ UIMMVAL; break;
|
||||
case 0x0f: /* LUI */ if (RTREG) RTVAL64 = (INT32)(UIMMVAL << 16); break;
|
||||
case 0x10: /* COP0 */ handle_cop0(op); break;
|
||||
case 0x11: /* COP1 */ if (IS_FR0) handle_cop1_fr0(op); else handle_cop1_fr1(op); break;
|
||||
case 0x11: /* COP1 */
|
||||
if (IS_FR0)
|
||||
handle_cop1_fr0(op);
|
||||
else
|
||||
handle_cop1_fr1(op);
|
||||
break;
|
||||
case 0x12: /* COP2 */ handle_cop2(op); break;
|
||||
case 0x13: /* COP1X - R5000 */if (IS_FR0) handle_cop1x_fr0(op); else handle_cop1x_fr1(op); break;
|
||||
case 0x13: /* COP1X - R5000 */
|
||||
if (IS_FR0)
|
||||
handle_cop1x_fr0(op);
|
||||
else
|
||||
handle_cop1x_fr1(op);
|
||||
break;
|
||||
case 0x14: /* BEQL */ if (RSVAL64 == RTVAL64) ADDPC(SIMMVAL); else m_core->pc += 4; break;
|
||||
case 0x15: /* BNEL */ if (RSVAL64 != RTVAL64) ADDPC(SIMMVAL); else m_core->pc += 4; break;
|
||||
case 0x16: /* BLEZL */ if ((INT64)RSVAL64 <= 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
|
||||
@ -2860,8 +2872,11 @@ void mips3_device::execute_run()
|
||||
{
|
||||
m_badcop_value = 1;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
break;
|
||||
}
|
||||
if (RWORD(SIMMVAL+RSVAL32, &temp)) set_cop1_reg32(RTREG, temp); break;
|
||||
if (RWORD(SIMMVAL+RSVAL32, &temp))
|
||||
set_cop1_reg32(RTREG, temp);
|
||||
break;
|
||||
case 0x32: /* LWC2 */ if (RWORD(SIMMVAL+RSVAL32, &temp)) set_cop2_reg(RTREG, temp); break;
|
||||
case 0x33: /* PREF */ /* effective no-op */ break;
|
||||
case 0x34: /* LLD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) RTVAL64 = temp64; m_lld_value = temp64; break;
|
||||
@ -2870,8 +2885,11 @@ void mips3_device::execute_run()
|
||||
{
|
||||
m_badcop_value = 1;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
break;
|
||||
}
|
||||
if (RDOUBLE(SIMMVAL+RSVAL32, &temp64)) set_cop1_reg64(RTREG, temp64); break;
|
||||
if (RDOUBLE(SIMMVAL+RSVAL32, &temp64))
|
||||
set_cop1_reg64(RTREG, temp64);
|
||||
break;
|
||||
case 0x36: /* LDC2 */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64)) set_cop2_reg(RTREG, temp64); break;
|
||||
case 0x37: /* LD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) RTVAL64 = temp64; break;
|
||||
case 0x38: /* SC */ if (RWORD(SIMMVAL+RSVAL32, &temp) && RTREG)
|
||||
@ -2892,8 +2910,10 @@ void mips3_device::execute_run()
|
||||
{
|
||||
m_badcop_value = 1;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
break;
|
||||
}
|
||||
WWORD(SIMMVAL+RSVAL32, get_cop1_reg32(RTREG)); break;
|
||||
WWORD(SIMMVAL+RSVAL32, get_cop1_reg32(RTREG));
|
||||
break;
|
||||
case 0x3a: /* SWC2 */ WWORD(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); break;
|
||||
case 0x3b: /* SWC3 */ invalid_instruction(op); break;
|
||||
case 0x3c: /* SCD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG)
|
||||
@ -2914,8 +2934,10 @@ void mips3_device::execute_run()
|
||||
{
|
||||
m_badcop_value = 1;
|
||||
generate_exception(EXCEPTION_BADCOP, 1);
|
||||
break;
|
||||
}
|
||||
WDOUBLE(SIMMVAL+RSVAL32, get_cop1_reg64(RTREG)); break;
|
||||
WDOUBLE(SIMMVAL+RSVAL32, get_cop1_reg64(RTREG));
|
||||
break;
|
||||
case 0x3e: /* SDC2 */ WDOUBLE(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); break;
|
||||
case 0x3f: /* SD */ WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); break;
|
||||
default: /* ??? */ invalid_instruction(op); break;
|
||||
|
Loading…
Reference in New Issue
Block a user