diff --git a/Source/Core/Core/Src/HW/MemmapFunctions.cpp b/Source/Core/Core/Src/HW/MemmapFunctions.cpp index c32e5d5e3b..a25e00e8c4 100644 --- a/Source/Core/Core/Src/HW/MemmapFunctions.cpp +++ b/Source/Core/Core/Src/HW/MemmapFunctions.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "Common.h" +#include "Atomic.h" #include "GPFifo.h" #include "Memmap.h" @@ -605,7 +606,7 @@ void GenerateDSIException(u32 _EffectiveAddress, bool _bWrite) PowerPC::ppcState.spr[SPR_DAR] = _EffectiveAddress; - PowerPC::ppcState.Exceptions |= EXCEPTION_DSI; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DSI); } @@ -615,7 +616,7 @@ void GenerateISIException(u32 _EffectiveAddress) SRR1 = (1 << 30) | (MSR & 0x3fffff); NPC = _EffectiveAddress; - PowerPC::ppcState.Exceptions |= EXCEPTION_ISI; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_ISI); } diff --git a/Source/Core/Core/Src/HW/ProcessorInterface.cpp b/Source/Core/Core/Src/HW/ProcessorInterface.cpp index f3fa5b72d6..e0ffc2997a 100644 --- a/Source/Core/Core/Src/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/Src/HW/ProcessorInterface.cpp @@ -17,6 +17,7 @@ #include #include "Common.h" +#include "Atomic.h" #include "ChunkFile.h" #include "../PowerPC/PowerPC.h" @@ -155,7 +156,7 @@ void Write32(const u32 _uValue, const u32 _iAddress) switch(_iAddress & 0xFFF) { case PI_INTERRUPT_CAUSE: - m_InterruptCause &= ~_uValue; // writes turn them off + Common::AtomicAnd(m_InterruptCause, ~_uValue); // writes turn them off UpdateException(); return; @@ -203,9 +204,9 @@ void Write32(const u32 _uValue, const u32 _iAddress) void UpdateException() { if ((m_InterruptCause & m_InterruptMask) != 0) - PowerPC::ppcState.Exceptions |= EXCEPTION_EXTERNAL_INT; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_EXTERNAL_INT); else - PowerPC::ppcState.Exceptions &= ~EXCEPTION_EXTERNAL_INT; + Common::AtomicAnd(PowerPC::ppcState.Exceptions, ~EXCEPTION_EXTERNAL_INT); } static const char *Debug_GetInterruptName(u32 _causemask) @@ -247,9 +248,9 @@ void SetInterrupt(u32 _causemask, bool _bSet) } if (_bSet) - m_InterruptCause |= _causemask; + Common::AtomicOr(m_InterruptCause, _causemask); else - m_InterruptCause &= ~_causemask;// is there any reason to have this possibility? + Common::AtomicAnd(m_InterruptCause, ~_causemask);// is there any reason to have this possibility? // F|RES: i think the hw devices reset the interrupt in the PI to 0 // if the interrupt cause is eliminated. that isnt done by software (afaik) UpdateException(); @@ -258,9 +259,9 @@ void SetInterrupt(u32 _causemask, bool _bSet) void SetResetButton(bool _bSet) { if (_bSet) - m_InterruptCause &= ~INT_CAUSE_RST_BUTTON; + Common::AtomicAnd(m_InterruptCause, ~INT_CAUSE_RST_BUTTON); else - m_InterruptCause |= INT_CAUSE_RST_BUTTON; + Common::AtomicOr(m_InterruptCause, INT_CAUSE_RST_BUTTON); } void ToggleResetButtonCallback(u64 userdata, int cyclesLate) diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index 8482d30966..1b39eeaea1 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -58,6 +58,7 @@ IPC_HLE_PERIOD: For the Wiimote this is the call schedule: #include "Common.h" +#include "Atomic.h" #include "../PatchEngine.h" #include "SystemTimers.h" #include "../PluginManager.h" @@ -192,7 +193,7 @@ void DecrementerCallback(u64 userdata, int cyclesLate) // A: Because it's 64bit (0xffffffffffffffff)...? fakeDec = -1; PowerPC::ppcState.spr[SPR_DEC] = 0xFFFFFFFF; - PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DECREMENTER); } void DecrementerSet() diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp index a2f05a4b82..249fd69ad6 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp @@ -25,6 +25,7 @@ #include "../../ConfigManager.h" #include "PowerPCDisasm.h" #include "../../IPC_HLE/WII_IPC_HLE.h" +#include "Atomic.h" namespace { @@ -107,7 +108,7 @@ void Interpreter::SingleStepInner(void) } else { - PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE); PowerPC::CheckExceptions(); m_EndBlock = true; } diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp index bc5c8d9aa1..0fd810436b 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -19,6 +19,7 @@ #include "../../HW/CPU.h" #include "../../HLE/HLE.h" #include "../PPCAnalyst.h" +#include "Atomic.h" void Interpreter::bx(UGeckoInstruction _inst) { @@ -134,7 +135,7 @@ void Interpreter::rfid(UGeckoInstruction _inst) // We do it anyway, though :P void Interpreter::sc(UGeckoInstruction _inst) { - PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_SYSCALL); PowerPC::CheckExceptions(); m_EndBlock = true; } diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp index 4dd39d6143..743ff86431 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -17,6 +17,7 @@ #include "Interpreter.h" #include "../../Core.h" +#include "Atomic.h" void Interpreter::Helper_UpdateCR0(u32 _uValue) { @@ -174,7 +175,7 @@ void Interpreter::twi(UGeckoInstruction _inst) || (((u32)a <(u32)b) && (TO & 0x02)) || (((u32)a >(u32)b) && (TO & 0x01))) { - PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_PROGRAM); PowerPC::CheckExceptions(); m_EndBlock = true; // Dunno about this } @@ -402,7 +403,7 @@ void Interpreter::tw(UGeckoInstruction _inst) || (((u32)a <(u32)b) && (TO & 0x02)) || (((u32)a >(u32)b) && (TO & 0x01))) { - PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_PROGRAM); PowerPC::CheckExceptions(); m_EndBlock = true; // Dunno about this } diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp index 9e1346a8ad..831b2a399c 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "Common.h" +#include "Atomic.h" #include "MathUtil.h" #include "../../HW/Memmap.h" @@ -405,10 +406,10 @@ void Interpreter::eciwx(UGeckoInstruction _inst) if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000)) { - PowerPC::ppcState.Exceptions |= EXCEPTION_DSI; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DSI); } if (EA & 3) - PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_ALIGNMENT); // _assert_msg_(POWERPC,0,"eciwx - fill r%i with word @ %08x from device %02x", // _inst.RS, EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f); @@ -427,10 +428,10 @@ void Interpreter::ecowx(UGeckoInstruction _inst) if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000)) { - PowerPC::ppcState.Exceptions |= EXCEPTION_DSI; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DSI); } if (EA & 3) - PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_ALIGNMENT); // _assert_msg_(POWERPC,0,"ecowx - send stw request (%08x@%08x) to device %02x", // m_GPR[_inst.RS], EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f); diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 542206f8ef..22f923fbbf 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -36,6 +36,7 @@ static const unsigned short FPU_ROUND_MASK = 3 << 10; #endif #include "CPUDetect.h" +#include "Atomic.h" #include "../../CoreTiming.h" #include "../../HW/Memmap.h" #include "../../HW/GPFifo.h" @@ -413,7 +414,7 @@ void Interpreter::mtspr(UGeckoInstruction _inst) if (!(oldValue >> 31) && (m_GPR[_inst.RD]>>31)) //top bit from 0 to 1 { PanicAlert("Interesting - Software triggered Decrementer exception"); - PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER; + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DECREMENTER); } else { diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index b54e5aaec0..10a94effbd 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -562,7 +562,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc gpr.Flush(FLUSH_ALL); fpr.Flush(FLUSH_ALL); - TEST(32, M(&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_DSI)); + TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_DSI)); FixupBranch noMemException = J_CC(CC_Z); // If a memory exception occurs, the exception handler will read diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 198ee0233b..c8a2035790 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -55,7 +55,7 @@ #define MEMCHECK_START \ FixupBranch memException; \ if (js.memcheck) \ - { TEST(32, M(&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_DSI)); \ + { TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_DSI)); \ memException = J_CC(CC_NZ); } #define MEMCHECK_END \ diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp index cc8b6edfda..4515cd5a79 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp @@ -193,7 +193,8 @@ void Jit64AsmRoutineManager::Generate() //FP blocks test for FPU available, jump here if false fpException = AlignCode4(); - OR(32, M(&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE)); + LOCK(); + OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE)); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); MOV(32, R(EAX), M(&NPC)); MOV(32, M(&PC), R(EAX)); @@ -205,7 +206,7 @@ void Jit64AsmRoutineManager::Generate() ABI_CallFunction(reinterpret_cast(&CoreTiming::Advance)); testExceptions = GetCodePtr(); - TEST(32, M(&PowerPC::ppcState.Exceptions), Imm32(0xFFFFFFFF)); + TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(0xFFFFFFFF)); FixupBranch skipExceptions = J_CC(CC_Z); MOV(32, R(EAX), M(&PC)); MOV(32, M(&NPC), R(EAX)); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp index 146c1f0513..334f89eb82 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp @@ -48,7 +48,8 @@ void Jit64::sc(UGeckoInstruction inst) gpr.Flush(FLUSH_ALL); fpr.Flush(FLUSH_ALL); MOV(32, M(&PC), Imm32(js.compilerPC + 4)); - OR(32, M(&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_SYSCALL)); + LOCK(); + OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_SYSCALL)); WriteExceptionExit(); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index b288c07256..6367ee6090 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -1716,7 +1716,8 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak } case SystemCall: { unsigned InstLoc = ibuild->GetImmValue(getOp1(I)); - Jit->OR(32, M(&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_SYSCALL)); + Jit->LOCK(); + Jit->OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_SYSCALL)); Jit->MOV(32, M(&PC), Imm32(InstLoc + 4)); Jit->WriteExceptionExit(); break; @@ -1759,7 +1760,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak } case FPExceptionCheckEnd: { unsigned InstLoc = ibuild->GetImmValue(getOp1(I)); - Jit->TEST(32, M(&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_DSI)); + Jit->TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_DSI)); FixupBranch noMemException = Jit->J_CC(CC_Z); // If a memory exception occurs, the exception handler will read diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp index cd2708512f..adf215135d 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp @@ -197,7 +197,8 @@ void JitILAsmRoutineManager::Generate() fpException = AlignCode4(); MOV(32, R(EAX), M(&PC)); MOV(32, M(&NPC), R(EAX)); - OR(32, M(&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE)); + LOCK(); + OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE)); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); MOV(32, R(EAX), M(&NPC)); MOV(32, M(&PC), R(EAX)); @@ -209,7 +210,7 @@ void JitILAsmRoutineManager::Generate() ABI_CallFunction(reinterpret_cast(&CoreTiming::Advance)); testExceptions = GetCodePtr(); - TEST(32, M(&PowerPC::ppcState.Exceptions), Imm32(0xFFFFFFFF)); + TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(0xFFFFFFFF)); FixupBranch skipExceptions = J_CC(CC_Z); MOV(32, R(EAX), M(&PC)); MOV(32, M(&NPC), R(EAX)); diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index 064be3f87c..9632ea6b4d 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -18,6 +18,7 @@ #include #include "Common.h" +#include "Atomic.h" #include "MathUtil.h" #include "ChunkFile.h" @@ -262,8 +263,11 @@ void Stop() void CheckExceptions() { + // Read volatile data once + u32 exceptions = ppcState.Exceptions; + // This check is unnecessary in JIT mode. However, it probably doesn't really hurt. - if (!ppcState.Exceptions) + if (!exceptions) return; // gcemu uses the mask 0x87C0FFFF instead of 0x0780FF77 @@ -285,7 +289,7 @@ void CheckExceptions() // set to exception type entry point //NPC = 0x80000x00; - if (ppcState.Exceptions & EXCEPTION_ISI) + if (exceptions & EXCEPTION_ISI) { SRR0 = NPC; //GenerateISIException() sets up SRR1 @@ -294,9 +298,9 @@ void CheckExceptions() NPC = 0x80000400; INFO_LOG(POWERPC, "EXCEPTION_ISI"); - ppcState.Exceptions &= ~EXCEPTION_ISI; + Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_ISI); } - else if (ppcState.Exceptions & EXCEPTION_PROGRAM) + else if (exceptions & EXCEPTION_PROGRAM) { SRR0 = PC; SRR1 = MSR & 0x87C0FFFF; @@ -307,9 +311,9 @@ void CheckExceptions() NPC = 0x80000700; INFO_LOG(POWERPC, "EXCEPTION_PROGRAM"); - ppcState.Exceptions &= ~EXCEPTION_PROGRAM; + Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_PROGRAM); } - else if (ppcState.Exceptions & EXCEPTION_SYSCALL) + else if (exceptions & EXCEPTION_SYSCALL) { SRR0 = NPC; SRR1 = MSR & 0x87C0FFFF; @@ -318,9 +322,9 @@ void CheckExceptions() NPC = 0x80000C00; INFO_LOG(POWERPC, "EXCEPTION_SYSCALL (PC=%08x)", PC); - ppcState.Exceptions &= ~EXCEPTION_SYSCALL; + Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_SYSCALL); } - else if (ppcState.Exceptions & EXCEPTION_FPU_UNAVAILABLE) + else if (exceptions & EXCEPTION_FPU_UNAVAILABLE) { //This happens a lot - Gamecube OS uses deferred FPU context switching SRR0 = PC; // re-execute the instruction @@ -334,9 +338,9 @@ void CheckExceptions() NPC = 0x80000800; INFO_LOG(POWERPC, "EXCEPTION_FPU_UNAVAILABLE"); - ppcState.Exceptions &= ~EXCEPTION_FPU_UNAVAILABLE; + Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_FPU_UNAVAILABLE); } - else if (ppcState.Exceptions & EXCEPTION_DSI) + else if (exceptions & EXCEPTION_DSI) { SRR0 = PC; SRR1 = MSR & 0x87C0FFFF; @@ -346,9 +350,9 @@ void CheckExceptions() //DSISR and DAR regs are changed in GenerateDSIException() INFO_LOG(POWERPC, "EXCEPTION_DSI"); - ppcState.Exceptions &= ~EXCEPTION_DSI; + Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_DSI); } - else if (ppcState.Exceptions & EXCEPTION_ALIGNMENT) + else if (exceptions & EXCEPTION_ALIGNMENT) { //This never happens ATM // perhaps we can get dcb* instructions to use this :p @@ -361,13 +365,13 @@ void CheckExceptions() //TODO crazy amount of DSISR options to check out INFO_LOG(POWERPC, "EXCEPTION_ALIGNMENT"); - ppcState.Exceptions &= ~EXCEPTION_ALIGNMENT; + Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_ALIGNMENT); } // EXTERNAL INTERRUPT else if (MSR & 0x0008000) //hacky...the exception shouldn't be generated if EE isn't set... { - if (ppcState.Exceptions & EXCEPTION_EXTERNAL_INT) + if (exceptions & EXCEPTION_EXTERNAL_INT) { // Pokemon gets this "too early", it hasn't a handler yet SRR0 = NPC; @@ -377,11 +381,11 @@ void CheckExceptions() NPC = 0x80000500; INFO_LOG(POWERPC, "EXCEPTION_EXTERNAL_INT"); - ppcState.Exceptions &= ~EXCEPTION_EXTERNAL_INT; + Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_EXTERNAL_INT); _dbg_assert_msg_(POWERPC, (SRR1 & 0x02) != 0, "GEKKO", "EXTERNAL_INT unrecoverable???"); } - else if (ppcState.Exceptions & EXCEPTION_DECREMENTER) + else if (exceptions & EXCEPTION_DECREMENTER) { SRR0 = NPC; SRR1 = MSR & 0x87C0FFFF; @@ -390,12 +394,12 @@ void CheckExceptions() NPC = 0x80000900; INFO_LOG(POWERPC, "EXCEPTION_DECREMENTER"); - ppcState.Exceptions &= ~EXCEPTION_DECREMENTER; + Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_DECREMENTER); } else { - _dbg_assert_msg_(POWERPC, 0, "Unknown EXT interrupt: Exceptions == %08x", ppcState.Exceptions); - ERROR_LOG(POWERPC, "Unknown EXTERNAL INTERRUPT exception: Exceptions == %08x", ppcState.Exceptions); + _dbg_assert_msg_(POWERPC, 0, "Unknown EXT interrupt: Exceptions == %08x", exceptions); + ERROR_LOG(POWERPC, "Unknown EXTERNAL INTERRUPT exception: Exceptions == %08x", exceptions); } } } diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.h b/Source/Core/Core/Src/PowerPC/PowerPC.h index 0543903fac..532f65bd42 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.h +++ b/Source/Core/Core/Src/PowerPC/PowerPC.h @@ -59,7 +59,7 @@ struct GC_ALIGNED64(PowerPCState) u32 fpscr; // floating point flags/status bits // Exception management. - u32 Exceptions; + volatile u32 Exceptions; u32 sr[16]; // Segment registers.