From 2c994b729e0b498bb0d5e3d7796cb01b47ac7e19 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 4 Jul 2021 14:49:10 +0200 Subject: [PATCH] PowerPC: Use broader mask for checking loadstore exceptions We will need to check for EXCEPTION_ALIGNMENT in addition to EXCEPTION_DSI. Let's also throw in EXCEPTION_FAKE_MEMCHECK_HIT while we're at it so we can skip doing fake DSI exceptions for that. Reordering the exceptions enum is done for the sake of saving one instruction on AArch64 when checking for loadstore exceptions. (Bitwise operations can encode immediates containing a run of ones of an arbitrary length, rotated by an arbitrary amount of bits, and in order to make use of this all loadstore exceptions should have adjacent bit positions.) --- .../CachedInterpreter/CachedInterpreter.cpp | 6 +- Source/Core/Core/PowerPC/Gekko.h | 13 +-- .../Core/PowerPC/Interpreter/Interpreter.cpp | 4 +- .../Interpreter/Interpreter_LoadStore.cpp | 93 ++++++++++--------- .../Interpreter_LoadStorePaired.cpp | 10 +- Source/Core/Core/PowerPC/Jit64/Jit.cpp | 2 +- .../Core/PowerPC/Jit64Common/EmuCodeBlock.cpp | 4 +- Source/Core/Core/PowerPC/JitArm64/Jit.cpp | 3 +- Source/Core/Core/PowerPC/MMU.cpp | 8 +- Source/Core/Core/PowerPC/PowerPC.cpp | 2 +- 10 files changed, 74 insertions(+), 71 deletions(-) diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp index 17b91a6627e2..e091b4310841 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp @@ -170,9 +170,9 @@ static bool CheckFPU(u32 data) return false; } -static bool CheckDSI(u32 data) +static bool CheckLoadStore(u32 data) { - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { PowerPC::CheckExceptions(); PowerPC::ppcState.downcount -= data; @@ -287,7 +287,7 @@ void CachedInterpreter::Jit(u32 address) 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); + m_code.emplace_back(CheckLoadStore, js.downcountAmount); if (idle_loop) m_code.emplace_back(CheckIdle, js.blockStart); if (endblock) diff --git a/Source/Core/Core/PowerPC/Gekko.h b/Source/Core/Core/PowerPC/Gekko.h index 9919aacfb43a..8b7cfe03b111 100644 --- a/Source/Core/Core/PowerPC/Gekko.h +++ b/Source/Core/Core/PowerPC/Gekko.h @@ -900,14 +900,15 @@ enum EXCEPTION_DECREMENTER = 0x00000001, EXCEPTION_SYSCALL = 0x00000002, EXCEPTION_EXTERNAL_INT = 0x00000004, - EXCEPTION_DSI = 0x00000008, - EXCEPTION_ISI = 0x00000010, + EXCEPTION_ISI = 0x00000008, + EXCEPTION_DSI = 0x00000010, EXCEPTION_ALIGNMENT = 0x00000020, - EXCEPTION_FPU_UNAVAILABLE = 0x00000040, - EXCEPTION_PROGRAM = 0x00000080, - EXCEPTION_PERFORMANCE_MONITOR = 0x00000100, + EXCEPTION_FAKE_MEMCHECK_HIT = 0x00000040, + EXCEPTION_FPU_UNAVAILABLE = 0x00000080, + EXCEPTION_PROGRAM = 0x00000100, + EXCEPTION_PERFORMANCE_MONITOR = 0x00000200, - EXCEPTION_FAKE_MEMCHECK_HIT = 0x00000200, + ANY_LOADSTORE_EXCEPTION = EXCEPTION_DSI | EXCEPTION_ALIGNMENT | EXCEPTION_FAKE_MEMCHECK_HIT, }; constexpr s32 SignExt16(s16 x) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index f047e2e57663..e13a5d03a109 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -188,7 +188,7 @@ int Interpreter::SingleStepInner() else if (MSR.FP) { m_op_table[m_prev_inst.OPCD](m_prev_inst); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { CheckExceptions(); } @@ -204,7 +204,7 @@ int Interpreter::SingleStepInner() else { m_op_table[m_prev_inst.OPCD](m_prev_inst); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { CheckExceptions(); } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index 888f751ffbc6..ce6dd0fdad3b 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -43,7 +43,7 @@ void Interpreter::lbz(UGeckoInstruction inst) { const u32 temp = PowerPC::Read_U8(Helper_Get_EA(PowerPC::ppcState, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) rGPR[inst.RD] = temp; } @@ -52,7 +52,7 @@ void Interpreter::lbzu(UGeckoInstruction inst) const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U8(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; rGPR[inst.RA] = address; @@ -71,7 +71,7 @@ void Interpreter::lfd(UGeckoInstruction inst) const u64 temp = PowerPC::Read_U64(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) rPS(inst.FD).SetPS0(temp); } @@ -87,7 +87,7 @@ void Interpreter::lfdu(UGeckoInstruction inst) const u64 temp = PowerPC::Read_U64(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rPS(inst.FD).SetPS0(temp); rGPR[inst.RA] = address; @@ -106,7 +106,7 @@ void Interpreter::lfdux(UGeckoInstruction inst) const u64 temp = PowerPC::Read_U64(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rPS(inst.FD).SetPS0(temp); rGPR[inst.RA] = address; @@ -125,7 +125,7 @@ void Interpreter::lfdx(UGeckoInstruction inst) const u64 temp = PowerPC::Read_U64(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) rPS(inst.FD).SetPS0(temp); } @@ -141,7 +141,7 @@ void Interpreter::lfs(UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { const u64 value = ConvertToDouble(temp); rPS(inst.FD).Fill(value); @@ -160,7 +160,7 @@ void Interpreter::lfsu(UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { const u64 value = ConvertToDouble(temp); rPS(inst.FD).Fill(value); @@ -180,7 +180,7 @@ void Interpreter::lfsux(UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { const u64 value = ConvertToDouble(temp); rPS(inst.FD).Fill(value); @@ -200,7 +200,7 @@ void Interpreter::lfsx(UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { const u64 value = ConvertToDouble(temp); rPS(inst.FD).Fill(value); @@ -211,7 +211,7 @@ void Interpreter::lha(UGeckoInstruction inst) { const u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(Helper_Get_EA(PowerPC::ppcState, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; } @@ -222,7 +222,7 @@ void Interpreter::lhau(UGeckoInstruction inst) const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); const u32 temp = (u32)(s32)(s16)PowerPC::Read_U16(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; rGPR[inst.RA] = address; @@ -233,7 +233,7 @@ void Interpreter::lhz(UGeckoInstruction inst) { const u32 temp = PowerPC::Read_U16(Helper_Get_EA(PowerPC::ppcState, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; } @@ -244,7 +244,7 @@ void Interpreter::lhzu(UGeckoInstruction inst) const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U16(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; rGPR[inst.RA] = address; @@ -266,10 +266,13 @@ void Interpreter::lmw(UGeckoInstruction inst) { const u32 temp_reg = PowerPC::Read_U32(address); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { - PanicAlertFmt("DSI exception in lmw"); - NOTICE_LOG_FMT(POWERPC, "DSI exception in lmw"); + if (!(PowerPC::ppcState.Exceptions & EXCEPTION_ALIGNMENT)) + { + PanicAlertFmt("DSI exception in lmw"); + NOTICE_LOG_FMT(POWERPC, "DSI exception in lmw"); + } return; } else @@ -293,7 +296,7 @@ void Interpreter::stmw(UGeckoInstruction inst) for (int i = inst.RS; i <= 31; i++, address += 4) { PowerPC::Write_U32(rGPR[i], address); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { PanicAlertFmt("DSI exception in stmw"); NOTICE_LOG_FMT(POWERPC, "DSI exception in stmw"); @@ -307,7 +310,7 @@ void Interpreter::lwz(UGeckoInstruction inst) const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; } @@ -318,7 +321,7 @@ void Interpreter::lwzu(UGeckoInstruction inst) const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; rGPR[inst.RA] = address; @@ -335,7 +338,7 @@ void Interpreter::stbu(UGeckoInstruction inst) const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); PowerPC::Write_U8((u8)rGPR[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } @@ -365,7 +368,7 @@ void Interpreter::stfdu(UGeckoInstruction inst) } PowerPC::Write_U64(rPS(inst.FS).PS0AsU64(), address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } @@ -395,7 +398,7 @@ void Interpreter::stfsu(UGeckoInstruction inst) } PowerPC::Write_U32(ConvertToSingle(rPS(inst.FS).PS0AsU64()), address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } @@ -411,7 +414,7 @@ void Interpreter::sthu(UGeckoInstruction inst) const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); PowerPC::Write_U16((u16)rGPR[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } @@ -427,7 +430,7 @@ void Interpreter::stwu(UGeckoInstruction inst) const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); PowerPC::Write_U32(rGPR[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } @@ -594,7 +597,7 @@ void Interpreter::lbzux(UGeckoInstruction inst) const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U8(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; rGPR[inst.RA] = address; @@ -605,7 +608,7 @@ void Interpreter::lbzx(UGeckoInstruction inst) { const u32 temp = PowerPC::Read_U8(Helper_Get_EA_X(PowerPC::ppcState, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; } @@ -616,7 +619,7 @@ void Interpreter::lhaux(UGeckoInstruction inst) const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); const s32 temp = (s32)(s16)PowerPC::Read_U16(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; rGPR[inst.RA] = address; @@ -627,7 +630,7 @@ void Interpreter::lhax(UGeckoInstruction inst) { const s32 temp = (s32)(s16)PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; } @@ -637,7 +640,7 @@ void Interpreter::lhbrx(UGeckoInstruction inst) { const u32 temp = Common::swap16(PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst))); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; } @@ -648,7 +651,7 @@ void Interpreter::lhzux(UGeckoInstruction inst) const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U16(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; rGPR[inst.RA] = address; @@ -659,7 +662,7 @@ void Interpreter::lhzx(UGeckoInstruction inst) { const u32 temp = PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; } @@ -687,7 +690,7 @@ void Interpreter::lswx(UGeckoInstruction inst) const u32 temp_value = PowerPC::Read_U8(EA) << (24 - offset); // Not64 (Homebrew N64 Emulator for Wii) triggers the following case. - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { NOTICE_LOG_FMT(POWERPC, "DSI exception in lswx"); return; @@ -702,7 +705,7 @@ void Interpreter::lwbrx(UGeckoInstruction inst) { const u32 temp = Common::swap32(PowerPC::Read_U32(Helper_Get_EA_X(PowerPC::ppcState, inst))); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; } @@ -713,7 +716,7 @@ void Interpreter::lwzux(UGeckoInstruction inst) const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; rGPR[inst.RA] = address; @@ -725,7 +728,7 @@ void Interpreter::lwzx(UGeckoInstruction inst) const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; } @@ -736,7 +739,7 @@ void Interpreter::stbux(UGeckoInstruction inst) const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); PowerPC::Write_U8((u8)rGPR[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } @@ -758,7 +761,7 @@ void Interpreter::stfdux(UGeckoInstruction inst) } PowerPC::Write_U64(rPS(inst.FS).PS0AsU64(), address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } @@ -802,7 +805,7 @@ void Interpreter::stfsux(UGeckoInstruction inst) } PowerPC::Write_U32(ConvertToSingle(rPS(inst.FS).PS0AsU64()), address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } @@ -831,7 +834,7 @@ void Interpreter::sthux(UGeckoInstruction inst) const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); PowerPC::Write_U16((u16)rGPR[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } @@ -876,7 +879,7 @@ void Interpreter::lswi(UGeckoInstruction inst) } const u32 temp_value = PowerPC::Read_U8(EA) << (24 - i); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { PanicAlertFmt("DSI exception in lsw."); return; @@ -925,7 +928,7 @@ void Interpreter::stswi(UGeckoInstruction inst) r &= 31; } PowerPC::Write_U8((rGPR[r] >> (24 - i)) & 0xFF, EA); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { return; } @@ -990,7 +993,7 @@ void Interpreter::lwarx(UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RD] = temp; m_reserve = true; @@ -1014,7 +1017,7 @@ void Interpreter::stwcxd(UGeckoInstruction inst) if (address == m_reserve_address) { PowerPC::Write_U32(rGPR[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { m_reserve = false; PowerPC::ppcState.cr.SetField(0, 2 | PowerPC::GetXER_SO()); @@ -1031,7 +1034,7 @@ void Interpreter::stwux(UGeckoInstruction inst) const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); PowerPC::Write_U32(rGPR[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION)) { rGPR[inst.RA] = address; } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp index 5d1a6ed21d38..7d3a8c9907c9 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp @@ -300,7 +300,7 @@ static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI, break; } - if (ppcs->Exceptions & EXCEPTION_DSI) + if (ppcs->Exceptions & ANY_LOADSTORE_EXCEPTION) { return; } @@ -331,7 +331,7 @@ void Interpreter::psq_lu(UGeckoInstruction inst) const u32 EA = rGPR[inst.RA] + inst.SIMM_12; Helper_Dequantize(&PowerPC::ppcState, EA, inst.I, inst.RD, inst.W); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { return; } @@ -361,7 +361,7 @@ void Interpreter::psq_stu(UGeckoInstruction inst) const u32 EA = rGPR[inst.RA] + inst.SIMM_12; Helper_Quantize(&PowerPC::ppcState, EA, inst.I, inst.RS, inst.W); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { return; } @@ -385,7 +385,7 @@ void Interpreter::psq_lux(UGeckoInstruction inst) const u32 EA = rGPR[inst.RA] + rGPR[inst.RB]; Helper_Dequantize(&PowerPC::ppcState, EA, inst.Ix, inst.RD, inst.Wx); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { return; } @@ -397,7 +397,7 @@ void Interpreter::psq_stux(UGeckoInstruction inst) const u32 EA = rGPR[inst.RA] + rGPR[inst.RB]; Helper_Quantize(&PowerPC::ppcState, EA, inst.Ix, inst.RS, inst.Wx); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + if (PowerPC::ppcState.Exceptions & ANY_LOADSTORE_EXCEPTION) { return; } diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index ed69b5d4cdc2..8905f3b2c5d6 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -1131,7 +1131,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) op.address); if (!js.fastmemLoadStore && !js.fixupExceptionHandler) { - TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_DSI)); + TEST(32, PPCSTATE(Exceptions), Imm32(ANY_LOADSTORE_EXCEPTION)); memException = J_CC(CC_NZ, true); } diff --git a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp index 01a5115ba080..5dff4c646616 100644 --- a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp +++ b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp @@ -60,7 +60,7 @@ void EmuCodeBlock::MemoryExceptionCheck() { if (js.trampolineExceptionHandler) { - TEST(32, PPCSTATE(Exceptions), Gen::Imm32(EXCEPTION_DSI)); + TEST(32, PPCSTATE(Exceptions), Gen::Imm32(ANY_LOADSTORE_EXCEPTION)); J_CC(CC_NZ, js.trampolineExceptionHandler); } return; @@ -71,7 +71,7 @@ void EmuCodeBlock::MemoryExceptionCheck() // exception check. if (m_jit.jo.memcheck && !js.fastmemLoadStore && !js.fixupExceptionHandler) { - TEST(32, PPCSTATE(Exceptions), Gen::Imm32(EXCEPTION_DSI)); + TEST(32, PPCSTATE(Exceptions), Gen::Imm32(ANY_LOADSTORE_EXCEPTION)); js.exceptionHandler = J_CC(Gen::CC_NZ, true); js.fixupExceptionHandler = true; } diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 5391d82ff289..503049b4babe 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -199,7 +199,8 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst) { ARM64Reg WA = gpr.GetReg(); LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); - FixupBranch noException = TBZ(WA, IntLog2(EXCEPTION_DSI)); + TSTI2R(WA, ANY_LOADSTORE_EXCEPTION); + FixupBranch noException = B(CCFlags::CC_EQ); FixupBranch handleException = B(); SwitchToFarCode(); diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index a7b35364ecdf..85647f2b04e3 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -445,14 +445,12 @@ static void Memcheck(u32 address, u32 var, bool write, size_t size) if (pause) { CPU::Break(); - // Fake a DSI so that all the code that tests for it in order to skip - // the rest of the instruction will apply. (This means that + // Fake an exception so that all the code that tests for it in order to + // skip the the rest of the instruction will apply. (This means that // watchpoints will stop the emulator before the offending load/store, // not after like GDB does, but that's better anyway. Just need to // make sure resuming after that works.) - // It doesn't matter if ReadFromHardware triggers its own DSI because - // we'll take it after resuming. - PowerPC::ppcState.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT; + PowerPC::ppcState.Exceptions |= EXCEPTION_FAKE_MEMCHECK_HIT; } } } diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp index 817276f8d716..4da70e44cc9a 100644 --- a/Source/Core/Core/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/PowerPC/PowerPC.cpp @@ -511,7 +511,7 @@ void CheckExceptions() } else if (exceptions & EXCEPTION_FAKE_MEMCHECK_HIT) { - ppcState.Exceptions &= ~EXCEPTION_DSI & ~EXCEPTION_FAKE_MEMCHECK_HIT; + ppcState.Exceptions &= ~EXCEPTION_FAKE_MEMCHECK_HIT; } else if (exceptions & EXCEPTION_DSI) {