PowerPC: Set SRR1 correctly for program exceptions
This commit is contained in:
parent
4541abd1c0
commit
83c6df1965
|
@ -7,6 +7,14 @@
|
|||
#include "Core/PowerPC/Gekko.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
enum class ProgramExceptionCause : u32
|
||||
{
|
||||
FloatingPoint = 1 << (31 - 11),
|
||||
IllegalInstruction = 1 << (31 - 12),
|
||||
PrivilegedInstruction = 1 << (31 - 13),
|
||||
Trap = 1 << (31 - 14),
|
||||
};
|
||||
|
||||
inline void GenerateAlignmentException(u32 address)
|
||||
{
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT;
|
||||
|
@ -19,7 +27,8 @@ inline void GenerateDSIException(u32 address)
|
|||
PowerPC::ppcState.spr[SPR_DAR] = address;
|
||||
}
|
||||
|
||||
inline void GenerateProgramException()
|
||||
inline void GenerateProgramException(ProgramExceptionCause cause)
|
||||
{
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
||||
PowerPC::ppcState.spr[SPR_SRR1] = static_cast<u32>(cause);
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ int Interpreter::SingleStepInner()
|
|||
{
|
||||
if (IsInvalidPairedSingleExecution(m_prev_inst))
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||
CheckExceptions();
|
||||
}
|
||||
else if (MSR.FP)
|
||||
|
|
|
@ -101,7 +101,7 @@ void Interpreter::rfi(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "Common/BitUtils.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
void Interpreter::Helper_UpdateCR0(u32 value)
|
||||
|
@ -131,7 +132,7 @@ void Interpreter::twi(UGeckoInstruction inst)
|
|||
if ((a < b && (TO & 0x10) != 0) || (a > b && (TO & 0x08) != 0) || (a == b && (TO & 0x04) != 0) ||
|
||||
(u32(a) < u32(b) && (TO & 0x02) != 0) || (u32(a) > u32(b) && (TO & 0x01) != 0))
|
||||
{
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
||||
GenerateProgramException(ProgramExceptionCause::Trap);
|
||||
PowerPC::CheckExceptions();
|
||||
m_end_block = true; // Dunno about this
|
||||
}
|
||||
|
@ -339,7 +340,7 @@ void Interpreter::tw(UGeckoInstruction inst)
|
|||
if ((a < b && (TO & 0x10) != 0) || (a > b && (TO & 0x08) != 0) || (a == b && (TO & 0x04) != 0) ||
|
||||
((u32(a) < u32(b)) && (TO & 0x02) != 0) || ((u32(a) > u32(b)) && (TO & 0x01) != 0))
|
||||
{
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
||||
GenerateProgramException(ProgramExceptionCause::Trap);
|
||||
PowerPC::CheckExceptions();
|
||||
m_end_block = true; // Dunno about this
|
||||
}
|
||||
|
|
|
@ -450,7 +450,7 @@ void Interpreter::dcbi(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -514,7 +514,7 @@ void Interpreter::dcbz_l(UGeckoInstruction inst)
|
|||
{
|
||||
if (!HID2.LCE)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1041,7 +1041,7 @@ void Interpreter::tlbie(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1055,7 +1055,7 @@ void Interpreter::tlbsync(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
}
|
||||
|
||||
// Ignored
|
||||
|
|
|
@ -311,7 +311,7 @@ void Interpreter::psq_l(UGeckoInstruction inst)
|
|||
{
|
||||
if (HID2.LSQE == 0)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -323,7 +323,7 @@ void Interpreter::psq_lu(UGeckoInstruction inst)
|
|||
{
|
||||
if (HID2.LSQE == 0)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ void Interpreter::psq_st(UGeckoInstruction inst)
|
|||
{
|
||||
if (HID2.LSQE == 0)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ void Interpreter::psq_stu(UGeckoInstruction inst)
|
|||
{
|
||||
if (HID2.LSQE == 0)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ void Interpreter::mfmsr(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ void Interpreter::mfsr(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ void Interpreter::mfsrin(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ void Interpreter::mtmsr(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ void Interpreter::mtsr(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ void Interpreter::mtsrin(UGeckoInstruction inst)
|
|||
{
|
||||
if (MSR.PR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ void Interpreter::mfspr(UGeckoInstruction inst)
|
|||
if (MSR.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR && index != SPR_TL &&
|
||||
index != SPR_TU)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ void Interpreter::mtspr(UGeckoInstruction inst)
|
|||
// XER, LR, and CTR are the only ones available to be written to in user mode
|
||||
if (MSR.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR)
|
||||
{
|
||||
GenerateProgramException();
|
||||
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
#include "Common/CommonTypes.h"
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||
#include "Core/PowerPC/Jit64/Jit.h"
|
||||
#include "Core/PowerPC/Jit64/RegCache/JitRegCache.h"
|
||||
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
|
||||
|
@ -2562,6 +2564,7 @@ void Jit64::twX(UGeckoInstruction inst)
|
|||
}
|
||||
LOCK();
|
||||
OR(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_PROGRAM));
|
||||
MOV(32, PPCSTATE_SRR1, Imm32(static_cast<u32>(ProgramExceptionCause::Trap)));
|
||||
|
||||
gpr.Flush();
|
||||
fpr.Flush();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||
#include "Core/PowerPC/PPCTables.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
@ -233,6 +234,9 @@ void JitArm64::twx(UGeckoInstruction inst)
|
|||
ORR(WA, WA, LogicalImm(EXCEPTION_PROGRAM, 32));
|
||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
|
||||
MOVI2R(WA, static_cast<u32>(ProgramExceptionCause::Trap));
|
||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF_SPR(SPR_SRR1));
|
||||
|
||||
WriteExceptionExit(js.compilerPC, false, true);
|
||||
|
||||
SwitchToNearCode();
|
||||
|
|
|
@ -483,8 +483,8 @@ void CheckExceptions()
|
|||
else if (exceptions & EXCEPTION_PROGRAM)
|
||||
{
|
||||
SRR0 = PC;
|
||||
// say that it's a trap exception
|
||||
SRR1 = (MSR.Hex & 0x87C0FFFF) | 0x20000;
|
||||
// SRR1 was partially set by GenerateProgramException, so bitwise or is used here
|
||||
SRR1 |= MSR.Hex & 0x87C0FFFF;
|
||||
MSR.LE = MSR.ILE;
|
||||
MSR.Hex &= ~0x04EF36;
|
||||
PC = NPC = 0x00000700;
|
||||
|
|
Loading…
Reference in New Issue