From 18f8ae37ab1091f104114489a4a8371d94b9475c Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 28 Mar 2023 20:39:02 +0200 Subject: [PATCH 1/7] PowerPC/Expression: Pass System to EvaluateCondition(). --- Source/Core/Core/PowerPC/BreakPoints.cpp | 7 ++++--- Source/Core/Core/PowerPC/BreakPoints.h | 4 ++-- Source/Core/Core/PowerPC/Expression.cpp | 23 ++++++++++++----------- Source/Core/Core/PowerPC/Expression.h | 11 ++++++----- Source/Core/Core/PowerPC/MMU.cpp | 3 ++- Source/Core/Core/PowerPC/PowerPC.cpp | 2 +- 6 files changed, 27 insertions(+), 23 deletions(-) diff --git a/Source/Core/Core/PowerPC/BreakPoints.cpp b/Source/Core/Core/PowerPC/BreakPoints.cpp index fd30da2b91..473871e74f 100644 --- a/Source/Core/Core/PowerPC/BreakPoints.cpp +++ b/Source/Core/Core/PowerPC/BreakPoints.cpp @@ -16,6 +16,7 @@ #include "Core/PowerPC/Expression.h" #include "Core/PowerPC/JitInterface.h" #include "Core/PowerPC/MMU.h" +#include "Core/PowerPC/PowerPC.h" #include "Core/System.h" bool BreakPoints::IsAddressBreakPoint(u32 address) const @@ -352,14 +353,14 @@ bool MemChecks::OverlapsMemcheck(u32 address, u32 length) const }); } -bool TMemCheck::Action(Common::DebugInterface* debug_interface, u64 value, u32 addr, bool write, - size_t size, u32 pc) +bool TMemCheck::Action(Core::System& system, Common::DebugInterface* debug_interface, u64 value, + u32 addr, bool write, size_t size, u32 pc) { if (!is_enabled) return false; if (((write && is_break_on_write) || (!write && is_break_on_read)) && - EvaluateCondition(this->condition)) + EvaluateCondition(system, this->condition)) { if (log_on_hit) { diff --git a/Source/Core/Core/PowerPC/BreakPoints.h b/Source/Core/Core/PowerPC/BreakPoints.h index 0be6981ebe..111e1bb365 100644 --- a/Source/Core/Core/PowerPC/BreakPoints.h +++ b/Source/Core/Core/PowerPC/BreakPoints.h @@ -45,8 +45,8 @@ struct TMemCheck std::optional condition; // returns whether to break - bool Action(Common::DebugInterface* debug_interface, u64 value, u32 addr, bool write, size_t size, - u32 pc); + bool Action(Core::System& system, Common::DebugInterface* debug_interface, u64 value, u32 addr, + bool write, size_t size, u32 pc); }; // Code breakpoints. diff --git a/Source/Core/Core/PowerPC/Expression.cpp b/Source/Core/Core/PowerPC/Expression.cpp index bd089e3a01..2fe2d8c036 100644 --- a/Source/Core/Core/PowerPC/Expression.cpp +++ b/Source/Core/Core/PowerPC/Expression.cpp @@ -267,21 +267,22 @@ std::optional Expression::TryParse(std::string_view text) return Expression{text, std::move(ex), std::move(vars)}; } -double Expression::Evaluate() const +double Expression::Evaluate(Core::System& system) const { - SynchronizeBindings(SynchronizeDirection::From); + SynchronizeBindings(system, SynchronizeDirection::From); double result = expr_eval(m_expr.get()); - SynchronizeBindings(SynchronizeDirection::To); + SynchronizeBindings(system, SynchronizeDirection::To); Reporting(result); return result; } -void Expression::SynchronizeBindings(SynchronizeDirection dir) const +void Expression::SynchronizeBindings(Core::System& system, SynchronizeDirection dir) const { + auto& ppc_state = system.GetPPCState(); auto bind = m_binds.begin(); for (auto* v = m_vars->head; v != nullptr; v = v->next, ++bind) { @@ -293,25 +294,25 @@ void Expression::SynchronizeBindings(SynchronizeDirection dir) const break; case VarBindingType::GPR: if (dir == SynchronizeDirection::From) - v->value = static_cast(PowerPC::ppcState.gpr[bind->index]); + v->value = static_cast(ppc_state.gpr[bind->index]); else - PowerPC::ppcState.gpr[bind->index] = static_cast(static_cast(v->value)); + ppc_state.gpr[bind->index] = static_cast(static_cast(v->value)); break; case VarBindingType::FPR: if (dir == SynchronizeDirection::From) - v->value = PowerPC::ppcState.ps[bind->index].PS0AsDouble(); + v->value = ppc_state.ps[bind->index].PS0AsDouble(); else - PowerPC::ppcState.ps[bind->index].SetPS0(v->value); + ppc_state.ps[bind->index].SetPS0(v->value); break; case VarBindingType::SPR: if (dir == SynchronizeDirection::From) - v->value = static_cast(PowerPC::ppcState.spr[bind->index]); + v->value = static_cast(ppc_state.spr[bind->index]); else - PowerPC::ppcState.spr[bind->index] = static_cast(static_cast(v->value)); + ppc_state.spr[bind->index] = static_cast(static_cast(v->value)); break; case VarBindingType::PCtr: if (dir == SynchronizeDirection::From) - v->value = static_cast(PowerPC::ppcState.pc); + v->value = static_cast(ppc_state.pc); break; } } diff --git a/Source/Core/Core/PowerPC/Expression.h b/Source/Core/Core/PowerPC/Expression.h index 2c96e04f44..d9799caa82 100644 --- a/Source/Core/Core/PowerPC/Expression.h +++ b/Source/Core/Core/PowerPC/Expression.h @@ -15,7 +15,8 @@ struct expr_var_list; namespace Core { class CPUThreadGuard; -} +class System; +} // namespace Core struct ExprDeleter { @@ -36,7 +37,7 @@ class Expression public: static std::optional TryParse(std::string_view text); - double Evaluate() const; + double Evaluate(Core::System& system) const; std::string GetText() const; @@ -64,7 +65,7 @@ private: Expression(std::string_view text, ExprPointer ex, ExprVarListPointer vars); - void SynchronizeBindings(SynchronizeDirection dir) const; + void SynchronizeBindings(Core::System& system, SynchronizeDirection dir) const; void Reporting(const double result) const; std::string m_text; @@ -73,7 +74,7 @@ private: std::vector m_binds; }; -inline bool EvaluateCondition(const std::optional& condition) +inline bool EvaluateCondition(Core::System& system, const std::optional& condition) { - return !condition || condition->Evaluate() != 0.0; + return !condition || condition->Evaluate(system) != 0.0; } diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index 92786beec6..bfbc25c655 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -545,7 +545,8 @@ void MMU::Memcheck(u32 address, u64 var, bool write, size_t size) mc->num_hits++; - const bool pause = mc->Action(&debug_interface, var, address, write, size, m_ppc_state.pc); + const bool pause = + mc->Action(m_system, &debug_interface, var, address, write, size, m_ppc_state.pc); if (!pause) return; diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp index fef24a482a..6f18fad090 100644 --- a/Source/Core/Core/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/PowerPC/PowerPC.cpp @@ -645,7 +645,7 @@ void CheckBreakPoints() { const TBreakPoint* bp = PowerPC::breakpoints.GetBreakpoint(PowerPC::ppcState.pc); - if (!bp || !bp->is_enabled || !EvaluateCondition(bp->condition)) + if (!bp || !bp->is_enabled || !EvaluateCondition(Core::System::GetInstance(), bp->condition)) return; if (bp->break_on_hit) From aec3a882d7a875e45f97279d4ced3d3140a7cc87 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 28 Mar 2023 21:47:38 +0200 Subject: [PATCH 2/7] PowerPC/JitInterface: Access PowerPCState through System. --- Source/Core/Core/PowerPC/JitInterface.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp index 084064ceaf..750d3b6d65 100644 --- a/Source/Core/Core/PowerPC/JitInterface.cpp +++ b/Source/Core/Core/PowerPC/JitInterface.cpp @@ -163,14 +163,13 @@ JitInterface::GetHostCode(u32 address) const return GetHostCodeError::NoJitActive; } - JitBlock* block = - m_jit->GetBlockCache()->GetBlockFromStartAddress(address, PowerPC::ppcState.msr.Hex); + auto& ppc_state = m_system.GetPPCState(); + JitBlock* block = m_jit->GetBlockCache()->GetBlockFromStartAddress(address, ppc_state.msr.Hex); if (!block) { for (int i = 0; i < 500; i++) { - block = m_jit->GetBlockCache()->GetBlockFromStartAddress(address - 4 * i, - PowerPC::ppcState.msr.Hex); + block = m_jit->GetBlockCache()->GetBlockFromStartAddress(address - 4 * i, ppc_state.msr.Hex); if (block) break; } @@ -287,25 +286,26 @@ void JitInterface::CompileExceptionCheck(ExceptionType type) break; } - if (PowerPC::ppcState.pc != 0 && - (exception_addresses->find(PowerPC::ppcState.pc)) == (exception_addresses->end())) + auto& ppc_state = m_system.GetPPCState(); + if (ppc_state.pc != 0 && + (exception_addresses->find(ppc_state.pc)) == (exception_addresses->end())) { if (type == ExceptionType::FIFOWrite) { ASSERT(Core::IsCPUThread()); - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); // Check in case the code has been replaced since: do we need to do this? const OpType optype = - PPCTables::GetOpInfo(PowerPC::MMU::HostRead_U32(guard, PowerPC::ppcState.pc))->type; + PPCTables::GetOpInfo(PowerPC::MMU::HostRead_U32(guard, ppc_state.pc))->type; if (optype != OpType::Store && optype != OpType::StoreFP && optype != OpType::StorePS) return; } - exception_addresses->insert(PowerPC::ppcState.pc); + exception_addresses->insert(ppc_state.pc); // Invalidate the JIT block so that it gets recompiled with the external exception check // included. - m_jit->GetBlockCache()->InvalidateICache(PowerPC::ppcState.pc, 4, true); + m_jit->GetBlockCache()->InvalidateICache(ppc_state.pc, 4, true); } } From 6018daa3fa05542b0f97da43fb4b97722c03e224 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 28 Mar 2023 21:48:22 +0200 Subject: [PATCH 3/7] PowerPC/PPCCache: Access PowerPCState through System. --- Source/Core/Core/PowerPC/PPCCache.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/PowerPC/PPCCache.cpp b/Source/Core/Core/PowerPC/PPCCache.cpp index 7818dcb616..d159eba1f2 100644 --- a/Source/Core/Core/PowerPC/PPCCache.cpp +++ b/Source/Core/Core/PowerPC/PPCCache.cpp @@ -392,19 +392,21 @@ void Cache::DoState(PointerWrap& p) u32 InstructionCache::ReadInstruction(u32 addr) { auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); + auto& ppc_state = system.GetPPCState(); - if (!HID0(PowerPC::ppcState).ICE || m_disable_icache) // instruction cache is disabled - return memory.Read_U32(addr); + if (!HID0(ppc_state).ICE || m_disable_icache) // instruction cache is disabled + return system.GetMemory().Read_U32(addr); u32 value; - Read(addr, &value, sizeof(value), HID0(PowerPC::ppcState).ILOCK); + Read(addr, &value, sizeof(value), HID0(ppc_state).ILOCK); return Common::swap32(value); } void InstructionCache::Invalidate(u32 addr) { - if (!HID0(PowerPC::ppcState).ICE || m_disable_icache) + auto& system = Core::System::GetInstance(); + auto& ppc_state = system.GetPPCState(); + if (!HID0(ppc_state).ICE || m_disable_icache) return; // Invalidates the whole set @@ -424,7 +426,7 @@ void InstructionCache::Invalidate(u32 addr) valid[set] = 0; modified[set] = 0; - Core::System::GetInstance().GetJitInterface().InvalidateICacheLine(addr); + system.GetJitInterface().InvalidateICacheLine(addr); } void InstructionCache::RefreshConfig() From e5941428d138e96c6dfb2832bb14bf402debd18b Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 28 Mar 2023 21:59:39 +0200 Subject: [PATCH 4/7] PowerPC/PPCTables: Pass instruction address to GetOpInfo(). --- .../Core/PowerPC/Interpreter/Interpreter.cpp | 4 ++-- Source/Core/Core/PowerPC/JitCommon/JitBase.h | 2 +- Source/Core/Core/PowerPC/JitInterface.cpp | 2 +- Source/Core/Core/PowerPC/PPCAnalyst.cpp | 10 +++++----- Source/Core/Core/PowerPC/PPCTables.cpp | 20 +++++++++---------- Source/Core/Core/PowerPC/PPCTables.h | 8 ++++---- Source/Core/DolphinQt/MenuBar.cpp | 2 +- 7 files changed, 23 insertions(+), 25 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index c41635c7e6..b4ba4e777d 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -120,13 +120,13 @@ int Interpreter::SingleStepInner() // TODO: Does it make sense to use m_prev_inst here? // It seems like we should use the num_cycles for the instruction at PC instead // (m_prev_inst has not yet been updated) - return PPCTables::GetOpInfo(m_prev_inst)->num_cycles; + return PPCTables::GetOpInfo(m_prev_inst, m_ppc_state.pc)->num_cycles; } m_ppc_state.npc = m_ppc_state.pc + sizeof(UGeckoInstruction); m_prev_inst.hex = m_mmu.Read_Opcode(m_ppc_state.pc); - const GekkoOPInfo* opinfo = PPCTables::GetOpInfo(m_prev_inst); + const GekkoOPInfo* opinfo = PPCTables::GetOpInfo(m_prev_inst, m_ppc_state.pc); // Uncomment to trace the interpreter // if ((m_ppc_state.pc & 0x00FFFFFF) >= 0x000AB54C && diff --git a/Source/Core/Core/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/PowerPC/JitCommon/JitBase.h index fe9c7341b8..70c72ef105 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitBase.h +++ b/Source/Core/Core/PowerPC/JitCommon/JitBase.h @@ -32,7 +32,7 @@ struct PowerPCState; // Use these to control the instruction selection // #define INSTRUCTION_START FallBackToInterpreter(inst); return; -// #define INSTRUCTION_START PPCTables::CountInstruction(inst); +// #define INSTRUCTION_START PPCTables::CountInstruction(inst, m_ppc_state.pc); #define INSTRUCTION_START #define FALLBACK_IF(cond) \ diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp index 750d3b6d65..7ca17cbffc 100644 --- a/Source/Core/Core/PowerPC/JitInterface.cpp +++ b/Source/Core/Core/PowerPC/JitInterface.cpp @@ -297,7 +297,7 @@ void JitInterface::CompileExceptionCheck(ExceptionType type) // Check in case the code has been replaced since: do we need to do this? const OpType optype = - PPCTables::GetOpInfo(PowerPC::MMU::HostRead_U32(guard, ppc_state.pc))->type; + PPCTables::GetOpInfo(PowerPC::MMU::HostRead_U32(guard, ppc_state.pc), ppc_state.pc)->type; if (optype != OpType::Store && optype != OpType::StoreFP && optype != OpType::StorePS) return; } diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index 1d4f5fab2f..029aecb87b 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -114,7 +114,7 @@ bool AnalyzeFunction(const Core::CPUThreadGuard& guard, u32 startAddr, Common::S } const PowerPC::TryReadInstResult read_result = mmu.TryReadInstruction(addr); const UGeckoInstruction instr = read_result.hex; - if (read_result.valid && PPCTables::IsValidInstruction(instr)) + if (read_result.valid && PPCTables::IsValidInstruction(instr, addr)) { // BLR or RFI // 4e800021 is blrl, not the end of a function @@ -274,7 +274,7 @@ static void FindFunctionsFromBranches(const Core::CPUThreadGuard& guard, u32 sta const PowerPC::TryReadInstResult read_result = mmu.TryReadInstruction(addr); const UGeckoInstruction instr = read_result.hex; - if (read_result.valid && PPCTables::IsValidInstruction(instr)) + if (read_result.valid && PPCTables::IsValidInstruction(instr, addr)) { switch (instr.OPCD) { @@ -323,7 +323,7 @@ static void FindFunctionsFromHandlers(const Core::CPUThreadGuard& guard, PPCSymb for (const auto& entry : handlers) { const PowerPC::TryReadInstResult read_result = mmu.TryReadInstruction(entry.first); - if (read_result.valid && PPCTables::IsValidInstruction(read_result.hex)) + if (read_result.valid && PPCTables::IsValidInstruction(read_result.hex, entry.first)) { // Check if this function is already mapped Common::Symbol* f = func_db->AddFunction(guard, entry.first); @@ -357,7 +357,7 @@ static void FindFunctionsAfterReturnInstruction(const Core::CPUThreadGuard& guar location += 4; read_result = mmu.TryReadInstruction(location); } - if (read_result.valid && PPCTables::IsValidInstruction(read_result.hex)) + if (read_result.valid && PPCTables::IsValidInstruction(read_result.hex, location)) { // check if this function is already mapped Common::Symbol* f = func_db->AddFunction(guard, location); @@ -778,7 +778,7 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, num_inst++; const UGeckoInstruction inst = result.hex; - const GekkoOPInfo* opinfo = PPCTables::GetOpInfo(inst); + const GekkoOPInfo* opinfo = PPCTables::GetOpInfo(inst, address); code[i] = {}; code[i].opinfo = opinfo; code[i].address = address; diff --git a/Source/Core/Core/PowerPC/PPCTables.cpp b/Source/Core/Core/PowerPC/PPCTables.cpp index dcd4d8417e..bf9392516b 100644 --- a/Source/Core/Core/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/PowerPC/PPCTables.cpp @@ -613,7 +613,7 @@ constexpr Tables s_tables = []() consteval } (); -const GekkoOPInfo* GetOpInfo(UGeckoInstruction inst) +const GekkoOPInfo* GetOpInfo(UGeckoInstruction inst, u32 pc) { const GekkoOPInfo* info = &s_tables.all_instructions[s_tables.primary_table[inst.OPCD]]; if (info->type == OpType::Subtable) @@ -631,8 +631,7 @@ const GekkoOPInfo* GetOpInfo(UGeckoInstruction inst) case 63: return &s_tables.all_instructions[s_tables.table63[inst.SUBOP10]]; default: - ASSERT_MSG(POWERPC, 0, "GetOpInfo - invalid subtable op {:08x} @ {:08x}", inst.hex, - PowerPC::ppcState.pc); + ASSERT_MSG(POWERPC, 0, "GetOpInfo - invalid subtable op {:08x} @ {:08x}", inst.hex, pc); return &s_tables.all_instructions[s_tables.unknown_op_info]; } } @@ -640,8 +639,7 @@ const GekkoOPInfo* GetOpInfo(UGeckoInstruction inst) { if (info->type == OpType::Invalid) { - ASSERT_MSG(POWERPC, 0, "GetOpInfo - invalid op {:08x} @ {:08x}", inst.hex, - PowerPC::ppcState.pc); + ASSERT_MSG(POWERPC, 0, "GetOpInfo - invalid op {:08x} @ {:08x}", inst.hex, pc); return &s_tables.all_instructions[s_tables.unknown_op_info]; } return info; @@ -658,21 +656,21 @@ std::vector rsplocations; } #endif -const char* GetInstructionName(UGeckoInstruction inst) +const char* GetInstructionName(UGeckoInstruction inst, u32 pc) { - const GekkoOPInfo* info = GetOpInfo(inst); + const GekkoOPInfo* info = GetOpInfo(inst, pc); return info->opname; } -bool IsValidInstruction(UGeckoInstruction inst) +bool IsValidInstruction(UGeckoInstruction inst, u32 pc) { - const GekkoOPInfo* info = GetOpInfo(inst); + const GekkoOPInfo* info = GetOpInfo(inst, pc); return info->type != OpType::Invalid && info->type != OpType::Unknown; } -void CountInstruction(UGeckoInstruction inst) +void CountInstruction(UGeckoInstruction inst, u32 pc) { - const GekkoOPInfo* info = GetOpInfo(inst); + const GekkoOPInfo* info = GetOpInfo(inst, pc); info->stats->run_count++; } diff --git a/Source/Core/Core/PowerPC/PPCTables.h b/Source/Core/Core/PowerPC/PPCTables.h index 8d92f1811e..33a6e2a9fb 100644 --- a/Source/Core/Core/PowerPC/PPCTables.h +++ b/Source/Core/Core/PowerPC/PPCTables.h @@ -118,13 +118,13 @@ struct GekkoOPInfo namespace PPCTables { -const GekkoOPInfo* GetOpInfo(UGeckoInstruction inst); +const GekkoOPInfo* GetOpInfo(UGeckoInstruction inst, u32 pc); -bool IsValidInstruction(UGeckoInstruction inst); +bool IsValidInstruction(UGeckoInstruction inst, u32 pc); -void CountInstruction(UGeckoInstruction inst); +void CountInstruction(UGeckoInstruction inst, u32 pc); void CountInstructionCompile(const GekkoOPInfo* info, u32 pc); void PrintInstructionRunCounts(); void LogCompiledInstructions(); -const char* GetInstructionName(UGeckoInstruction inst); +const char* GetInstructionName(UGeckoInstruction inst, u32 pc); } // namespace PPCTables diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index 2677ac27d0..4d764f2fac 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -1699,7 +1699,7 @@ void MenuBar::SearchInstruction() addr += 4) { const auto ins_name = QString::fromStdString( - PPCTables::GetInstructionName(PowerPC::MMU::HostRead_U32(guard, addr))); + PPCTables::GetInstructionName(PowerPC::MMU::HostRead_U32(guard, addr), addr)); if (op == ins_name) { NOTICE_LOG_FMT(POWERPC, "Found {} at {:08x}", op.toStdString(), addr); From 192d8b6e40567338a84ef7a98a92561e53e198aa Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 28 Mar 2023 22:07:50 +0200 Subject: [PATCH 5/7] VideoCommon/CommandProcessor: Pass System to HandleUnknownOpcode(). --- Source/Core/VideoCommon/CommandProcessor.cpp | 8 +++++--- Source/Core/VideoCommon/CommandProcessor.h | 2 +- Source/Core/VideoCommon/OpcodeDecoding.cpp | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 75cedcf96f..3174c2983a 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -637,7 +637,8 @@ void CommandProcessorManager::SetCpClearRegister() { } -void CommandProcessorManager::HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess) +void CommandProcessorManager::HandleUnknownOpcode(Core::System& system, u8 cmd_byte, + const u8* buffer, bool preprocess) { const auto& fifo = m_fifo; @@ -665,6 +666,7 @@ void CommandProcessorManager::HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, // PC and LR are meaningless when using the fifoplayer, and will generally not be helpful if the // unknown opcode is inside of a display list. Also note that the changes in GPFifo.h are not // accurate and may introduce timing issues. + const auto& ppc_state = system.GetPPCState(); GENERIC_LOG_FMT( Common::Log::LogType::VIDEO, log_level, "FIFO: Unknown Opcode {:#04x} @ {}, preprocessing = {}, CPBase: {:#010x}, CPEnd: " @@ -686,8 +688,8 @@ void CommandProcessorManager::HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, fifo.bFF_Breakpoint.load(std::memory_order_relaxed) ? "true" : "false", fifo.bFF_GPLinkEnable.load(std::memory_order_relaxed) ? "true" : "false", fifo.bFF_HiWatermarkInt.load(std::memory_order_relaxed) ? "true" : "false", - fifo.bFF_LoWatermarkInt.load(std::memory_order_relaxed) ? "true" : "false", - PowerPC::ppcState.pc, LR(PowerPC::ppcState)); + fifo.bFF_LoWatermarkInt.load(std::memory_order_relaxed) ? "true" : "false", ppc_state.pc, + LR(ppc_state)); if (!m_is_fifo_error_seen && !suppress_panic_alert) { diff --git a/Source/Core/VideoCommon/CommandProcessor.h b/Source/Core/VideoCommon/CommandProcessor.h index 34b1e8701f..ccc381b535 100644 --- a/Source/Core/VideoCommon/CommandProcessor.h +++ b/Source/Core/VideoCommon/CommandProcessor.h @@ -177,7 +177,7 @@ public: void SetCpControlRegister(Core::System& system); void SetCpStatusRegister(Core::System& system); - void HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess); + void HandleUnknownOpcode(Core::System& system, u8 cmd_byte, const u8* buffer, bool preprocess); // This one is shared between gfx thread and emulator thread. // It is only used by the Fifo and by the CommandProcessor. diff --git a/Source/Core/VideoCommon/OpcodeDecoding.cpp b/Source/Core/VideoCommon/OpcodeDecoding.cpp index 9ffb59a277..4d43c6e66a 100644 --- a/Source/Core/VideoCommon/OpcodeDecoding.cpp +++ b/Source/Core/VideoCommon/OpcodeDecoding.cpp @@ -219,8 +219,8 @@ public: } else { - Core::System::GetInstance().GetCommandProcessor().HandleUnknownOpcode(opcode, data, - is_preprocess); + auto& system = Core::System::GetInstance(); + system.GetCommandProcessor().HandleUnknownOpcode(system, opcode, data, is_preprocess); m_cycles += 1; } } From 2d1f661118cda9b90318aef943afed086dbfc794 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 28 Mar 2023 23:52:36 +0200 Subject: [PATCH 6/7] DolphinQt: Avoid ppcState global. --- .../DolphinQt/Debugger/CodeViewWidget.cpp | 56 +++---- .../Core/DolphinQt/Debugger/CodeViewWidget.h | 5 +- Source/Core/DolphinQt/Debugger/CodeWidget.cpp | 60 ++++---- Source/Core/DolphinQt/Debugger/CodeWidget.h | 6 + .../DolphinQt/Debugger/RegisterWidget.cpp | 137 +++++++++--------- .../Core/DolphinQt/Debugger/RegisterWidget.h | 6 + 6 files changed, 143 insertions(+), 127 deletions(-) diff --git a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp index f954f57ccc..8e8b535b7f 100644 --- a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp @@ -135,7 +135,7 @@ constexpr int CODE_VIEW_COLUMN_DESCRIPTION = 4; constexpr int CODE_VIEW_COLUMN_BRANCH_ARROWS = 5; constexpr int CODE_VIEW_COLUMNCOUNT = 6; -CodeViewWidget::CodeViewWidget() +CodeViewWidget::CodeViewWidget() : m_system(Core::System::GetInstance()) { setColumnCount(CODE_VIEW_COLUMNCOUNT); setShowGrid(false); @@ -168,11 +168,11 @@ CodeViewWidget::CodeViewWidget() &CodeViewWidget::FontBasedSizing); connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this] { - m_address = PowerPC::ppcState.pc; + m_address = m_system.GetPPCState().pc; Update(); }); connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, [this] { - m_address = PowerPC::ppcState.pc; + m_address = m_system.GetPPCState().pc; Update(); }); @@ -259,7 +259,7 @@ void CodeViewWidget::Update() if (Core::GetState() == Core::State::Paused) { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); Update(&guard); } else @@ -294,7 +294,8 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard) for (int i = 0; i < rows; i++) setRowHeight(i, rowh); - const std::optional pc = guard ? std::make_optional(PowerPC::ppcState.pc) : std::nullopt; + const std::optional pc = + guard ? std::make_optional(m_system.GetPPCState().pc) : std::nullopt; const bool dark_theme = qApp->palette().color(QPalette::Base).valueF() < 0.5; @@ -533,7 +534,7 @@ void CodeViewWidget::SetAddress(u32 address, SetAddressUpdate update) void CodeViewWidget::ReplaceAddress(u32 address, ReplaceWith replace) { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); PowerPC::debug_interface.SetPatch(guard, address, replace == ReplaceWith::BLR ? 0x4e800020 : 0x60000000); @@ -595,10 +596,11 @@ void CodeViewWidget::OnContextMenu() bool follow_branch_enabled = false; if (paused) { - Core::CPUThreadGuard guard(Core::System::GetInstance()); - const std::string disasm = PowerPC::debug_interface.Disassemble(&guard, PowerPC::ppcState.pc); + Core::CPUThreadGuard guard(m_system); + const u32 pc = m_system.GetPPCState().pc; + const std::string disasm = PowerPC::debug_interface.Disassemble(&guard, pc); - if (addr == PowerPC::ppcState.pc) + if (addr == pc) { const auto target_it = std::find(disasm.begin(), disasm.end(), '\t'); const auto target_end = std::find(target_it, disasm.end(), ','); @@ -651,7 +653,7 @@ void CodeViewWidget::AutoStep(CodeTrace::AutoStop option) // Autosteps and follows value in the target (left-most) register. The Used and Changed options // silently follows target through reshuffles in memory and registers and stops on use or update. - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); CodeTrace code_trace; bool repeat = false; @@ -741,8 +743,8 @@ void CodeViewWidget::OnCopyTargetAddress() const u32 addr = GetContextAddress(); - const std::string code_line = [addr] { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + const std::string code_line = [this, addr] { + Core::CPUThreadGuard guard(m_system); return PowerPC::debug_interface.Disassemble(&guard, addr); }(); @@ -771,8 +773,8 @@ void CodeViewWidget::OnShowTargetInMemory() const u32 addr = GetContextAddress(); - const std::string code_line = [addr] { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + const std::string code_line = [this, addr] { + Core::CPUThreadGuard guard(m_system); return PowerPC::debug_interface.Disassemble(&guard, addr); }(); @@ -790,8 +792,8 @@ void CodeViewWidget::OnCopyCode() { const u32 addr = GetContextAddress(); - const std::string text = [addr] { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + const std::string text = [this, addr] { + Core::CPUThreadGuard guard(m_system); return PowerPC::debug_interface.Disassemble(&guard, addr); }(); @@ -809,7 +811,7 @@ void CodeViewWidget::OnCopyFunction() std::string text = symbol->name + "\r\n"; { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); // we got a function const u32 start = symbol->address; @@ -828,8 +830,8 @@ void CodeViewWidget::OnCopyHex() { const u32 addr = GetContextAddress(); - const u32 instruction = [addr] { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + const u32 instruction = [this, addr] { + Core::CPUThreadGuard guard(m_system); return PowerPC::debug_interface.ReadInstruction(guard, addr); }(); @@ -857,7 +859,7 @@ void CodeViewWidget::OnAddFunction() { const u32 addr = GetContextAddress(); - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); g_symbolDB.AddFunction(guard, addr); emit SymbolsChanged(); @@ -882,8 +884,8 @@ void CodeViewWidget::OnFollowBranch() { const u32 addr = GetContextAddress(); - const u32 branch_addr = [addr] { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + const u32 branch_addr = [this, addr] { + Core::CPUThreadGuard guard(m_system); return GetBranchFromAddress(guard, addr); }(); @@ -917,7 +919,7 @@ void CodeViewWidget::OnRenameSymbol() void CodeViewWidget::OnSelectionChanged() { - if (m_address == PowerPC::ppcState.pc) + if (m_address == m_system.GetPPCState().pc) { setStyleSheet( QStringLiteral("QTableView::item:selected {background-color: #00FF00; color: #000000;}")); @@ -946,7 +948,7 @@ void CodeViewWidget::OnSetSymbolSize() if (!good) return; - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); PPCAnalyst::ReanalyzeFunction(guard, symbol->address, *symbol, size); emit SymbolsChanged(); @@ -974,7 +976,7 @@ void CodeViewWidget::OnSetSymbolEndAddress() if (!good) return; - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); PPCAnalyst::ReanalyzeFunction(guard, symbol->address, *symbol, address - symbol->address); emit SymbolsChanged(); @@ -983,7 +985,7 @@ void CodeViewWidget::OnSetSymbolEndAddress() void CodeViewWidget::OnReplaceInstruction() { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); const u32 addr = GetContextAddress(); @@ -1006,7 +1008,7 @@ void CodeViewWidget::OnReplaceInstruction() void CodeViewWidget::OnRestoreInstruction() { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(m_system); const u32 addr = GetContextAddress(); diff --git a/Source/Core/DolphinQt/Debugger/CodeViewWidget.h b/Source/Core/DolphinQt/Debugger/CodeViewWidget.h index bf06b1e91d..2812d84a92 100644 --- a/Source/Core/DolphinQt/Debugger/CodeViewWidget.h +++ b/Source/Core/DolphinQt/Debugger/CodeViewWidget.h @@ -18,7 +18,8 @@ class QShowEvent; namespace Core { class CPUThreadGuard; -}; +class System; +} // namespace Core struct CodeViewBranch; class BranchDisplayDelegate; @@ -98,6 +99,8 @@ private: void CalculateBranchIndentation(); + Core::System& m_system; + bool m_updating = false; u32 m_address = 0; diff --git a/Source/Core/DolphinQt/Debugger/CodeWidget.cpp b/Source/Core/DolphinQt/Debugger/CodeWidget.cpp index 29d72faf18..02286fa8b1 100644 --- a/Source/Core/DolphinQt/Debugger/CodeWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/CodeWidget.cpp @@ -28,7 +28,7 @@ #include "DolphinQt/Host.h" #include "DolphinQt/Settings.h" -CodeWidget::CodeWidget(QWidget* parent) : QDockWidget(parent) +CodeWidget::CodeWidget(QWidget* parent) : QDockWidget(parent), m_system(Core::System::GetInstance()) { setWindowTitle(tr("Code")); setObjectName(QStringLiteral("code")); @@ -51,7 +51,7 @@ CodeWidget::CodeWidget(QWidget* parent) : QDockWidget(parent) connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, [this] { if (Core::GetState() == Core::State::Paused) - SetAddress(PowerPC::ppcState.pc, CodeViewWidget::SetAddressUpdate::WithoutUpdate); + SetAddress(m_system.GetPPCState().pc, CodeViewWidget::SetAddressUpdate::WithoutUpdate); Update(); }); @@ -329,9 +329,9 @@ void CodeWidget::UpdateCallstack() std::vector stack; - const bool success = [&stack] { - Core::CPUThreadGuard guard(Core::System::GetInstance()); - return Dolphin_Debugger::GetCallstack(Core::System::GetInstance(), guard, stack); + const bool success = [this, &stack] { + Core::CPUThreadGuard guard(m_system); + return Dolphin_Debugger::GetCallstack(m_system, guard, stack); }(); if (!success) @@ -435,8 +435,7 @@ void CodeWidget::UpdateFunctionCallers(const Common::Symbol* symbol) void CodeWidget::Step() { - auto& system = Core::System::GetInstance(); - auto& cpu = system.GetCPU(); + auto& cpu = m_system.GetCPU(); if (!cpu.IsStepping()) return; @@ -455,21 +454,20 @@ void CodeWidget::Step() void CodeWidget::StepOver() { - auto& system = Core::System::GetInstance(); - auto& cpu = system.GetCPU(); + auto& cpu = m_system.GetCPU(); if (!cpu.IsStepping()) return; const UGeckoInstruction inst = [&] { - Core::CPUThreadGuard guard(system); - return PowerPC::MMU::HostRead_Instruction(guard, PowerPC::ppcState.pc); + Core::CPUThreadGuard guard(m_system); + return PowerPC::MMU::HostRead_Instruction(guard, m_system.GetPPCState().pc); }(); if (inst.LK) { PowerPC::breakpoints.ClearAllTemporary(); - PowerPC::breakpoints.Add(PowerPC::ppcState.pc + 4, true); + PowerPC::breakpoints.Add(m_system.GetPPCState().pc + 4, true); cpu.EnableStepping(false); Core::DisplayMessage(tr("Step over in progress...").toStdString(), 2000); } @@ -480,23 +478,21 @@ void CodeWidget::StepOver() } // Returns true on a rfi, blr or on a bclr that evaluates to true. -static bool WillInstructionReturn(UGeckoInstruction inst) +static bool WillInstructionReturn(Core::System& system, UGeckoInstruction inst) { // Is a rfi instruction if (inst.hex == 0x4C000064u) return true; - bool counter = - (inst.BO_2 >> 2 & 1) != 0 || (CTR(PowerPC::ppcState) != 0) != ((inst.BO_2 >> 1 & 1) != 0); - bool condition = - inst.BO_2 >> 4 != 0 || PowerPC::ppcState.cr.GetBit(inst.BI_2) == (inst.BO_2 >> 3 & 1); + const auto& ppc_state = system.GetPPCState(); + bool counter = (inst.BO_2 >> 2 & 1) != 0 || (CTR(ppc_state) != 0) != ((inst.BO_2 >> 1 & 1) != 0); + bool condition = inst.BO_2 >> 4 != 0 || ppc_state.cr.GetBit(inst.BI_2) == (inst.BO_2 >> 3 & 1); bool isBclr = inst.OPCD_7 == 0b010011 && (inst.hex >> 1 & 0b10000) != 0; return isBclr && counter && condition && !inst.LK_3; } void CodeWidget::StepOut() { - auto& system = Core::System::GetInstance(); - auto& cpu = system.GetCPU(); + auto& cpu = m_system.GetCPU(); if (!cpu.IsStepping()) return; @@ -505,8 +501,9 @@ void CodeWidget::StepOut() using clock = std::chrono::steady_clock; clock::time_point timeout = clock::now() + std::chrono::seconds(5); + auto& ppc_state = m_system.GetPPCState(); { - Core::CPUThreadGuard guard(system); + Core::CPUThreadGuard guard(m_system); PowerPC::breakpoints.ClearAllTemporary(); @@ -516,10 +513,10 @@ void CodeWidget::StepOut() // Loop until either the current instruction is a return instruction with no Link flag // or a breakpoint is detected so it can step at the breakpoint. If the PC is currently // on a breakpoint, skip it. - UGeckoInstruction inst = PowerPC::MMU::HostRead_Instruction(guard, PowerPC::ppcState.pc); + UGeckoInstruction inst = PowerPC::MMU::HostRead_Instruction(guard, ppc_state.pc); do { - if (WillInstructionReturn(inst)) + if (WillInstructionReturn(m_system, inst)) { PowerPC::SingleStep(); break; @@ -528,28 +525,27 @@ void CodeWidget::StepOut() if (inst.LK) { // Step over branches - u32 next_pc = PowerPC::ppcState.pc + 4; + u32 next_pc = ppc_state.pc + 4; do { PowerPC::SingleStep(); - } while (PowerPC::ppcState.pc != next_pc && clock::now() < timeout && - !PowerPC::breakpoints.IsAddressBreakPoint(PowerPC::ppcState.pc)); + } while (ppc_state.pc != next_pc && clock::now() < timeout && + !PowerPC::breakpoints.IsAddressBreakPoint(ppc_state.pc)); } else { PowerPC::SingleStep(); } - inst = PowerPC::MMU::HostRead_Instruction(guard, PowerPC::ppcState.pc); - } while (clock::now() < timeout && - !PowerPC::breakpoints.IsAddressBreakPoint(PowerPC::ppcState.pc)); + inst = PowerPC::MMU::HostRead_Instruction(guard, ppc_state.pc); + } while (clock::now() < timeout && !PowerPC::breakpoints.IsAddressBreakPoint(ppc_state.pc)); PowerPC::SetMode(old_mode); } emit Host::GetInstance()->UpdateDisasmDialog(); - if (PowerPC::breakpoints.IsAddressBreakPoint(PowerPC::ppcState.pc)) + if (PowerPC::breakpoints.IsAddressBreakPoint(ppc_state.pc)) Core::DisplayMessage(tr("Breakpoint encountered! Step out aborted.").toStdString(), 2000); else if (clock::now() >= timeout) Core::DisplayMessage(tr("Step out timed out!").toStdString(), 2000); @@ -559,19 +555,19 @@ void CodeWidget::StepOut() void CodeWidget::Skip() { - PowerPC::ppcState.pc += 4; + m_system.GetPPCState().pc += 4; ShowPC(); } void CodeWidget::ShowPC() { - m_code_view->SetAddress(PowerPC::ppcState.pc, CodeViewWidget::SetAddressUpdate::WithUpdate); + m_code_view->SetAddress(m_system.GetPPCState().pc, CodeViewWidget::SetAddressUpdate::WithUpdate); Update(); } void CodeWidget::SetPC() { - PowerPC::ppcState.pc = m_code_view->GetAddress(); + m_system.GetPPCState().pc = m_code_view->GetAddress(); Update(); } diff --git a/Source/Core/DolphinQt/Debugger/CodeWidget.h b/Source/Core/DolphinQt/Debugger/CodeWidget.h index f198e004cc..1e933a8c70 100644 --- a/Source/Core/DolphinQt/Debugger/CodeWidget.h +++ b/Source/Core/DolphinQt/Debugger/CodeWidget.h @@ -22,6 +22,10 @@ namespace Common { struct Symbol; } +namespace Core +{ +class System; +} class CodeWidget : public QDockWidget { @@ -66,6 +70,8 @@ private: void closeEvent(QCloseEvent*) override; void showEvent(QShowEvent* event) override; + Core::System& m_system; + CodeDiffDialog* m_diff_dialog = nullptr; QLineEdit* m_search_address; QPushButton* m_code_diff; diff --git a/Source/Core/DolphinQt/Debugger/RegisterWidget.cpp b/Source/Core/DolphinQt/Debugger/RegisterWidget.cpp index 9d7079e04a..f11df86444 100644 --- a/Source/Core/DolphinQt/Debugger/RegisterWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/RegisterWidget.cpp @@ -20,7 +20,8 @@ #include "DolphinQt/Host.h" #include "DolphinQt/Settings.h" -RegisterWidget::RegisterWidget(QWidget* parent) : QDockWidget(parent) +RegisterWidget::RegisterWidget(QWidget* parent) + : QDockWidget(parent), m_system(Core::System::GetInstance()) { setWindowTitle(tr("Registers")); setObjectName(QStringLiteral("registers")); @@ -295,8 +296,8 @@ void RegisterWidget::AutoStep(const std::string& reg) const while (true) { - const AutoStepResults results = [&trace] { - Core::CPUThreadGuard guard(Core::System::GetInstance()); + const AutoStepResults results = [this, &trace] { + Core::CPUThreadGuard guard(m_system); return trace.AutoStepping(guard, true); }(); @@ -318,18 +319,19 @@ void RegisterWidget::PopulateTable() { // General purpose registers (int) AddRegister( - i, 0, RegisterType::gpr, "r" + std::to_string(i), [i] { return PowerPC::ppcState.gpr[i]; }, - [i](u64 value) { PowerPC::ppcState.gpr[i] = value; }); + i, 0, RegisterType::gpr, "r" + std::to_string(i), + [this, i] { return m_system.GetPPCState().gpr[i]; }, + [this, i](u64 value) { m_system.GetPPCState().gpr[i] = value; }); // Floating point registers (double) AddRegister( i, 2, RegisterType::fpr, "f" + std::to_string(i), - [i] { return PowerPC::ppcState.ps[i].PS0AsU64(); }, - [i](u64 value) { PowerPC::ppcState.ps[i].SetPS0(value); }); + [this, i] { return m_system.GetPPCState().ps[i].PS0AsU64(); }, + [this, i](u64 value) { m_system.GetPPCState().ps[i].SetPS0(value); }); AddRegister( - i, 4, RegisterType::fpr, "", [i] { return PowerPC::ppcState.ps[i].PS1AsU64(); }, - [i](u64 value) { PowerPC::ppcState.ps[i].SetPS1(value); }); + i, 4, RegisterType::fpr, "", [this, i] { return m_system.GetPPCState().ps[i].PS1AsU64(); }, + [this, i](u64 value) { m_system.GetPPCState().ps[i].SetPS1(value); }); } // The IBAT and DBAT registers have a large gap between @@ -340,32 +342,36 @@ void RegisterWidget::PopulateTable() // IBAT registers AddRegister( i, 5, RegisterType::ibat, "IBAT" + std::to_string(i), - [i] { - return (static_cast(PowerPC::ppcState.spr[SPR_IBAT0U + i * 2]) << 32) + - PowerPC::ppcState.spr[SPR_IBAT0L + i * 2]; + [this, i] { + const auto& ppc_state = m_system.GetPPCState(); + return (static_cast(ppc_state.spr[SPR_IBAT0U + i * 2]) << 32) + + ppc_state.spr[SPR_IBAT0L + i * 2]; }, nullptr); AddRegister( i + 4, 5, RegisterType::ibat, "IBAT" + std::to_string(4 + i), - [i] { - return (static_cast(PowerPC::ppcState.spr[SPR_IBAT4U + i * 2]) << 32) + - PowerPC::ppcState.spr[SPR_IBAT4L + i * 2]; + [this, i] { + const auto& ppc_state = m_system.GetPPCState(); + return (static_cast(ppc_state.spr[SPR_IBAT4U + i * 2]) << 32) + + ppc_state.spr[SPR_IBAT4L + i * 2]; }, nullptr); // DBAT registers AddRegister( i + 8, 5, RegisterType::dbat, "DBAT" + std::to_string(i), - [i] { - return (static_cast(PowerPC::ppcState.spr[SPR_DBAT0U + i * 2]) << 32) + - PowerPC::ppcState.spr[SPR_DBAT0L + i * 2]; + [this, i] { + const auto& ppc_state = m_system.GetPPCState(); + return (static_cast(ppc_state.spr[SPR_DBAT0U + i * 2]) << 32) + + ppc_state.spr[SPR_DBAT0L + i * 2]; }, nullptr); AddRegister( i + 12, 5, RegisterType::dbat, "DBAT" + std::to_string(4 + i), - [i] { - return (static_cast(PowerPC::ppcState.spr[SPR_DBAT4U + i * 2]) << 32) + - PowerPC::ppcState.spr[SPR_DBAT4L + i * 2]; + [this, i] { + const auto& ppc_state = m_system.GetPPCState(); + return (static_cast(ppc_state.spr[SPR_DBAT4U + i * 2]) << 32) + + ppc_state.spr[SPR_DBAT4L + i * 2]; }, nullptr); } @@ -375,29 +381,30 @@ void RegisterWidget::PopulateTable() // Graphics quantization registers AddRegister( i + 16, 7, RegisterType::gqr, "GQR" + std::to_string(i), - [i] { return PowerPC::ppcState.spr[SPR_GQR0 + i]; }, nullptr); + [this, i] { return m_system.GetPPCState().spr[SPR_GQR0 + i]; }, nullptr); } // HID registers AddRegister( - 24, 7, RegisterType::hid, "HID0", [] { return PowerPC::ppcState.spr[SPR_HID0]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_HID0] = static_cast(value); }); + 24, 7, RegisterType::hid, "HID0", [this] { return m_system.GetPPCState().spr[SPR_HID0]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_HID0] = static_cast(value); }); AddRegister( - 25, 7, RegisterType::hid, "HID1", [] { return PowerPC::ppcState.spr[SPR_HID1]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_HID1] = static_cast(value); }); + 25, 7, RegisterType::hid, "HID1", [this] { return m_system.GetPPCState().spr[SPR_HID1]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_HID1] = static_cast(value); }); AddRegister( - 26, 7, RegisterType::hid, "HID2", [] { return PowerPC::ppcState.spr[SPR_HID2]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_HID2] = static_cast(value); }); + 26, 7, RegisterType::hid, "HID2", [this] { return m_system.GetPPCState().spr[SPR_HID2]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_HID2] = static_cast(value); }); AddRegister( - 27, 7, RegisterType::hid, "HID4", [] { return PowerPC::ppcState.spr[SPR_HID4]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_HID4] = static_cast(value); }); + 27, 7, RegisterType::hid, "HID4", [this] { return m_system.GetPPCState().spr[SPR_HID4]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_HID4] = static_cast(value); }); for (int i = 0; i < 16; i++) { // SR registers AddRegister( - i, 7, RegisterType::sr, "SR" + std::to_string(i), [i] { return PowerPC::ppcState.sr[i]; }, - [i](u64 value) { PowerPC::ppcState.sr[i] = value; }); + i, 7, RegisterType::sr, "SR" + std::to_string(i), + [this, i] { return m_system.GetPPCState().sr[i]; }, + [this, i](u64 value) { m_system.GetPPCState().sr[i] = value; }); } // Special registers @@ -406,83 +413,79 @@ void RegisterWidget::PopulateTable() // PC AddRegister( - 17, 5, RegisterType::pc, "PC", [] { return PowerPC::ppcState.pc; }, - [](u64 value) { PowerPC::ppcState.pc = value; }); + 17, 5, RegisterType::pc, "PC", [this] { return m_system.GetPPCState().pc; }, + [this](u64 value) { m_system.GetPPCState().pc = value; }); // LR AddRegister( - 18, 5, RegisterType::lr, "LR", [] { return PowerPC::ppcState.spr[SPR_LR]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_LR] = value; }); + 18, 5, RegisterType::lr, "LR", [this] { return m_system.GetPPCState().spr[SPR_LR]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_LR] = value; }); // CTR AddRegister( - 19, 5, RegisterType::ctr, "CTR", [] { return PowerPC::ppcState.spr[SPR_CTR]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_CTR] = value; }); + 19, 5, RegisterType::ctr, "CTR", [this] { return m_system.GetPPCState().spr[SPR_CTR]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_CTR] = value; }); // CR AddRegister( - 20, 5, RegisterType::cr, "CR", [] { return PowerPC::ppcState.cr.Get(); }, - [](u64 value) { PowerPC::ppcState.cr.Set(value); }); + 20, 5, RegisterType::cr, "CR", [this] { return m_system.GetPPCState().cr.Get(); }, + [this](u64 value) { m_system.GetPPCState().cr.Set(value); }); // XER AddRegister( - 21, 5, RegisterType::xer, "XER", [] { return PowerPC::ppcState.GetXER().Hex; }, - [](u64 value) { PowerPC::ppcState.SetXER(UReg_XER(value)); }); + 21, 5, RegisterType::xer, "XER", [this] { return m_system.GetPPCState().GetXER().Hex; }, + [this](u64 value) { m_system.GetPPCState().SetXER(UReg_XER(value)); }); // FPSCR AddRegister( - 22, 5, RegisterType::fpscr, "FPSCR", [] { return PowerPC::ppcState.fpscr.Hex; }, - [](u64 value) { PowerPC::ppcState.fpscr = static_cast(value); }); + 22, 5, RegisterType::fpscr, "FPSCR", [this] { return m_system.GetPPCState().fpscr.Hex; }, + [this](u64 value) { m_system.GetPPCState().fpscr = static_cast(value); }); // MSR AddRegister( - 23, 5, RegisterType::msr, "MSR", [] { return PowerPC::ppcState.msr.Hex; }, - [](u64 value) { PowerPC::ppcState.msr.Hex = value; }); + 23, 5, RegisterType::msr, "MSR", [this] { return m_system.GetPPCState().msr.Hex; }, + [this](u64 value) { m_system.GetPPCState().msr.Hex = value; }); // SRR 0-1 AddRegister( - 24, 5, RegisterType::srr, "SRR0", [] { return PowerPC::ppcState.spr[SPR_SRR0]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_SRR0] = value; }); + 24, 5, RegisterType::srr, "SRR0", [this] { return m_system.GetPPCState().spr[SPR_SRR0]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_SRR0] = value; }); AddRegister( - 25, 5, RegisterType::srr, "SRR1", [] { return PowerPC::ppcState.spr[SPR_SRR1]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_SRR1] = value; }); + 25, 5, RegisterType::srr, "SRR1", [this] { return m_system.GetPPCState().spr[SPR_SRR1]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_SRR1] = value; }); // Exceptions AddRegister( - 26, 5, RegisterType::exceptions, "Exceptions", [] { return PowerPC::ppcState.Exceptions; }, - [](u64 value) { PowerPC::ppcState.Exceptions = value; }); + 26, 5, RegisterType::exceptions, "Exceptions", + [this] { return m_system.GetPPCState().Exceptions; }, + [this](u64 value) { m_system.GetPPCState().Exceptions = value; }); // Int Mask AddRegister( 27, 5, RegisterType::int_mask, "Int Mask", - [] { - auto& system = Core::System::GetInstance(); - return system.GetProcessorInterface().GetMask(); - }, - nullptr); + [this] { return m_system.GetProcessorInterface().GetMask(); }, nullptr); // Int Cause AddRegister( 28, 5, RegisterType::int_cause, "Int Cause", - [] { - auto& system = Core::System::GetInstance(); - return system.GetProcessorInterface().GetCause(); - }, - nullptr); + [this] { return m_system.GetProcessorInterface().GetCause(); }, nullptr); // DSISR AddRegister( - 29, 5, RegisterType::dsisr, "DSISR", [] { return PowerPC::ppcState.spr[SPR_DSISR]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_DSISR] = value; }); + 29, 5, RegisterType::dsisr, "DSISR", [this] { return m_system.GetPPCState().spr[SPR_DSISR]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_DSISR] = value; }); // DAR AddRegister( - 30, 5, RegisterType::dar, "DAR", [] { return PowerPC::ppcState.spr[SPR_DAR]; }, - [](u64 value) { PowerPC::ppcState.spr[SPR_DAR] = value; }); + 30, 5, RegisterType::dar, "DAR", [this] { return m_system.GetPPCState().spr[SPR_DAR]; }, + [this](u64 value) { m_system.GetPPCState().spr[SPR_DAR] = value; }); // Hash Mask AddRegister( 31, 5, RegisterType::pt_hashmask, "Hash Mask", - [] { return (PowerPC::ppcState.pagetable_hashmask << 6) | PowerPC::ppcState.pagetable_base; }, + [this] { + const auto& ppc_state = m_system.GetPPCState(); + return (ppc_state.pagetable_hashmask << 6) | ppc_state.pagetable_base; + }, nullptr); emit RequestTableUpdate(); diff --git a/Source/Core/DolphinQt/Debugger/RegisterWidget.h b/Source/Core/DolphinQt/Debugger/RegisterWidget.h index f57a3b04d9..13432692a6 100644 --- a/Source/Core/DolphinQt/Debugger/RegisterWidget.h +++ b/Source/Core/DolphinQt/Debugger/RegisterWidget.h @@ -13,6 +13,10 @@ class QTableWidget; class QCloseEvent; class QShowEvent; +namespace Core +{ +class System; +} class RegisterWidget : public QDockWidget { @@ -49,6 +53,8 @@ private: void AutoStep(const std::string& reg) const; void Update(); + Core::System& m_system; + QTableWidget* m_table; bool m_updating = false; }; From 62de9c593bb5e402a9315777cb49917721e43799 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Wed, 29 Mar 2023 00:42:27 +0200 Subject: [PATCH 7/7] UnitTests: Avoid ppcState global. --- Source/UnitTests/Core/CoreTimingTest.cpp | 105 +++++++++--------- .../UnitTests/Core/PowerPC/JitArm64/FPRF.cpp | 24 ++-- .../UnitTests/Core/PowerPC/JitArm64/Fres.cpp | 2 +- .../Core/PowerPC/JitArm64/Frsqrte.cpp | 2 +- 4 files changed, 71 insertions(+), 62 deletions(-) diff --git a/Source/UnitTests/Core/CoreTimingTest.cpp b/Source/UnitTests/Core/CoreTimingTest.cpp index 14731a10e7..3a8012cdf0 100644 --- a/Source/UnitTests/Core/CoreTimingTest.cpp +++ b/Source/UnitTests/Core/CoreTimingTest.cpp @@ -74,20 +74,20 @@ private: std::string m_profile_path; }; -static void AdvanceAndCheck(u32 idx, int downcount, int expected_lateness = 0, +static void AdvanceAndCheck(Core::System& system, u32 idx, int downcount, int expected_lateness = 0, int cpu_downcount = 0) { s_callbacks_ran_flags = 0; s_expected_callback = CB_IDS[idx]; s_lateness = expected_lateness; - PowerPC::ppcState.downcount = cpu_downcount; // Pretend we executed X cycles of instructions. - auto& system = Core::System::GetInstance(); + auto& ppc_state = system.GetPPCState(); + ppc_state.downcount = cpu_downcount; // Pretend we executed X cycles of instructions. auto& core_timing = system.GetCoreTiming(); core_timing.Advance(); EXPECT_EQ(decltype(s_callbacks_ran_flags)().set(idx), s_callbacks_ran_flags); - EXPECT_EQ(downcount, PowerPC::ppcState.downcount); + EXPECT_EQ(downcount, ppc_state.downcount); } TEST(CoreTiming, BasicOrder) @@ -97,6 +97,7 @@ TEST(CoreTiming, BasicOrder) auto& system = Core::System::GetInstance(); auto& core_timing = system.GetCoreTiming(); + auto& ppc_state = system.GetPPCState(); CoreTiming::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>); CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>); @@ -109,21 +110,21 @@ TEST(CoreTiming, BasicOrder) // D -> B -> C -> A -> E core_timing.ScheduleEvent(1000, cb_a, CB_IDS[0]); - EXPECT_EQ(1000, PowerPC::ppcState.downcount); + EXPECT_EQ(1000, ppc_state.downcount); core_timing.ScheduleEvent(500, cb_b, CB_IDS[1]); - EXPECT_EQ(500, PowerPC::ppcState.downcount); + EXPECT_EQ(500, ppc_state.downcount); core_timing.ScheduleEvent(800, cb_c, CB_IDS[2]); - EXPECT_EQ(500, PowerPC::ppcState.downcount); + EXPECT_EQ(500, ppc_state.downcount); core_timing.ScheduleEvent(100, cb_d, CB_IDS[3]); - EXPECT_EQ(100, PowerPC::ppcState.downcount); + EXPECT_EQ(100, ppc_state.downcount); core_timing.ScheduleEvent(1200, cb_e, CB_IDS[4]); - EXPECT_EQ(100, PowerPC::ppcState.downcount); + EXPECT_EQ(100, ppc_state.downcount); - AdvanceAndCheck(3, 400); - AdvanceAndCheck(1, 300); - AdvanceAndCheck(2, 200); - AdvanceAndCheck(0, 200); - AdvanceAndCheck(4, MAX_SLICE_LENGTH); + AdvanceAndCheck(system, 3, 400); + AdvanceAndCheck(system, 1, 300); + AdvanceAndCheck(system, 2, 200); + AdvanceAndCheck(system, 0, 200); + AdvanceAndCheck(system, 4, MAX_SLICE_LENGTH); } namespace SharedSlotTest @@ -151,6 +152,7 @@ TEST(CoreTiming, SharedSlot) auto& system = Core::System::GetInstance(); auto& core_timing = system.GetCoreTiming(); + auto& ppc_state = system.GetPPCState(); CoreTiming::EventType* cb_a = core_timing.RegisterEvent("callbackA", FifoCallback<0>); CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", FifoCallback<1>); @@ -166,14 +168,14 @@ TEST(CoreTiming, SharedSlot) // Enter slice 0 core_timing.Advance(); - EXPECT_EQ(1000, PowerPC::ppcState.downcount); + EXPECT_EQ(1000, ppc_state.downcount); s_callbacks_ran_flags = 0; s_counter = 0; s_lateness = 0; - PowerPC::ppcState.downcount = 0; + ppc_state.downcount = 0; core_timing.Advance(); - EXPECT_EQ(MAX_SLICE_LENGTH, PowerPC::ppcState.downcount); + EXPECT_EQ(MAX_SLICE_LENGTH, ppc_state.downcount); EXPECT_EQ(0x1FULL, s_callbacks_ran_flags.to_ullong()); } @@ -194,8 +196,8 @@ TEST(CoreTiming, PredictableLateness) core_timing.ScheduleEvent(100, cb_a, CB_IDS[0]); core_timing.ScheduleEvent(200, cb_b, CB_IDS[1]); - AdvanceAndCheck(0, 90, 10, -10); // (100 - 10) - AdvanceAndCheck(1, MAX_SLICE_LENGTH, 50, -50); + AdvanceAndCheck(system, 0, 90, 10, -10); // (100 - 10) + AdvanceAndCheck(system, 1, MAX_SLICE_LENGTH, 50, -50); } namespace ChainSchedulingTest @@ -225,6 +227,7 @@ TEST(CoreTiming, ChainScheduling) auto& system = Core::System::GetInstance(); auto& core_timing = system.GetCoreTiming(); + auto& ppc_state = system.GetPPCState(); CoreTiming::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>); CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>); @@ -239,24 +242,24 @@ TEST(CoreTiming, ChainScheduling) core_timing.ScheduleEvent(1000, cb_b, CB_IDS[1]); core_timing.ScheduleEvent(2200, cb_c, CB_IDS[2]); core_timing.ScheduleEvent(1000, cb_rs, reinterpret_cast(cb_rs)); - EXPECT_EQ(800, PowerPC::ppcState.downcount); + EXPECT_EQ(800, ppc_state.downcount); s_reschedules = 3; - AdvanceAndCheck(0, 200); // cb_a - AdvanceAndCheck(1, 1000); // cb_b, cb_rs + AdvanceAndCheck(system, 0, 200); // cb_a + AdvanceAndCheck(system, 1, 1000); // cb_b, cb_rs EXPECT_EQ(2, s_reschedules); - PowerPC::ppcState.downcount = 0; + ppc_state.downcount = 0; core_timing.Advance(); // cb_rs EXPECT_EQ(1, s_reschedules); - EXPECT_EQ(200, PowerPC::ppcState.downcount); + EXPECT_EQ(200, ppc_state.downcount); - AdvanceAndCheck(2, 800); // cb_c + AdvanceAndCheck(system, 2, 800); // cb_c - PowerPC::ppcState.downcount = 0; + ppc_state.downcount = 0; core_timing.Advance(); // cb_rs EXPECT_EQ(0, s_reschedules); - EXPECT_EQ(MAX_SLICE_LENGTH, PowerPC::ppcState.downcount); + EXPECT_EQ(MAX_SLICE_LENGTH, ppc_state.downcount); } namespace ScheduleIntoPastTest @@ -284,6 +287,7 @@ TEST(CoreTiming, ScheduleIntoPast) auto& system = Core::System::GetInstance(); auto& core_timing = system.GetCoreTiming(); + auto& ppc_state = system.GetPPCState(); s_cb_next = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>); CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>); @@ -293,9 +297,9 @@ TEST(CoreTiming, ScheduleIntoPast) core_timing.Advance(); core_timing.ScheduleEvent(1000, cb_chain, CB_IDS[0] + 1); - EXPECT_EQ(1000, PowerPC::ppcState.downcount); + EXPECT_EQ(1000, ppc_state.downcount); - AdvanceAndCheck(0, MAX_SLICE_LENGTH, 1000); // Run cb_chain into late cb_a + AdvanceAndCheck(system, 0, MAX_SLICE_LENGTH, 1000); // Run cb_chain into late cb_a // Schedule late from wrong thread // The problem with scheduling CPU events from outside the CPU Thread is that g_global_timer @@ -309,14 +313,14 @@ TEST(CoreTiming, ScheduleIntoPast) core_timing.ScheduleEvent(0, cb_b, CB_IDS[1], CoreTiming::FromThread::NON_CPU); core_timing_globals.global_timer += 1000; Core::DeclareAsCPUThread(); - AdvanceAndCheck(1, MAX_SLICE_LENGTH, MAX_SLICE_LENGTH + 1000); + AdvanceAndCheck(system, 1, MAX_SLICE_LENGTH, MAX_SLICE_LENGTH + 1000); // Schedule directly into the past from the CPU. // This shouldn't happen in practice, but it's best if we don't mess up the slice length and // downcount if we do. core_timing.ScheduleEvent(-1000, s_cb_next, CB_IDS[0]); - EXPECT_EQ(0, PowerPC::ppcState.downcount); - AdvanceAndCheck(0, MAX_SLICE_LENGTH, 1000); + EXPECT_EQ(0, ppc_state.downcount); + AdvanceAndCheck(system, 0, MAX_SLICE_LENGTH, 1000); } TEST(CoreTiming, Overclocking) @@ -326,6 +330,7 @@ TEST(CoreTiming, Overclocking) auto& system = Core::System::GetInstance(); auto& core_timing = system.GetCoreTiming(); + auto& ppc_state = system.GetPPCState(); CoreTiming::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>); CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>); @@ -346,13 +351,13 @@ TEST(CoreTiming, Overclocking) core_timing.ScheduleEvent(400, cb_c, CB_IDS[2]); core_timing.ScheduleEvent(800, cb_d, CB_IDS[3]); core_timing.ScheduleEvent(1600, cb_e, CB_IDS[4]); - EXPECT_EQ(200, PowerPC::ppcState.downcount); + EXPECT_EQ(200, ppc_state.downcount); - AdvanceAndCheck(0, 200); // (200 - 100) * 2 - AdvanceAndCheck(1, 400); // (400 - 200) * 2 - AdvanceAndCheck(2, 800); // (800 - 400) * 2 - AdvanceAndCheck(3, 1600); // (1600 - 800) * 2 - AdvanceAndCheck(4, MAX_SLICE_LENGTH * 2); + AdvanceAndCheck(system, 0, 200); // (200 - 100) * 2 + AdvanceAndCheck(system, 1, 400); // (400 - 200) * 2 + AdvanceAndCheck(system, 2, 800); // (800 - 400) * 2 + AdvanceAndCheck(system, 3, 1600); // (1600 - 800) * 2 + AdvanceAndCheck(system, 4, MAX_SLICE_LENGTH * 2); // Underclock Config::SetCurrent(Config::MAIN_OVERCLOCK, 0.5f); @@ -363,13 +368,13 @@ TEST(CoreTiming, Overclocking) core_timing.ScheduleEvent(400, cb_c, CB_IDS[2]); core_timing.ScheduleEvent(800, cb_d, CB_IDS[3]); core_timing.ScheduleEvent(1600, cb_e, CB_IDS[4]); - EXPECT_EQ(50, PowerPC::ppcState.downcount); + EXPECT_EQ(50, ppc_state.downcount); - AdvanceAndCheck(0, 50); // (200 - 100) / 2 - AdvanceAndCheck(1, 100); // (400 - 200) / 2 - AdvanceAndCheck(2, 200); // (800 - 400) / 2 - AdvanceAndCheck(3, 400); // (1600 - 800) / 2 - AdvanceAndCheck(4, MAX_SLICE_LENGTH / 2); + AdvanceAndCheck(system, 0, 50); // (200 - 100) / 2 + AdvanceAndCheck(system, 1, 100); // (400 - 200) / 2 + AdvanceAndCheck(system, 2, 200); // (800 - 400) / 2 + AdvanceAndCheck(system, 3, 400); // (1600 - 800) / 2 + AdvanceAndCheck(system, 4, MAX_SLICE_LENGTH / 2); // Try switching the clock mid-emulation Config::SetCurrent(Config::MAIN_OVERCLOCK, 1.0f); @@ -380,14 +385,14 @@ TEST(CoreTiming, Overclocking) core_timing.ScheduleEvent(400, cb_c, CB_IDS[2]); core_timing.ScheduleEvent(800, cb_d, CB_IDS[3]); core_timing.ScheduleEvent(1600, cb_e, CB_IDS[4]); - EXPECT_EQ(100, PowerPC::ppcState.downcount); + EXPECT_EQ(100, ppc_state.downcount); - AdvanceAndCheck(0, 100); // (200 - 100) + AdvanceAndCheck(system, 0, 100); // (200 - 100) Config::SetCurrent(Config::MAIN_OVERCLOCK, 2.0f); - AdvanceAndCheck(1, 400); // (400 - 200) * 2 - AdvanceAndCheck(2, 800); // (800 - 400) * 2 + AdvanceAndCheck(system, 1, 400); // (400 - 200) * 2 + AdvanceAndCheck(system, 2, 800); // (800 - 400) * 2 Config::SetCurrent(Config::MAIN_OVERCLOCK, 0.1f); - AdvanceAndCheck(3, 80); // (1600 - 800) / 10 + AdvanceAndCheck(system, 3, 80); // (1600 - 800) / 10 Config::SetCurrent(Config::MAIN_OVERCLOCK, 1.0f); - AdvanceAndCheck(4, MAX_SLICE_LENGTH); + AdvanceAndCheck(system, 4, MAX_SLICE_LENGTH); } diff --git a/Source/UnitTests/Core/PowerPC/JitArm64/FPRF.cpp b/Source/UnitTests/Core/PowerPC/JitArm64/FPRF.cpp index 1bc22c3263..285469b90f 100644 --- a/Source/UnitTests/Core/PowerPC/JitArm64/FPRF.cpp +++ b/Source/UnitTests/Core/PowerPC/JitArm64/FPRF.cpp @@ -34,10 +34,12 @@ public: const u8* raw_fprf_double = GetCodePtr(); GenerateFPRF(false); + auto& ppc_state = system.GetPPCState(); + fprf_single = Common::BitCast(GetCodePtr()); MOV(ARM64Reg::X15, ARM64Reg::X30); MOV(ARM64Reg::X14, PPC_REG); - MOVP2R(PPC_REG, &PowerPC::ppcState); + MOVP2R(PPC_REG, &ppc_state); BL(raw_fprf_single); MOV(ARM64Reg::X30, ARM64Reg::X15); MOV(PPC_REG, ARM64Reg::X14); @@ -46,7 +48,7 @@ public: fprf_double = Common::BitCast(GetCodePtr()); MOV(ARM64Reg::X15, ARM64Reg::X30); MOV(ARM64Reg::X14, PPC_REG); - MOVP2R(PPC_REG, &PowerPC::ppcState); + MOVP2R(PPC_REG, &ppc_state); BL(raw_fprf_double); MOV(ARM64Reg::X30, ARM64Reg::X15); MOV(PPC_REG, ARM64Reg::X14); @@ -59,29 +61,31 @@ public: } // namespace -static u32 RunUpdateFPRF(const std::function& f) +static u32 RunUpdateFPRF(PowerPC::PowerPCState& ppc_state, const std::function& f) { - PowerPC::ppcState.fpscr.Hex = 0x12345678; + ppc_state.fpscr.Hex = 0x12345678; f(); - return PowerPC::ppcState.fpscr.Hex; + return ppc_state.fpscr.Hex; } TEST(JitArm64, FPRF) { - TestFPRF test(Core::System::GetInstance()); + auto& system = Core::System::GetInstance(); + auto& ppc_state = system.GetPPCState(); + TestFPRF test(system); for (const u64 double_input : double_test_values) { const u32 expected_double = RunUpdateFPRF( - [&] { PowerPC::ppcState.UpdateFPRFDouble(Common::BitCast(double_input)); }); - const u32 actual_double = RunUpdateFPRF([&] { test.fprf_double(double_input); }); + ppc_state, [&] { ppc_state.UpdateFPRFDouble(Common::BitCast(double_input)); }); + const u32 actual_double = RunUpdateFPRF(ppc_state, [&] { test.fprf_double(double_input); }); EXPECT_EQ(expected_double, actual_double); const u32 single_input = ConvertToSingle(double_input); const u32 expected_single = RunUpdateFPRF( - [&] { PowerPC::ppcState.UpdateFPRFSingle(Common::BitCast(single_input)); }); - const u32 actual_single = RunUpdateFPRF([&] { test.fprf_single(single_input); }); + ppc_state, [&] { ppc_state.UpdateFPRFSingle(Common::BitCast(single_input)); }); + const u32 actual_single = RunUpdateFPRF(ppc_state, [&] { test.fprf_single(single_input); }); EXPECT_EQ(expected_single, actual_single); } } diff --git a/Source/UnitTests/Core/PowerPC/JitArm64/Fres.cpp b/Source/UnitTests/Core/PowerPC/JitArm64/Fres.cpp index ea82ea9c98..d2624f117d 100644 --- a/Source/UnitTests/Core/PowerPC/JitArm64/Fres.cpp +++ b/Source/UnitTests/Core/PowerPC/JitArm64/Fres.cpp @@ -34,7 +34,7 @@ public: fres = Common::BitCast(GetCodePtr()); MOV(ARM64Reg::X15, ARM64Reg::X30); MOV(ARM64Reg::X14, PPC_REG); - MOVP2R(PPC_REG, &PowerPC::ppcState); + MOVP2R(PPC_REG, &system.GetPPCState()); MOV(ARM64Reg::X1, ARM64Reg::X0); m_float_emit.FMOV(ARM64Reg::D0, ARM64Reg::X0); m_float_emit.FRECPE(ARM64Reg::D0, ARM64Reg::D0); diff --git a/Source/UnitTests/Core/PowerPC/JitArm64/Frsqrte.cpp b/Source/UnitTests/Core/PowerPC/JitArm64/Frsqrte.cpp index af15857476..cf5bfd0df0 100644 --- a/Source/UnitTests/Core/PowerPC/JitArm64/Frsqrte.cpp +++ b/Source/UnitTests/Core/PowerPC/JitArm64/Frsqrte.cpp @@ -34,7 +34,7 @@ public: frsqrte = Common::BitCast(GetCodePtr()); MOV(ARM64Reg::X15, ARM64Reg::X30); MOV(ARM64Reg::X14, PPC_REG); - MOVP2R(PPC_REG, &PowerPC::ppcState); + MOVP2R(PPC_REG, &system.GetPPCState()); MOV(ARM64Reg::X1, ARM64Reg::X0); m_float_emit.FMOV(ARM64Reg::D0, ARM64Reg::X0); m_float_emit.FRSQRTE(ARM64Reg::D0, ARM64Reg::D0);