mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #10043 from JosJuice/true-crime
Raise program exception on floating point exceptions
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# G2CD52, G2CE52, G2CP52, G2CX52 - True Crime: New York City
|
||||
|
||||
[Core]
|
||||
DivByZeroExceptions = True
|
||||
@@ -0,0 +1,4 @@
|
||||
# GCOD52, GCOE52, GCOF52, GCOP52 - Call of Duty: Finest Hour
|
||||
|
||||
[Core]
|
||||
DivByZeroExceptions = True
|
||||
@@ -75,6 +75,8 @@ private:
|
||||
bool bCPUThread;
|
||||
bool bJITFollowBranch;
|
||||
bool bSyncGPUOnSkipIdleHack;
|
||||
bool bFloatExceptions;
|
||||
bool bDivideByZeroExceptions;
|
||||
bool bFPRF;
|
||||
bool bAccurateNaNs;
|
||||
bool bMMU;
|
||||
@@ -109,6 +111,8 @@ void ConfigCache::SaveConfig(const SConfig& config)
|
||||
bCPUThread = config.bCPUThread;
|
||||
bJITFollowBranch = config.bJITFollowBranch;
|
||||
bSyncGPUOnSkipIdleHack = config.bSyncGPUOnSkipIdleHack;
|
||||
bFloatExceptions = config.bFloatExceptions;
|
||||
bDivideByZeroExceptions = config.bDivideByZeroExceptions;
|
||||
bFPRF = config.bFPRF;
|
||||
bAccurateNaNs = config.bAccurateNaNs;
|
||||
bDisableICache = config.bDisableICache;
|
||||
@@ -154,6 +158,8 @@ void ConfigCache::RestoreConfig(SConfig* config)
|
||||
config->bCPUThread = bCPUThread;
|
||||
config->bJITFollowBranch = bJITFollowBranch;
|
||||
config->bSyncGPUOnSkipIdleHack = bSyncGPUOnSkipIdleHack;
|
||||
config->bFloatExceptions = bFloatExceptions;
|
||||
config->bDivideByZeroExceptions = bDivideByZeroExceptions;
|
||||
config->bFPRF = bFPRF;
|
||||
config->bAccurateNaNs = bAccurateNaNs;
|
||||
config->bDisableICache = bDisableICache;
|
||||
@@ -256,6 +262,9 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
|
||||
core_section->Get("JITFollowBranch", &StartUp.bJITFollowBranch, StartUp.bJITFollowBranch);
|
||||
core_section->Get("SyncOnSkipIdle", &StartUp.bSyncGPUOnSkipIdleHack,
|
||||
StartUp.bSyncGPUOnSkipIdleHack);
|
||||
core_section->Get("FloatExceptions", &StartUp.bFloatExceptions, StartUp.bFloatExceptions);
|
||||
core_section->Get("DivByZeroExceptions", &StartUp.bDivideByZeroExceptions,
|
||||
StartUp.bDivideByZeroExceptions);
|
||||
core_section->Get("FPRF", &StartUp.bFPRF, StartUp.bFPRF);
|
||||
core_section->Get("AccurateNaNs", &StartUp.bAccurateNaNs, StartUp.bAccurateNaNs);
|
||||
core_section->Get("DisableICache", &StartUp.bDisableICache, StartUp.bDisableICache);
|
||||
@@ -370,6 +379,8 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
|
||||
StartUp.bAccurateNaNs = netplay_settings.m_AccurateNaNs;
|
||||
StartUp.bDisableICache = netplay_settings.m_DisableICache;
|
||||
StartUp.bSyncGPUOnSkipIdleHack = netplay_settings.m_SyncOnSkipIdle;
|
||||
StartUp.bFloatExceptions = netplay_settings.m_FloatExceptions;
|
||||
StartUp.bDivideByZeroExceptions = netplay_settings.m_DivideByZeroExceptions;
|
||||
StartUp.bSyncGPU = netplay_settings.m_SyncGPU;
|
||||
StartUp.iSyncGpuMaxDistance = netplay_settings.m_SyncGpuMaxDistance;
|
||||
StartUp.iSyncGpuMinDistance = netplay_settings.m_SyncGpuMinDistance;
|
||||
|
||||
@@ -86,6 +86,9 @@ const Info<int> MAIN_SYNC_GPU_MIN_DISTANCE{{System::Main, "Core", "SyncGpuMinDis
|
||||
const Info<float> MAIN_SYNC_GPU_OVERCLOCK{{System::Main, "Core", "SyncGpuOverclock"}, 1.0f};
|
||||
const Info<bool> MAIN_FAST_DISC_SPEED{{System::Main, "Core", "FastDiscSpeed"}, false};
|
||||
const Info<bool> MAIN_LOW_DCBZ_HACK{{System::Main, "Core", "LowDCBZHack"}, false};
|
||||
const Info<bool> MAIN_FLOAT_EXCEPTIONS{{System::Main, "Core", "FloatExceptions"}, false};
|
||||
const Info<bool> MAIN_DIVIDE_BY_ZERO_EXCEPTIONS{{System::Main, "Core", "DivByZeroExceptions"},
|
||||
false};
|
||||
const Info<bool> MAIN_FPRF{{System::Main, "Core", "FPRF"}, false};
|
||||
const Info<bool> MAIN_ACCURATE_NANS{{System::Main, "Core", "AccurateNaNs"}, false};
|
||||
const Info<bool> MAIN_DISABLE_ICACHE{{System::Main, "Core", "DisableICache"}, false};
|
||||
|
||||
@@ -68,6 +68,8 @@ extern const Info<int> MAIN_SYNC_GPU_MIN_DISTANCE;
|
||||
extern const Info<float> MAIN_SYNC_GPU_OVERCLOCK;
|
||||
extern const Info<bool> MAIN_FAST_DISC_SPEED;
|
||||
extern const Info<bool> MAIN_LOW_DCBZ_HACK;
|
||||
extern const Info<bool> MAIN_FLOAT_EXCEPTIONS;
|
||||
extern const Info<bool> MAIN_DIVIDE_BY_ZERO_EXCEPTIONS;
|
||||
extern const Info<bool> MAIN_FPRF;
|
||||
extern const Info<bool> MAIN_ACCURATE_NANS;
|
||||
extern const Info<bool> MAIN_DISABLE_ICACHE;
|
||||
|
||||
@@ -69,6 +69,8 @@ public:
|
||||
layer->Set(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES,
|
||||
m_settings.m_SafeTextureCacheColorSamples);
|
||||
layer->Set(Config::GFX_PERF_QUERIES_ENABLE, m_settings.m_PerfQueriesEnable);
|
||||
layer->Set(Config::MAIN_FLOAT_EXCEPTIONS, m_settings.m_FloatExceptions);
|
||||
layer->Set(Config::MAIN_DIVIDE_BY_ZERO_EXCEPTIONS, m_settings.m_DivideByZeroExceptions);
|
||||
layer->Set(Config::MAIN_FPRF, m_settings.m_FPRF);
|
||||
layer->Set(Config::MAIN_ACCURATE_NANS, m_settings.m_AccurateNaNs);
|
||||
layer->Set(Config::MAIN_DISABLE_ICACHE, m_settings.m_DisableICache);
|
||||
|
||||
@@ -213,6 +213,8 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
||||
core->Set("SyncGpuMaxDistance", iSyncGpuMaxDistance);
|
||||
core->Set("SyncGpuMinDistance", iSyncGpuMinDistance);
|
||||
core->Set("SyncGpuOverclock", fSyncGpuOverclock);
|
||||
core->Set("FloatExceptions", bFloatExceptions);
|
||||
core->Set("DivByZeroExceptions", bDivideByZeroExceptions);
|
||||
core->Set("FPRF", bFPRF);
|
||||
core->Set("AccurateNaNs", bAccurateNaNs);
|
||||
core->Set("SelectedLanguage", SelectedLanguage);
|
||||
@@ -509,6 +511,8 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
||||
core->Get("SyncGpuOverclock", &fSyncGpuOverclock, 1.0f);
|
||||
core->Get("FastDiscSpeed", &bFastDiscSpeed, false);
|
||||
core->Get("LowDCBZHack", &bLowDCBZHack, false);
|
||||
core->Get("FloatExceptions", &bFloatExceptions, false);
|
||||
core->Get("DivByZeroExceptions", &bDivideByZeroExceptions, false);
|
||||
core->Get("FPRF", &bFPRF, false);
|
||||
core->Get("AccurateNaNs", &bAccurateNaNs, false);
|
||||
core->Get("DisableICache", &bDisableICache, false);
|
||||
@@ -747,6 +751,8 @@ void SConfig::LoadDefaults()
|
||||
bRunCompareServer = false;
|
||||
bDSPHLE = true;
|
||||
bFastmem = true;
|
||||
bFloatExceptions = false;
|
||||
bDivideByZeroExceptions = false;
|
||||
bFPRF = false;
|
||||
bAccurateNaNs = false;
|
||||
bDisableICache = false;
|
||||
|
||||
@@ -108,6 +108,8 @@ struct SConfig
|
||||
bool bJITRegisterCacheOff = false;
|
||||
|
||||
bool bFastmem;
|
||||
bool bFloatExceptions = false;
|
||||
bool bDivideByZeroExceptions = false;
|
||||
bool bFPRF = false;
|
||||
bool bAccurateNaNs = false;
|
||||
bool bDisableICache = false;
|
||||
|
||||
@@ -831,6 +831,8 @@ void NetPlayClient::OnStartGame(sf::Packet& packet)
|
||||
packet >> m_net_settings.m_EFBEmulateFormatChanges;
|
||||
packet >> m_net_settings.m_SafeTextureCacheColorSamples;
|
||||
packet >> m_net_settings.m_PerfQueriesEnable;
|
||||
packet >> m_net_settings.m_FloatExceptions;
|
||||
packet >> m_net_settings.m_DivideByZeroExceptions;
|
||||
packet >> m_net_settings.m_FPRF;
|
||||
packet >> m_net_settings.m_AccurateNaNs;
|
||||
packet >> m_net_settings.m_DisableICache;
|
||||
|
||||
@@ -58,6 +58,8 @@ struct NetSettings
|
||||
bool m_EFBEmulateFormatChanges;
|
||||
int m_SafeTextureCacheColorSamples;
|
||||
bool m_PerfQueriesEnable;
|
||||
bool m_FloatExceptions;
|
||||
bool m_DivideByZeroExceptions;
|
||||
bool m_FPRF;
|
||||
bool m_AccurateNaNs;
|
||||
bool m_DisableICache;
|
||||
|
||||
@@ -1329,6 +1329,8 @@ bool NetPlayServer::SetupNetSettings()
|
||||
settings.m_SafeTextureCacheColorSamples =
|
||||
Config::Get(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES);
|
||||
settings.m_PerfQueriesEnable = Config::Get(Config::GFX_PERF_QUERIES_ENABLE);
|
||||
settings.m_FloatExceptions = Config::Get(Config::MAIN_FLOAT_EXCEPTIONS);
|
||||
settings.m_DivideByZeroExceptions = Config::Get(Config::MAIN_DIVIDE_BY_ZERO_EXCEPTIONS);
|
||||
settings.m_FPRF = Config::Get(Config::MAIN_FPRF);
|
||||
settings.m_AccurateNaNs = Config::Get(Config::MAIN_ACCURATE_NANS);
|
||||
settings.m_DisableICache = Config::Get(Config::MAIN_DISABLE_ICACHE);
|
||||
@@ -1505,6 +1507,8 @@ bool NetPlayServer::StartGame()
|
||||
spac << m_settings.m_EFBEmulateFormatChanges;
|
||||
spac << m_settings.m_SafeTextureCacheColorSamples;
|
||||
spac << m_settings.m_PerfQueriesEnable;
|
||||
spac << m_settings.m_FloatExceptions;
|
||||
spac << m_settings.m_DivideByZeroExceptions;
|
||||
spac << m_settings.m_FPRF;
|
||||
spac << m_settings.m_AccurateNaNs;
|
||||
spac << m_settings.m_DisableICache;
|
||||
|
||||
@@ -58,7 +58,7 @@ void CachedInterpreter::Init()
|
||||
jo.enableBlocklink = false;
|
||||
|
||||
m_block_cache.Init();
|
||||
UpdateMemoryOptions();
|
||||
UpdateMemoryAndExceptionOptions();
|
||||
|
||||
code_block.m_stats = &js.st;
|
||||
code_block.m_gpa = &js.gpa;
|
||||
@@ -180,6 +180,17 @@ static bool CheckDSI(u32 data)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CheckProgramException(u32 data)
|
||||
{
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_PROGRAM)
|
||||
{
|
||||
PowerPC::CheckExceptions();
|
||||
PowerPC::ppcState.downcount -= data;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CheckBreakpoint(u32 data)
|
||||
{
|
||||
PowerPC::CheckBreakPoints();
|
||||
@@ -267,26 +278,26 @@ void CachedInterpreter::Jit(u32 address)
|
||||
const bool check_fpu = (op.opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound;
|
||||
const bool endblock = (op.opinfo->flags & FL_ENDBLOCK) != 0;
|
||||
const bool memcheck = (op.opinfo->flags & FL_LOADSTORE) && jo.memcheck;
|
||||
const bool check_program_exception = !endblock && ShouldHandleFPExceptionForInstruction(&op);
|
||||
const bool idle_loop = op.branchIsIdleLoop;
|
||||
|
||||
if (breakpoint)
|
||||
{
|
||||
if (breakpoint || check_fpu || endblock || memcheck || check_program_exception)
|
||||
m_code.emplace_back(WritePC, op.address);
|
||||
|
||||
if (breakpoint)
|
||||
m_code.emplace_back(CheckBreakpoint, js.downcountAmount);
|
||||
}
|
||||
|
||||
if (check_fpu)
|
||||
{
|
||||
m_code.emplace_back(WritePC, op.address);
|
||||
m_code.emplace_back(CheckFPU, js.downcountAmount);
|
||||
js.firstFPInstructionFound = true;
|
||||
}
|
||||
|
||||
if (endblock || memcheck)
|
||||
m_code.emplace_back(WritePC, op.address);
|
||||
m_code.emplace_back(PPCTables::GetInterpreterOp(op.inst), op.inst);
|
||||
if (memcheck)
|
||||
m_code.emplace_back(CheckDSI, js.downcountAmount);
|
||||
if (check_program_exception)
|
||||
m_code.emplace_back(CheckProgramException, js.downcountAmount);
|
||||
if (idle_loop)
|
||||
m_code.emplace_back(CheckIdle, js.blockStart);
|
||||
if (endblock)
|
||||
@@ -316,5 +327,5 @@ void CachedInterpreter::ClearCache()
|
||||
{
|
||||
m_code.clear();
|
||||
m_block_cache.Clear();
|
||||
UpdateMemoryOptions();
|
||||
UpdateMemoryAndExceptionOptions();
|
||||
}
|
||||
|
||||
@@ -419,11 +419,17 @@ enum FPSCRExceptionFlag : u32
|
||||
FPSCR_VXSQRT = 1U << (31 - 22),
|
||||
FPSCR_VXCVI = 1U << (31 - 23),
|
||||
FPSCR_VE = 1U << (31 - 24),
|
||||
FPSCR_OE = 1U << (31 - 25),
|
||||
FPSCR_UE = 1U << (31 - 26),
|
||||
FPSCR_ZE = 1U << (31 - 27),
|
||||
FPSCR_XE = 1U << (31 - 28),
|
||||
|
||||
FPSCR_VX_ANY = FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI | FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC |
|
||||
FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI,
|
||||
|
||||
FPSCR_ANY_X = FPSCR_OX | FPSCR_UX | FPSCR_ZX | FPSCR_XX | FPSCR_VX_ANY,
|
||||
|
||||
FPSCR_ANY_E = FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE,
|
||||
};
|
||||
|
||||
// Floating Point Status and Control Register
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FloatUtils.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
constexpr double PPC_NAN = std::numeric_limits<double>::quiet_NaN();
|
||||
@@ -24,6 +25,20 @@ enum class FPCC
|
||||
FU = 1, // ?
|
||||
};
|
||||
|
||||
inline void CheckFPExceptions(UReg_FPSCR fpscr)
|
||||
{
|
||||
if (fpscr.FEX && (MSR.FE0 || MSR.FE1))
|
||||
GenerateProgramException(ProgramExceptionCause::FloatingPoint);
|
||||
}
|
||||
|
||||
inline void UpdateFPExceptionSummary(UReg_FPSCR* fpscr)
|
||||
{
|
||||
fpscr->VX = (fpscr->Hex & FPSCR_VX_ANY) != 0;
|
||||
fpscr->FEX = ((fpscr->Hex >> 22) & (fpscr->Hex & FPSCR_ANY_E)) != 0;
|
||||
|
||||
CheckFPExceptions(*fpscr);
|
||||
}
|
||||
|
||||
inline void SetFPException(UReg_FPSCR* fpscr, u32 mask)
|
||||
{
|
||||
if ((fpscr->Hex & mask) != mask)
|
||||
@@ -32,7 +47,7 @@ inline void SetFPException(UReg_FPSCR* fpscr, u32 mask)
|
||||
}
|
||||
|
||||
fpscr->Hex |= mask;
|
||||
fpscr->VX = (fpscr->Hex & FPSCR_VX_ANY) != 0;
|
||||
UpdateFPExceptionSummary(fpscr);
|
||||
}
|
||||
|
||||
inline float ForceSingle(const UReg_FPSCR& fpscr, double value)
|
||||
@@ -123,7 +138,15 @@ inline FPResult NI_div(UReg_FPSCR* fpscr, double a, double b)
|
||||
{
|
||||
FPResult result{a / b};
|
||||
|
||||
if (std::isnan(result.value))
|
||||
if (std::isinf(result.value))
|
||||
{
|
||||
if (b == 0.0)
|
||||
{
|
||||
result.SetException(fpscr, FPSCR_ZX);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (std::isnan(result.value))
|
||||
{
|
||||
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
||||
result.SetException(fpscr, FPSCR_VXSNAN);
|
||||
@@ -142,20 +165,9 @@ inline FPResult NI_div(UReg_FPSCR* fpscr, double a, double b)
|
||||
}
|
||||
|
||||
if (b == 0.0)
|
||||
{
|
||||
if (a == 0.0)
|
||||
{
|
||||
result.SetException(fpscr, FPSCR_VXZDZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.SetException(fpscr, FPSCR_ZX);
|
||||
}
|
||||
}
|
||||
result.SetException(fpscr, FPSCR_VXZDZ);
|
||||
else if (std::isinf(a) && std::isinf(b))
|
||||
{
|
||||
result.SetException(fpscr, FPSCR_VXIDI);
|
||||
}
|
||||
|
||||
result.value = PPC_NAN;
|
||||
return result;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user