diff --git a/Source/Core/Core/HLE/HLE.cpp b/Source/Core/Core/HLE/HLE.cpp index c25a3232f5..5d7de6eccf 100644 --- a/Source/Core/Core/HLE/HLE.cpp +++ b/Source/Core/Core/HLE/HLE.cpp @@ -166,10 +166,10 @@ void Execute(const Core::CPUThreadGuard& guard, u32 current_pc, u32 hook_index) } } -void ExecuteFromJIT(u32 current_pc, u32 hook_index) +void ExecuteFromJIT(u32 current_pc, u32 hook_index, Core::System& system) { ASSERT(Core::IsCPUThread()); - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(system); Execute(guard, current_pc, hook_index); } @@ -200,7 +200,7 @@ HookFlag GetHookFlagsByIndex(u32 index) return os_patches[index].flags; } -TryReplaceFunctionResult TryReplaceFunction(u32 address) +TryReplaceFunctionResult TryReplaceFunction(u32 address, PowerPC::CoreMode mode) { const u32 hook_index = GetHookByFunctionAddress(address); if (hook_index == 0) @@ -211,16 +211,16 @@ TryReplaceFunctionResult TryReplaceFunction(u32 address) return {}; const HookFlag flags = GetHookFlagsByIndex(hook_index); - if (!IsEnabled(flags)) + if (!IsEnabled(flags, mode)) return {}; return {type, hook_index}; } -bool IsEnabled(HookFlag flag) +bool IsEnabled(HookFlag flag, PowerPC::CoreMode mode) { return flag != HLE::HookFlag::Debug || Config::IsDebuggingEnabled() || - Core::System::GetInstance().GetPowerPC().GetMode() == PowerPC::CoreMode::Interpreter; + mode == PowerPC::CoreMode::Interpreter; } u32 UnPatch(Core::System& system, std::string_view patch_name) diff --git a/Source/Core/Core/HLE/HLE.h b/Source/Core/Core/HLE/HLE.h index 725ef1aa54..3935ce4c5e 100644 --- a/Source/Core/Core/HLE/HLE.h +++ b/Source/Core/Core/HLE/HLE.h @@ -13,6 +13,11 @@ class CPUThreadGuard; class System; } // namespace Core +namespace PowerPC +{ +enum class CoreMode; +} + namespace HLE { using HookFunction = void (*)(const Core::CPUThreadGuard&); @@ -56,7 +61,7 @@ void Patch(Core::System& system, u32 pc, std::string_view func_name); u32 UnPatch(Core::System& system, std::string_view patch_name); u32 UnpatchRange(Core::System& system, u32 start_addr, u32 end_addr); void Execute(const Core::CPUThreadGuard& guard, u32 current_pc, u32 hook_index); -void ExecuteFromJIT(u32 current_pc, u32 hook_index); +void ExecuteFromJIT(u32 current_pc, u32 hook_index, Core::System& system); // Returns the HLE hook index of the address u32 GetHookByAddress(u32 address); @@ -65,10 +70,10 @@ u32 GetHookByFunctionAddress(u32 address); HookType GetHookTypeByIndex(u32 index); HookFlag GetHookFlagsByIndex(u32 index); -bool IsEnabled(HookFlag flag); +bool IsEnabled(HookFlag flag, PowerPC::CoreMode mode); // Performs the backend-independent preliminary checking for whether a function // can be HLEd. If it can be, the information needed for HLEing it is returned. -TryReplaceFunctionResult TryReplaceFunction(u32 address); +TryReplaceFunctionResult TryReplaceFunction(u32 address, PowerPC::CoreMode mode); } // namespace HLE diff --git a/Source/Core/Core/HLE/HLE_Misc.cpp b/Source/Core/Core/HLE/HLE_Misc.cpp index e2adaffebb..91ca651342 100644 --- a/Source/Core/Core/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/HLE/HLE_Misc.cpp @@ -5,6 +5,7 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" +#include "Core/Core.h" #include "Core/GeckoCode.h" #include "Core/HW/CPU.h" #include "Core/Host.h" @@ -16,24 +17,24 @@ namespace HLE_Misc { // If you just want to kill a function, one of the three following are usually appropriate. // According to the PPC ABI, the return value is always in r3. -void UnimplementedFunction(const Core::CPUThreadGuard&) +void UnimplementedFunction(const Core::CPUThreadGuard& guard) { - auto& system = Core::System::GetInstance(); + auto& system = guard.GetSystem(); auto& ppc_state = system.GetPPCState(); ppc_state.npc = LR(ppc_state); } -void HBReload(const Core::CPUThreadGuard&) +void HBReload(const Core::CPUThreadGuard& guard) { // There isn't much we can do. Just stop cleanly. - auto& system = Core::System::GetInstance(); + auto& system = guard.GetSystem(); system.GetCPU().Break(); Host_Message(HostMessageID::WMUserStop); } void GeckoCodeHandlerICacheFlush(const Core::CPUThreadGuard& guard) { - auto& system = Core::System::GetInstance(); + auto& system = guard.GetSystem(); auto& ppc_state = system.GetPPCState(); // Work around the codehandler not properly invalidating the icache, but @@ -62,11 +63,11 @@ void GeckoCodeHandlerICacheFlush(const Core::CPUThreadGuard& guard) // and PC before the magic, invisible BL instruction happened. void GeckoReturnTrampoline(const Core::CPUThreadGuard& guard) { - auto& system = Core::System::GetInstance(); + auto& system = guard.GetSystem(); auto& ppc_state = system.GetPPCState(); // Stack frame is built in GeckoCode.cpp, Gecko::RunCodeHandler. - u32 SP = ppc_state.gpr[1]; + const u32 SP = ppc_state.gpr[1]; ppc_state.gpr[1] = PowerPC::MMU::HostRead_U32(guard, SP + 8); ppc_state.npc = PowerPC::MMU::HostRead_U32(guard, SP + 12); LR(ppc_state) = PowerPC::MMU::HostRead_U32(guard, SP + 16); diff --git a/Source/Core/Core/HLE/HLE_OS.cpp b/Source/Core/Core/HLE/HLE_OS.cpp index 52f3b43deb..084bd0ee25 100644 --- a/Source/Core/Core/HLE/HLE_OS.cpp +++ b/Source/Core/Core/HLE/HLE_OS.cpp @@ -30,15 +30,13 @@ enum class ParameterType : bool VariableArgumentList = true }; -std::string GetStringVA(Core::System& system, const Core::CPUThreadGuard& guard, u32 str_reg = 3, - ParameterType parameter_type = ParameterType::ParameterList); -void HLE_GeneralDebugPrint(const Core::CPUThreadGuard& guard, ParameterType parameter_type); -void HLE_LogDPrint(const Core::CPUThreadGuard& guard, ParameterType parameter_type); -void HLE_LogFPrint(const Core::CPUThreadGuard& guard, ParameterType parameter_type); +static std::string GetStringVA(Core::System& system, const Core::CPUThreadGuard& guard, + u32 str_reg = 3, + ParameterType parameter_type = ParameterType::ParameterList); void HLE_OSPanic(const Core::CPUThreadGuard& guard) { - auto& system = Core::System::GetInstance(); + auto& system = guard.GetSystem(); auto& ppc_state = system.GetPPCState(); std::string error = GetStringVA(system, guard); @@ -55,10 +53,10 @@ void HLE_OSPanic(const Core::CPUThreadGuard& guard) } // Generalized function for printing formatted string. -void HLE_GeneralDebugPrint(const Core::CPUThreadGuard& guard, ParameterType parameter_type) +static void HLE_GeneralDebugPrint(const Core::CPUThreadGuard& guard, ParameterType parameter_type) { - auto& system = Core::System::GetInstance(); - auto& ppc_state = system.GetPPCState(); + auto& system = guard.GetSystem(); + const auto& ppc_state = system.GetPPCState(); std::string report_message; @@ -114,7 +112,7 @@ void HLE_GeneralDebugVPrint(const Core::CPUThreadGuard& guard) void HLE_write_console(const Core::CPUThreadGuard& guard) { auto& system = guard.GetSystem(); - auto& ppc_state = system.GetPPCState(); + const auto& ppc_state = system.GetPPCState(); std::string report_message = GetStringVA(system, guard, 4); if (PowerPC::MMU::HostIsRAMAddress(guard, ppc_state.gpr[5])) @@ -139,10 +137,10 @@ void HLE_write_console(const Core::CPUThreadGuard& guard) } // Log (v)dprintf message if fd is 1 (stdout) or 2 (stderr) -void HLE_LogDPrint(const Core::CPUThreadGuard& guard, ParameterType parameter_type) +static void HLE_LogDPrint(const Core::CPUThreadGuard& guard, ParameterType parameter_type) { - auto& system = Core::System::GetInstance(); - auto& ppc_state = system.GetPPCState(); + auto& system = guard.GetSystem(); + const auto& ppc_state = system.GetPPCState(); if (ppc_state.gpr[3] != 1 && ppc_state.gpr[3] != 2) return; @@ -168,10 +166,10 @@ void HLE_LogVDPrint(const Core::CPUThreadGuard& guard) } // Log (v)fprintf message if FILE is stdout or stderr -void HLE_LogFPrint(const Core::CPUThreadGuard& guard, ParameterType parameter_type) +static void HLE_LogFPrint(const Core::CPUThreadGuard& guard, ParameterType parameter_type) { - auto& system = Core::System::GetInstance(); - auto& ppc_state = system.GetPPCState(); + auto& system = guard.GetSystem(); + const auto& ppc_state = system.GetPPCState(); // The structure FILE is implementation defined. // Both libogc and Dolphin SDK seem to store the fd at the same address. @@ -242,8 +240,8 @@ private: }; } // namespace -std::string GetStringVA(Core::System& system, const Core::CPUThreadGuard& guard, u32 str_reg, - ParameterType parameter_type) +static std::string GetStringVA(Core::System& system, const Core::CPUThreadGuard& guard, u32 str_reg, + ParameterType parameter_type) { auto& ppc_state = system.GetPPCState(); diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp index 8a836b6fe5..291321f97a 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp @@ -269,7 +269,9 @@ bool CachedInterpreter::CheckIdle(CachedInterpreter& cached_interpreter, u32 idl bool CachedInterpreter::HandleFunctionHooking(u32 address) { - const auto result = HLE::TryReplaceFunction(address); + // CachedInterpreter inherits from JitBase and is considered a JIT by relevant code. + // (see JitInterface and how m_mode is set within PowerPC.cpp) + const auto result = HLE::TryReplaceFunction(address, PowerPC::CoreMode::JIT); if (!result) return false; diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index 929ec185c4..71f01d13b7 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -106,7 +106,7 @@ void Interpreter::Trace(const UGeckoInstruction& inst) bool Interpreter::HandleFunctionHooking(u32 address) { - const auto result = HLE::TryReplaceFunction(address); + const auto result = HLE::TryReplaceFunction(address, PowerPC::CoreMode::Interpreter); if (!result) return false; diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 5938080b0e..4e8fa16889 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -396,7 +396,7 @@ void Jit64::HLEFunction(u32 hook_index) gpr.Flush(); fpr.Flush(); ABI_PushRegistersAndAdjustStack({}, 0); - ABI_CallFunctionCC(HLE::ExecuteFromJIT, js.compilerPC, hook_index); + ABI_CallFunctionCCP(HLE::ExecuteFromJIT, js.compilerPC, hook_index, &m_system); ABI_PopRegistersAndAdjustStack({}, 0); } @@ -1274,7 +1274,7 @@ void Jit64::IntializeSpeculativeConstants() bool Jit64::HandleFunctionHooking(u32 address) { - const auto result = HLE::TryReplaceFunction(address); + const auto result = HLE::TryReplaceFunction(address, PowerPC::CoreMode::JIT); if (!result) return false; diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 311f5d40d8..5d7e9b2831 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -248,7 +248,7 @@ void JitArm64::HLEFunction(u32 hook_index) gpr.Flush(FlushMode::All, ARM64Reg::INVALID_REG); fpr.Flush(FlushMode::All, ARM64Reg::INVALID_REG); - ABI_CallFunction(&HLE::ExecuteFromJIT, js.compilerPC, hook_index); + ABI_CallFunction(&HLE::ExecuteFromJIT, js.compilerPC, hook_index, &m_system); } void JitArm64::DoNothing(UGeckoInstruction inst) @@ -781,7 +781,7 @@ void JitArm64::WriteConditionalExceptionExit(int exception, ARM64Reg temp_gpr, A bool JitArm64::HandleFunctionHooking(u32 address) { - const auto result = HLE::TryReplaceFunction(address); + const auto result = HLE::TryReplaceFunction(address, PowerPC::CoreMode::JIT); if (!result) return false; diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index eaf49c7c46..3bf85b3dfb 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -998,7 +998,8 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, crDiscardable = BitSet8{}; } - const bool hle = !!HLE::TryReplaceFunction(op.address); + const auto ppc_mode = Core::System::GetInstance().GetPowerPC().GetMode(); + const bool hle = !!HLE::TryReplaceFunction(op.address, ppc_mode); const bool may_exit_block = hle || op.canEndBlock || op.canCauseException; const bool opWantsFPRF = op.wantsFPRF;