mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-25 06:44:59 +00:00
PowerPC: Set SRR1 correctly for program exceptions
This commit is contained in:
parent
4541abd1c0
commit
83c6df1965
10 changed files with 40 additions and 23 deletions
|
@ -7,6 +7,14 @@
|
||||||
#include "Core/PowerPC/Gekko.h"
|
#include "Core/PowerPC/Gekko.h"
|
||||||
#include "Core/PowerPC/PowerPC.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)
|
inline void GenerateAlignmentException(u32 address)
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT;
|
PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT;
|
||||||
|
@ -19,7 +27,8 @@ inline void GenerateDSIException(u32 address)
|
||||||
PowerPC::ppcState.spr[SPR_DAR] = address;
|
PowerPC::ppcState.spr[SPR_DAR] = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GenerateProgramException()
|
inline void GenerateProgramException(ProgramExceptionCause cause)
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
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))
|
if (IsInvalidPairedSingleExecution(m_prev_inst))
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||||
CheckExceptions();
|
CheckExceptions();
|
||||||
}
|
}
|
||||||
else if (MSR.FP)
|
else if (MSR.FP)
|
||||||
|
|
|
@ -101,7 +101,7 @@ void Interpreter::rfi(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "Common/BitUtils.h"
|
#include "Common/BitUtils.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
|
||||||
void Interpreter::Helper_UpdateCR0(u32 value)
|
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) ||
|
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))
|
(u32(a) < u32(b) && (TO & 0x02) != 0) || (u32(a) > u32(b) && (TO & 0x01) != 0))
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
GenerateProgramException(ProgramExceptionCause::Trap);
|
||||||
PowerPC::CheckExceptions();
|
PowerPC::CheckExceptions();
|
||||||
m_end_block = true; // Dunno about this
|
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) ||
|
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))
|
((u32(a) < u32(b)) && (TO & 0x02) != 0) || ((u32(a) > u32(b)) && (TO & 0x01) != 0))
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM;
|
GenerateProgramException(ProgramExceptionCause::Trap);
|
||||||
PowerPC::CheckExceptions();
|
PowerPC::CheckExceptions();
|
||||||
m_end_block = true; // Dunno about this
|
m_end_block = true; // Dunno about this
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,7 +450,7 @@ void Interpreter::dcbi(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ void Interpreter::dcbz_l(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (!HID2.LCE)
|
if (!HID2.LCE)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1041,7 +1041,7 @@ void Interpreter::tlbie(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1055,7 +1055,7 @@ void Interpreter::tlbsync(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignored
|
// Ignored
|
||||||
|
|
|
@ -311,7 +311,7 @@ void Interpreter::psq_l(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (HID2.LSQE == 0)
|
if (HID2.LSQE == 0)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ void Interpreter::psq_lu(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (HID2.LSQE == 0)
|
if (HID2.LSQE == 0)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ void Interpreter::psq_st(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (HID2.LSQE == 0)
|
if (HID2.LSQE == 0)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +354,7 @@ void Interpreter::psq_stu(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (HID2.LSQE == 0)
|
if (HID2.LSQE == 0)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::IllegalInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ void Interpreter::mfmsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ void Interpreter::mfsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ void Interpreter::mfsrin(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ void Interpreter::mtmsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ void Interpreter::mtsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ void Interpreter::mtsrin(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (MSR.PR)
|
if (MSR.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
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 &&
|
if (MSR.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR && index != SPR_TL &&
|
||||||
index != SPR_TU)
|
index != SPR_TU)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
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
|
// 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)
|
if (MSR.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR)
|
||||||
{
|
{
|
||||||
GenerateProgramException();
|
GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/MathUtil.h"
|
#include "Common/MathUtil.h"
|
||||||
#include "Common/x64Emitter.h"
|
#include "Common/x64Emitter.h"
|
||||||
|
|
||||||
#include "Core/CoreTiming.h"
|
#include "Core/CoreTiming.h"
|
||||||
|
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||||
#include "Core/PowerPC/Jit64/Jit.h"
|
#include "Core/PowerPC/Jit64/Jit.h"
|
||||||
#include "Core/PowerPC/Jit64/RegCache/JitRegCache.h"
|
#include "Core/PowerPC/Jit64/RegCache/JitRegCache.h"
|
||||||
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
|
#include "Core/PowerPC/Jit64Common/Jit64PowerPCState.h"
|
||||||
|
@ -2562,6 +2564,7 @@ void Jit64::twX(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
LOCK();
|
LOCK();
|
||||||
OR(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_PROGRAM));
|
OR(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_PROGRAM));
|
||||||
|
MOV(32, PPCSTATE_SRR1, Imm32(static_cast<u32>(ProgramExceptionCause::Trap)));
|
||||||
|
|
||||||
gpr.Flush();
|
gpr.Flush();
|
||||||
fpr.Flush();
|
fpr.Flush();
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/CoreTiming.h"
|
#include "Core/CoreTiming.h"
|
||||||
|
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#include "Core/PowerPC/PPCTables.h"
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
@ -233,6 +234,9 @@ void JitArm64::twx(UGeckoInstruction inst)
|
||||||
ORR(WA, WA, LogicalImm(EXCEPTION_PROGRAM, 32));
|
ORR(WA, WA, LogicalImm(EXCEPTION_PROGRAM, 32));
|
||||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
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);
|
WriteExceptionExit(js.compilerPC, false, true);
|
||||||
|
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
|
|
|
@ -483,8 +483,8 @@ void CheckExceptions()
|
||||||
else if (exceptions & EXCEPTION_PROGRAM)
|
else if (exceptions & EXCEPTION_PROGRAM)
|
||||||
{
|
{
|
||||||
SRR0 = PC;
|
SRR0 = PC;
|
||||||
// say that it's a trap exception
|
// SRR1 was partially set by GenerateProgramException, so bitwise or is used here
|
||||||
SRR1 = (MSR.Hex & 0x87C0FFFF) | 0x20000;
|
SRR1 |= MSR.Hex & 0x87C0FFFF;
|
||||||
MSR.LE = MSR.ILE;
|
MSR.LE = MSR.ILE;
|
||||||
MSR.Hex &= ~0x04EF36;
|
MSR.Hex &= ~0x04EF36;
|
||||||
PC = NPC = 0x00000700;
|
PC = NPC = 0x00000700;
|
||||||
|
|
Loading…
Add table
Reference in a new issue