Merge pull request #12442 from lioncash/hle
Core/HLE/HLE: Remove global system accessors
This commit is contained in:
commit
01340d7f8d
|
@ -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());
|
ASSERT(Core::IsCPUThread());
|
||||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
Core::CPUThreadGuard guard(system);
|
||||||
Execute(guard, current_pc, hook_index);
|
Execute(guard, current_pc, hook_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ HookFlag GetHookFlagsByIndex(u32 index)
|
||||||
return os_patches[index].flags;
|
return os_patches[index].flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
TryReplaceFunctionResult TryReplaceFunction(u32 address)
|
TryReplaceFunctionResult TryReplaceFunction(u32 address, PowerPC::CoreMode mode)
|
||||||
{
|
{
|
||||||
const u32 hook_index = GetHookByFunctionAddress(address);
|
const u32 hook_index = GetHookByFunctionAddress(address);
|
||||||
if (hook_index == 0)
|
if (hook_index == 0)
|
||||||
|
@ -211,16 +211,16 @@ TryReplaceFunctionResult TryReplaceFunction(u32 address)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const HookFlag flags = GetHookFlagsByIndex(hook_index);
|
const HookFlag flags = GetHookFlagsByIndex(hook_index);
|
||||||
if (!IsEnabled(flags))
|
if (!IsEnabled(flags, mode))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return {type, hook_index};
|
return {type, hook_index};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsEnabled(HookFlag flag)
|
bool IsEnabled(HookFlag flag, PowerPC::CoreMode mode)
|
||||||
{
|
{
|
||||||
return flag != HLE::HookFlag::Debug || Config::IsDebuggingEnabled() ||
|
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)
|
u32 UnPatch(Core::System& system, std::string_view patch_name)
|
||||||
|
|
|
@ -13,6 +13,11 @@ class CPUThreadGuard;
|
||||||
class System;
|
class System;
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
|
namespace PowerPC
|
||||||
|
{
|
||||||
|
enum class CoreMode;
|
||||||
|
}
|
||||||
|
|
||||||
namespace HLE
|
namespace HLE
|
||||||
{
|
{
|
||||||
using HookFunction = void (*)(const Core::CPUThreadGuard&);
|
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 UnPatch(Core::System& system, std::string_view patch_name);
|
||||||
u32 UnpatchRange(Core::System& system, u32 start_addr, u32 end_addr);
|
u32 UnpatchRange(Core::System& system, u32 start_addr, u32 end_addr);
|
||||||
void Execute(const Core::CPUThreadGuard& guard, u32 current_pc, u32 hook_index);
|
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
|
// Returns the HLE hook index of the address
|
||||||
u32 GetHookByAddress(u32 address);
|
u32 GetHookByAddress(u32 address);
|
||||||
|
@ -65,10 +70,10 @@ u32 GetHookByFunctionAddress(u32 address);
|
||||||
HookType GetHookTypeByIndex(u32 index);
|
HookType GetHookTypeByIndex(u32 index);
|
||||||
HookFlag GetHookFlagsByIndex(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
|
// 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.
|
// 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
|
} // namespace HLE
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Core/Core.h"
|
||||||
#include "Core/GeckoCode.h"
|
#include "Core/GeckoCode.h"
|
||||||
#include "Core/HW/CPU.h"
|
#include "Core/HW/CPU.h"
|
||||||
#include "Core/Host.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.
|
// 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.
|
// 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();
|
auto& ppc_state = system.GetPPCState();
|
||||||
ppc_state.npc = LR(ppc_state);
|
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.
|
// There isn't much we can do. Just stop cleanly.
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = guard.GetSystem();
|
||||||
system.GetCPU().Break();
|
system.GetCPU().Break();
|
||||||
Host_Message(HostMessageID::WMUserStop);
|
Host_Message(HostMessageID::WMUserStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeckoCodeHandlerICacheFlush(const Core::CPUThreadGuard& guard)
|
void GeckoCodeHandlerICacheFlush(const Core::CPUThreadGuard& guard)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = guard.GetSystem();
|
||||||
auto& ppc_state = system.GetPPCState();
|
auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
// Work around the codehandler not properly invalidating the icache, but
|
// 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.
|
// and PC before the magic, invisible BL instruction happened.
|
||||||
void GeckoReturnTrampoline(const Core::CPUThreadGuard& guard)
|
void GeckoReturnTrampoline(const Core::CPUThreadGuard& guard)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = guard.GetSystem();
|
||||||
auto& ppc_state = system.GetPPCState();
|
auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
// Stack frame is built in GeckoCode.cpp, Gecko::RunCodeHandler.
|
// 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.gpr[1] = PowerPC::MMU::HostRead_U32(guard, SP + 8);
|
||||||
ppc_state.npc = PowerPC::MMU::HostRead_U32(guard, SP + 12);
|
ppc_state.npc = PowerPC::MMU::HostRead_U32(guard, SP + 12);
|
||||||
LR(ppc_state) = PowerPC::MMU::HostRead_U32(guard, SP + 16);
|
LR(ppc_state) = PowerPC::MMU::HostRead_U32(guard, SP + 16);
|
||||||
|
|
|
@ -30,15 +30,13 @@ enum class ParameterType : bool
|
||||||
VariableArgumentList = true
|
VariableArgumentList = true
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string GetStringVA(Core::System& system, const Core::CPUThreadGuard& guard, u32 str_reg = 3,
|
static std::string GetStringVA(Core::System& system, const Core::CPUThreadGuard& guard,
|
||||||
|
u32 str_reg = 3,
|
||||||
ParameterType parameter_type = ParameterType::ParameterList);
|
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);
|
|
||||||
|
|
||||||
void HLE_OSPanic(const Core::CPUThreadGuard& guard)
|
void HLE_OSPanic(const Core::CPUThreadGuard& guard)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = guard.GetSystem();
|
||||||
auto& ppc_state = system.GetPPCState();
|
auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
std::string error = GetStringVA(system, guard);
|
std::string error = GetStringVA(system, guard);
|
||||||
|
@ -55,10 +53,10 @@ void HLE_OSPanic(const Core::CPUThreadGuard& guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generalized function for printing formatted string.
|
// 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& system = guard.GetSystem();
|
||||||
auto& ppc_state = system.GetPPCState();
|
const auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
std::string report_message;
|
std::string report_message;
|
||||||
|
|
||||||
|
@ -114,7 +112,7 @@ void HLE_GeneralDebugVPrint(const Core::CPUThreadGuard& guard)
|
||||||
void HLE_write_console(const Core::CPUThreadGuard& guard)
|
void HLE_write_console(const Core::CPUThreadGuard& guard)
|
||||||
{
|
{
|
||||||
auto& system = guard.GetSystem();
|
auto& system = guard.GetSystem();
|
||||||
auto& ppc_state = system.GetPPCState();
|
const auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
std::string report_message = GetStringVA(system, guard, 4);
|
std::string report_message = GetStringVA(system, guard, 4);
|
||||||
if (PowerPC::MMU::HostIsRAMAddress(guard, ppc_state.gpr[5]))
|
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)
|
// 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& system = guard.GetSystem();
|
||||||
auto& ppc_state = system.GetPPCState();
|
const auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
if (ppc_state.gpr[3] != 1 && ppc_state.gpr[3] != 2)
|
if (ppc_state.gpr[3] != 1 && ppc_state.gpr[3] != 2)
|
||||||
return;
|
return;
|
||||||
|
@ -168,10 +166,10 @@ void HLE_LogVDPrint(const Core::CPUThreadGuard& guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log (v)fprintf message if FILE is stdout or stderr
|
// 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& system = guard.GetSystem();
|
||||||
auto& ppc_state = system.GetPPCState();
|
const auto& ppc_state = system.GetPPCState();
|
||||||
|
|
||||||
// The structure FILE is implementation defined.
|
// The structure FILE is implementation defined.
|
||||||
// Both libogc and Dolphin SDK seem to store the fd at the same address.
|
// Both libogc and Dolphin SDK seem to store the fd at the same address.
|
||||||
|
@ -242,7 +240,7 @@ private:
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::string GetStringVA(Core::System& system, const Core::CPUThreadGuard& guard, u32 str_reg,
|
static std::string GetStringVA(Core::System& system, const Core::CPUThreadGuard& guard, u32 str_reg,
|
||||||
ParameterType parameter_type)
|
ParameterType parameter_type)
|
||||||
{
|
{
|
||||||
auto& ppc_state = system.GetPPCState();
|
auto& ppc_state = system.GetPPCState();
|
||||||
|
|
|
@ -269,7 +269,9 @@ bool CachedInterpreter::CheckIdle(CachedInterpreter& cached_interpreter, u32 idl
|
||||||
|
|
||||||
bool CachedInterpreter::HandleFunctionHooking(u32 address)
|
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)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ void Interpreter::Trace(const UGeckoInstruction& inst)
|
||||||
|
|
||||||
bool Interpreter::HandleFunctionHooking(u32 address)
|
bool Interpreter::HandleFunctionHooking(u32 address)
|
||||||
{
|
{
|
||||||
const auto result = HLE::TryReplaceFunction(address);
|
const auto result = HLE::TryReplaceFunction(address, PowerPC::CoreMode::Interpreter);
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -396,7 +396,7 @@ void Jit64::HLEFunction(u32 hook_index)
|
||||||
gpr.Flush();
|
gpr.Flush();
|
||||||
fpr.Flush();
|
fpr.Flush();
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionCC(HLE::ExecuteFromJIT, js.compilerPC, hook_index);
|
ABI_CallFunctionCCP(HLE::ExecuteFromJIT, js.compilerPC, hook_index, &m_system);
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1274,7 +1274,7 @@ void Jit64::IntializeSpeculativeConstants()
|
||||||
|
|
||||||
bool Jit64::HandleFunctionHooking(u32 address)
|
bool Jit64::HandleFunctionHooking(u32 address)
|
||||||
{
|
{
|
||||||
const auto result = HLE::TryReplaceFunction(address);
|
const auto result = HLE::TryReplaceFunction(address, PowerPC::CoreMode::JIT);
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -248,7 +248,7 @@ void JitArm64::HLEFunction(u32 hook_index)
|
||||||
gpr.Flush(FlushMode::All, ARM64Reg::INVALID_REG);
|
gpr.Flush(FlushMode::All, ARM64Reg::INVALID_REG);
|
||||||
fpr.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)
|
void JitArm64::DoNothing(UGeckoInstruction inst)
|
||||||
|
@ -781,7 +781,7 @@ void JitArm64::WriteConditionalExceptionExit(int exception, ARM64Reg temp_gpr, A
|
||||||
|
|
||||||
bool JitArm64::HandleFunctionHooking(u32 address)
|
bool JitArm64::HandleFunctionHooking(u32 address)
|
||||||
{
|
{
|
||||||
const auto result = HLE::TryReplaceFunction(address);
|
const auto result = HLE::TryReplaceFunction(address, PowerPC::CoreMode::JIT);
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -998,7 +998,8 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer,
|
||||||
crDiscardable = BitSet8{};
|
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 may_exit_block = hle || op.canEndBlock || op.canCauseException;
|
||||||
|
|
||||||
const bool opWantsFPRF = op.wantsFPRF;
|
const bool opWantsFPRF = op.wantsFPRF;
|
||||||
|
|
Loading…
Reference in New Issue