diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index c266d31189..e268c66bfd 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -352,7 +352,7 @@ static void CpuThread() if (!s_state_filename.empty()) { // Needs to PauseAndLock the Core - // NOTE: EmuThread should have left us in CPU_STEPPING so nothing will happen + // NOTE: EmuThread should have left us in State::Stepping so nothing will happen // until after the job is serviced. QueueHostJob([] { // Recheck in case Movie cleared it since. @@ -431,11 +431,11 @@ static void FifoPlayerThread() // If we did not enter the CPU Run Loop above then run a fake one instead. // We need to be IsRunningAndStarted() for DolphinWX to stop us. - if (CPU::GetState() != CPU::CPU_POWERDOWN) + if (CPU::GetState() != CPU::State::PowerDown) { s_is_started = true; Host_Message(WM_USER_STOP); - while (CPU::GetState() != CPU::CPU_POWERDOWN) + while (CPU::GetState() != CPU::State::PowerDown) { if (!_CoreParameter.bCPUThread) g_video_backend->PeekMessages(); @@ -594,7 +594,7 @@ void EmuThread() // Spawn the CPU+GPU thread s_cpu_thread = std::thread(cpuThreadFunc); - while (CPU::GetState() != CPU::CPU_POWERDOWN) + while (CPU::GetState() != CPU::State::PowerDown) { g_video_backend->PeekMessages(); Common::SleepCurrentThread(20); diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp index b6e7ab60ef..e4d4d34396 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp @@ -99,19 +99,22 @@ public: const char* GetName() override { return "FifoPlayer"; } void Run() override { - while (CPU::GetState() == CPU::CPU_RUNNING) + while (CPU::GetState() == CPU::State::Running) { switch (m_parent->AdvanceFrame()) { - case CPU::CPU_POWERDOWN: + case CPU::State::PowerDown: CPU::Break(); Host_Message(WM_USER_STOP); break; - case CPU::CPU_STEPPING: + case CPU::State::Stepping: CPU::Break(); Host_UpdateMainFrame(); break; + + case CPU::State::Running: + break; } } } @@ -120,15 +123,15 @@ private: FifoPlayer* m_parent; }; -int FifoPlayer::AdvanceFrame() +CPU::State FifoPlayer::AdvanceFrame() { if (m_CurrentFrame >= m_FrameRangeEnd) { if (!m_Loop) - return CPU::CPU_POWERDOWN; + return CPU::State::PowerDown; // If there are zero frames in the range then sleep instead of busy spinning if (m_FrameRangeStart >= m_FrameRangeEnd) - return CPU::CPU_STEPPING; + return CPU::State::Stepping; // When looping, reload the contents of all the BP/CP/CF registers. // This ensures that each time the first frame is played back, the state of the @@ -148,7 +151,7 @@ int FifoPlayer::AdvanceFrame() WriteFrame(m_File->GetFrame(m_CurrentFrame), m_FrameInfo[m_CurrentFrame]); ++m_CurrentFrame; - return CPU::CPU_RUNNING; + return CPU::State::Running; } std::unique_ptr FifoPlayer::GetCPUCore() diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.h b/Source/Core/Core/FifoPlayer/FifoPlayer.h index 1751a2f997..b291415ead 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.h +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.h @@ -16,6 +16,11 @@ class FifoDataFile; struct MemoryUpdate; struct AnalyzedFrameInfo; +namespace CPU +{ +enum class State; +} + // Story time: // When FifoRecorder was created, efb copies weren't really used or they used efb2tex which ignored // the underlying memory, so FifoRecorder didn't do anything special about the memory backing efb @@ -94,7 +99,7 @@ private: FifoPlayer(); - int AdvanceFrame(); + CPU::State AdvanceFrame(); void WriteFrame(const FifoFrameInfo& frame, const AnalyzedFrameInfo& info); void WriteFramePart(u32 dataStart, u32 dataEnd, u32& nextMemUpdate, const FifoFrameInfo& frame, diff --git a/Source/Core/Core/HW/CPU.cpp b/Source/Core/Core/HW/CPU.cpp index 8bd8ae8787..a57e1cb1a1 100644 --- a/Source/Core/Core/HW/CPU.cpp +++ b/Source/Core/Core/HW/CPU.cpp @@ -22,7 +22,7 @@ namespace CPU // CPU Thread execution state. // Requires s_state_change_lock to modify the value. // Read access is unsynchronized. -static State s_state = CPU_POWERDOWN; +static State s_state = State::PowerDown; // Synchronizes EnableStepping and PauseAndLock so only one instance can be // active at a time. Simplifies code by eliminating several edge cases where @@ -50,7 +50,7 @@ static Common::Event* s_state_cpu_step_instruction_sync = nullptr; void Init(int cpu_core) { PowerPC::Init(cpu_core); - s_state = CPU_STEPPING; + s_state = State::Stepping; } void Shutdown() @@ -73,13 +73,13 @@ static void FlushStepSyncEventLocked() void Run() { std::unique_lock state_lock(s_state_change_lock); - while (s_state != CPU_POWERDOWN) + while (s_state != State::PowerDown) { s_state_cpu_cvar.wait(state_lock, [] { return !s_state_paused_and_locked; }); switch (s_state) { - case CPU_RUNNING: + case State::Running: s_state_cpu_thread_active = true; state_lock.unlock(); @@ -91,12 +91,12 @@ void Run() { if (PowerPC::breakpoints.IsAddressBreakPoint(PC) || PowerPC::memchecks.HasAny()) { - s_state = CPU_STEPPING; + s_state = State::Stepping; PowerPC::CoreMode old_mode = PowerPC::GetMode(); PowerPC::SetMode(PowerPC::CoreMode::Interpreter); PowerPC::SingleStep(); PowerPC::SetMode(old_mode); - s_state = CPU_RUNNING; + s_state = State::Running; } } @@ -108,11 +108,11 @@ void Run() s_state_cpu_idle_cvar.notify_all(); break; - case CPU_STEPPING: + case State::Stepping: // Wait for step command. s_state_cpu_cvar.wait(state_lock, - [] { return s_state_cpu_step_instruction || s_state != CPU_STEPPING; }); - if (s_state != CPU_STEPPING) + [] { return s_state_cpu_step_instruction || !IsStepping(); }); + if (!IsStepping()) { // Signal event if the mode changes. FlushStepSyncEventLocked(); @@ -136,7 +136,7 @@ void Run() Host_UpdateDisasmDialog(); break; - case CPU_POWERDOWN: + case State::PowerDown: break; } } @@ -155,10 +155,10 @@ static void RunAdjacentSystems(bool running) void Stop() { // Change state and wait for it to be acknowledged. - // We don't need the stepping lock because CPU_POWERDOWN is a priority state which + // We don't need the stepping lock because State::PowerDown is a priority state which // will stick permanently. std::unique_lock state_lock(s_state_change_lock); - s_state = CPU_POWERDOWN; + s_state = State::PowerDown; s_state_cpu_cvar.notify_one(); while (s_state_cpu_thread_active) @@ -175,7 +175,7 @@ void Stop() bool IsStepping() { - return s_state == CPU_STEPPING; + return s_state == State::Stepping; } State GetState() @@ -215,7 +215,7 @@ void StepOpcode(Common::Event* event) // Requires s_state_change_lock static bool SetStateLocked(State s) { - if (s_state == CPU_POWERDOWN) + if (s_state == State::PowerDown) return false; s_state = s; return true; @@ -228,7 +228,7 @@ void EnableStepping(bool stepping) if (stepping) { - SetStateLocked(CPU_STEPPING); + SetStateLocked(State::Stepping); while (s_state_cpu_thread_active) { @@ -240,7 +240,7 @@ void EnableStepping(bool stepping) RunAdjacentSystems(false); } - else if (SetStateLocked(CPU_RUNNING)) + else if (SetStateLocked(State::Running)) { s_state_cpu_cvar.notify_one(); RunAdjacentSystems(true); @@ -261,7 +261,7 @@ void Break() // We'll deadlock if we synchronize, the CPU may block waiting for our caller to // finish resulting in the CPU loop never terminating. - SetStateLocked(CPU_STEPPING); + SetStateLocked(State::Stepping); RunAdjacentSystems(false); } @@ -278,8 +278,8 @@ bool PauseAndLock(bool do_lock, bool unpause_on_unlock, bool control_adjacent) std::unique_lock state_lock(s_state_change_lock); s_state_paused_and_locked = true; - was_unpaused = s_state == CPU_RUNNING; - SetStateLocked(CPU_STEPPING); + was_unpaused = s_state == State::Running; + SetStateLocked(State::Stepping); while (s_state_cpu_thread_active) { @@ -316,7 +316,7 @@ bool PauseAndLock(bool do_lock, bool unpause_on_unlock, bool control_adjacent) { s_state_system_request_stepping = false; } - else if (unpause_on_unlock && SetStateLocked(CPU_RUNNING)) + else if (unpause_on_unlock && SetStateLocked(State::Running)) { was_unpaused = true; } @@ -324,7 +324,7 @@ bool PauseAndLock(bool do_lock, bool unpause_on_unlock, bool control_adjacent) s_state_cpu_cvar.notify_one(); if (control_adjacent) - RunAdjacentSystems(s_state == CPU_RUNNING); + RunAdjacentSystems(s_state == State::Running); } s_stepping_lock.unlock(); } diff --git a/Source/Core/Core/HW/CPU.h b/Source/Core/Core/HW/CPU.h index 390f12f58a..280db7f500 100644 --- a/Source/Core/Core/HW/CPU.h +++ b/Source/Core/Core/HW/CPU.h @@ -11,11 +11,11 @@ class Event; namespace CPU { -enum State +enum class State { - CPU_RUNNING = 0, - CPU_STEPPING = 2, - CPU_POWERDOWN = 3 + Running = 0, + Stepping = 2, + PowerDown = 3 }; // Init @@ -29,7 +29,7 @@ void Shutdown(); void Run(); // Causes shutdown -// Once started, CPU_POWERDOWN cannot be stopped. +// Once started, State::PowerDown cannot be stopped. // Synchronizes with the CPU Thread (waits for CPU::Run to exit). void Stop(); @@ -48,8 +48,8 @@ void EnableStepping(bool stepping); // should not be used by the Host. void Break(); -// Shorthand for GetState() == CPU_STEPPING. -// WARNING: CPU_POWERDOWN will return false, not just CPU_RUNNING. +// Shorthand for GetState() == State::Stepping. +// WARNING: State::PowerDown will return false, not just State::Running. bool IsStepping(); // Get current CPU Thread State @@ -63,8 +63,8 @@ const volatile State* GetStatePtr(); // While this lock is held, the CPU Thread will not perform any action so it is safe to access // PowerPC::ppcState, CoreTiming, etc. without racing the CPU Thread. // Cannot be used recursively. Must be paired as PauseAndLock(true)/PauseAndLock(false). -// Return value for do_lock == true is whether the state was CPU_RUNNING or not. -// Return value for do_lock == false is whether the state was changed *to* CPU_RUNNING or not. +// Return value for do_lock == true is whether the state was State::Running or not. +// Return value for do_lock == false is whether the state was changed *to* State::Running or not. // Cannot be used by System threads as it will deadlock. It is threadsafe otherwise. // "control_adjacent" causes PauseAndLock to behave like EnableStepping by modifying the // state of the Audio and FIFO subsystems as well. diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index 9e4ef23607..3bba028fc0 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -1344,7 +1344,7 @@ void EndPlayInput(bool cont) } else if (s_playMode != MODE_NONE) { - // We can be called by EmuThread during boot (CPU_POWERDOWN) + // We can be called by EmuThread during boot (CPU::State::PowerDown) bool was_running = Core::IsRunningAndStarted() && !CPU::IsStepping(); if (was_running) CPU::Break(); diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp index 258c3af095..313e102f5c 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp @@ -107,7 +107,7 @@ void CachedInterpreter::ExecuteOneBlock() void CachedInterpreter::Run() { - while (CPU::GetState() == CPU::CPU_RUNNING) + while (CPU::GetState() == CPU::State::Running) { // Start new timing slice // NOTE: Exceptions may change PC diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index fa08d55252..5972014463 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -224,7 +224,7 @@ int ShowSteps = 300; // FastRun - inspired by GCemu (to imitate the JIT so that they can be compared). void Interpreter::Run() { - while (!CPU::GetState()) + while (CPU::GetState() == CPU::State::Running) { // CoreTiming Advance() ends the previous slice and declares the start of the next // one so it must always be called at the start. At boot, we are in slice -1 and must diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 6d506b3d06..e157994416 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -583,7 +583,7 @@ void Jit64::Jit(u32 em_address) // Comment out the following to disable breakpoints (speed-up) if (!Profiler::g_ProfileBlocks) { - if (CPU::GetState() == CPU::CPU_STEPPING) + if (CPU::IsStepping()) { blockSize = 1; @@ -841,7 +841,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc } if (SConfig::GetInstance().bEnableDebugging && - breakpoints.IsAddressBreakPoint(ops[i].address) && CPU::GetState() != CPU::CPU_STEPPING) + breakpoints.IsAddressBreakPoint(ops[i].address) && !CPU::IsStepping()) { // Turn off block linking if there are breakpoints so that the Step Over command does not // link this block. diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp index 443f63f229..cc47c1d695 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp @@ -84,7 +84,7 @@ void Jit64AsmRoutineManager::Generate() if (SConfig::GetInstance().bEnableDebugging) { - TEST(32, M(CPU::GetStatePtr()), Imm32(CPU::CPU_STEPPING)); + TEST(32, M(CPU::GetStatePtr()), Imm32(static_cast(CPU::State::Stepping))); FixupBranch notStepping = J_CC(CC_Z); ABI_PushRegistersAndAdjustStack({}, 0); ABI_CallFunction(PowerPC::CheckBreakPoints); diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp index 74d41076ba..bc770da4ea 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp @@ -119,7 +119,7 @@ void Jit64::lXXx(UGeckoInstruction inst) signExtend = true; } - if (CPU::GetState() != CPU::CPU_STEPPING && inst.OPCD == 32 && CanMergeNextInstructions(2) && + if (!CPU::IsStepping() && inst.OPCD == 32 && CanMergeNextInstructions(2) && (inst.hex & 0xFFFF0000) == 0x800D0000 && (js.op[1].inst.hex == 0x28000000 || (SConfig::GetInstance().bWii && js.op[1].inst.hex == 0x2C000000)) && diff --git a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp index c2200791f2..b94b8a486f 100644 --- a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp @@ -487,7 +487,7 @@ void JitIL::Jit(u32 em_address) // Comment out the following to disable breakpoints (speed-up) if (!Profiler::g_ProfileBlocks) { - if (CPU::GetState() == CPU::CPU_STEPPING) + if (CPU::IsStepping()) { blockSize = 1; @@ -638,7 +638,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBloc } if (SConfig::GetInstance().bEnableDebugging && - breakpoints.IsAddressBreakPoint(ops[i].address) && CPU::GetState() != CPU::CPU_STEPPING) + breakpoints.IsAddressBreakPoint(ops[i].address) && !CPU::IsStepping()) { // Turn off block linking if there are breakpoints so that the Step Over command does not // link this block. diff --git a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp index 700a43ae99..8c105c4cc1 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp @@ -66,7 +66,7 @@ void JitArm64::GenerateAsm() // } while (PowerPC::ppcState.downcount > 0); // doTiming: // NPC = PC = DISPATCHER_PC; - // } while (CPU::GetState() == CPU::CPU_RUNNING); + // } while (CPU::GetState() == CPU::State::Running); AlignCodePage(); dispatcher = GetCodePtr(); WARN_LOG(DYNA_REC, "Dispatcher is %p", dispatcher); diff --git a/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp b/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp index 5965974165..aa111117b6 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp @@ -29,7 +29,7 @@ JitBase::~JitBase() = default; bool JitBase::CanMergeNextInstructions(int count) const { - if (CPU::GetState() == CPU::CPU_STEPPING || js.instructionsLeft < count) + if (CPU::IsStepping() || js.instructionsLeft < count) return false; // Be careful: a breakpoint kills flags in between instructions for (int i = 1; i <= count; i++) diff --git a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp index 99f38b2b18..a1efb94111 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitILCommon/JitILBase_LoadStore.cpp @@ -57,7 +57,7 @@ void JitILBase::lXz(UGeckoInstruction inst) // TODO: This really should be done somewhere else. Either lower in the IR // or higher in PPCAnalyst // TODO: We shouldn't use debug reads here. - if (CPU::GetState() != CPU::CPU_STEPPING && inst.OPCD == 32 && // Lwx + if (!CPU::IsStepping() && inst.OPCD == 32 && // Lwx (inst.hex & 0xFFFF0000) == 0x800D0000 && (PowerPC::HostRead_U32(js.compilerPC + 4) == 0x28000000 || (SConfig::GetInstance().bWii && PowerPC::HostRead_U32(js.compilerPC + 4) == 0x2C000000)) && diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp index b7c91f3de2..2b950f28a3 100644 --- a/Source/Core/Core/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/PowerPC/PowerPC.cpp @@ -210,11 +210,15 @@ void Reset() void ScheduleInvalidateCacheThreadSafe(u32 address) { - if (CPU::GetState() == CPU::State::CPU_RUNNING) + if (CPU::GetState() == CPU::State::Running) + { CoreTiming::ScheduleEvent(0, s_invalidate_cache_thread_safe, address, CoreTiming::FromThread::NON_CPU); + } else + { PowerPC::ppcState.iCache.Invalidate(static_cast(address)); + } } void Shutdown() diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 808083a653..d323c7918d 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -152,7 +152,7 @@ const char* GetCPUName(); // Init() will be called when added and Shutdown() when removed. // [Threadsafety: Same as SetMode(), except it cannot be called from inside the CPU // run loop on the CPU Thread - it doesn't make sense for a CPU to remove itself -// while it is CPU_RUNNING] +// while it is in State::Running] void InjectExternalCPUCore(CPUCoreBase* core); // Stepping requires the CPU Execution lock (CPU::PauseAndLock or CPU Thread)