summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2023-11-19 11:14:43 +0100
committerJosJuice <josjuice@gmail.com>2023-11-27 21:40:42 +0100
commitba6fea1c8189cc43431fdf245cb3dd3936dae6d2 (patch)
tree4c066265f91dcf30647a95bb40c92f666cf697b2 /Source
parentd28155a7bb081812990fee21a8b3a4d978b163bf (diff)
HLE: Refactor ReplaceFunctionIfPossible
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/HLE/HLE.cpp17
-rw-r--r--Source/Core/Core/HLE/HLE.h40
-rw-r--r--Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp20
-rw-r--r--Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp11
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.cpp20
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.cpp20
6 files changed, 69 insertions, 59 deletions
diff --git a/Source/Core/Core/HLE/HLE.cpp b/Source/Core/Core/HLE/HLE.cpp
index 310aec6620..2d4f3313f2 100644
--- a/Source/Core/Core/HLE/HLE.cpp
+++ b/Source/Core/Core/HLE/HLE.cpp
@@ -200,6 +200,23 @@ HookFlag GetHookFlagsByIndex(u32 index)
return os_patches[index].flags;
}
+TryReplaceFunctionResult TryReplaceFunction(u32 address)
+{
+ const u32 hook_index = GetHookByFunctionAddress(address);
+ if (hook_index == 0)
+ return {};
+
+ const HookType type = GetHookTypeByIndex(hook_index);
+ if (type != HookType::Start && type != HookType::Replace)
+ return {};
+
+ const HookFlag flags = GetHookFlagsByIndex(hook_index);
+ if (!IsEnabled(flags))
+ return {};
+
+ return {type, hook_index};
+}
+
bool IsEnabled(HookFlag flag)
{
return flag != HLE::HookFlag::Debug || Config::Get(Config::MAIN_ENABLE_DEBUGGING) ||
diff --git a/Source/Core/Core/HLE/HLE.h b/Source/Core/Core/HLE/HLE.h
index 330cf6a92f..725ef1aa54 100644
--- a/Source/Core/Core/HLE/HLE.h
+++ b/Source/Core/Core/HLE/HLE.h
@@ -19,9 +19,9 @@ using HookFunction = void (*)(const Core::CPUThreadGuard&);
enum class HookType
{
+ None, // Do not hook the function
Start, // Hook the beginning of the function and execute the function afterwards
Replace, // Replace the function with the HLE version
- None, // Do not hook the function
};
enum class HookFlag
@@ -39,6 +39,14 @@ struct Hook
HookFlag flags;
};
+struct TryReplaceFunctionResult
+{
+ HookType type = HookType::None;
+ u32 hook_index = 0;
+
+ explicit operator bool() const { return type != HookType::None; }
+};
+
void PatchFixedFunctions(Core::System& system);
void PatchFunctions(Core::System& system);
void Clear();
@@ -59,32 +67,8 @@ HookFlag GetHookFlagsByIndex(u32 index);
bool IsEnabled(HookFlag flag);
-// Performs the backend-independent preliminary checking before calling a
-// FunctionObject to do the actual replacing. Typically, this callback will
-// be in the backend itself, containing the backend-specific portions
-// required in replacing a function.
-//
-// fn may be any object that satisfies the FunctionObject concept in the C++
-// standard library. That is, any lambda, object with an overloaded function
-// call operator, or regular function pointer.
-//
-// fn must return a bool indicating whether or not function replacing occurred.
-// fn must also accept a parameter list of the form: fn(u32 function, HLE::HookType type).
-template <typename FunctionObject>
-bool ReplaceFunctionIfPossible(u32 address, FunctionObject fn)
-{
- const u32 hook_index = GetHookByFunctionAddress(address);
- if (hook_index == 0)
- return false;
-
- const HookType type = GetHookTypeByIndex(hook_index);
- if (type != HookType::Start && type != HookType::Replace)
- return false;
-
- const HookFlag flags = GetHookFlagsByIndex(hook_index);
- if (!IsEnabled(flags))
- return false;
+// 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);
- return fn(hook_index, type);
-}
} // namespace HLE
diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
index 8fbed42f06..8a836b6fe5 100644
--- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
+++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
@@ -269,17 +269,19 @@ bool CachedInterpreter::CheckIdle(CachedInterpreter& cached_interpreter, u32 idl
bool CachedInterpreter::HandleFunctionHooking(u32 address)
{
- return HLE::ReplaceFunctionIfPossible(address, [&](u32 hook_index, HLE::HookType type) {
- m_code.emplace_back(WritePC, address);
- m_code.emplace_back(Interpreter::HLEFunction, hook_index);
+ const auto result = HLE::TryReplaceFunction(address);
+ if (!result)
+ return false;
- if (type != HLE::HookType::Replace)
- return false;
+ m_code.emplace_back(WritePC, address);
+ m_code.emplace_back(Interpreter::HLEFunction, result.hook_index);
- m_code.emplace_back(EndBlock, js.downcountAmount);
- m_code.emplace_back();
- return true;
- });
+ if (result.type != HLE::HookType::Replace)
+ return false;
+
+ m_code.emplace_back(EndBlock, js.downcountAmount);
+ m_code.emplace_back();
+ return true;
}
void CachedInterpreter::Jit(u32 address)
diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp
index 168df8deaf..f3d3619f1b 100644
--- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp
+++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp
@@ -106,10 +106,13 @@ void Interpreter::Trace(const UGeckoInstruction& inst)
bool Interpreter::HandleFunctionHooking(u32 address)
{
- return HLE::ReplaceFunctionIfPossible(address, [this](u32 hook_index, HLE::HookType type) {
- HLEFunction(*this, hook_index);
- return type != HLE::HookType::Start;
- });
+ const auto result = HLE::TryReplaceFunction(address);
+ if (!result)
+ return false;
+
+ HLEFunction(*this, result.hook_index);
+
+ return result.type != HLE::HookType::Start;
}
int Interpreter::SingleStepInner()
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
index 9b089196b8..5cd47cd092 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
@@ -1238,17 +1238,19 @@ void Jit64::IntializeSpeculativeConstants()
bool Jit64::HandleFunctionHooking(u32 address)
{
- return HLE::ReplaceFunctionIfPossible(address, [&](u32 hook_index, HLE::HookType type) {
- HLEFunction(hook_index);
+ const auto result = HLE::TryReplaceFunction(address);
+ if (!result)
+ return false;
- if (type != HLE::HookType::Replace)
- return false;
+ HLEFunction(result.hook_index);
- MOV(32, R(RSCRATCH), PPCSTATE(npc));
- js.downcountAmount += js.st.numCycles;
- WriteExitDestInRSCRATCH();
- return true;
- });
+ if (result.type != HLE::HookType::Replace)
+ return false;
+
+ MOV(32, R(RSCRATCH), PPCSTATE(npc));
+ js.downcountAmount += js.st.numCycles;
+ WriteExitDestInRSCRATCH();
+ return true;
}
void LogGeneratedX86(size_t size, const PPCAnalyst::CodeBuffer& code_buffer, const u8* normalEntry,
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
index df782e4de8..a2dc1cb6b7 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
@@ -696,17 +696,19 @@ void JitArm64::WriteConditionalExceptionExit(int exception, ARM64Reg temp_gpr, A
bool JitArm64::HandleFunctionHooking(u32 address)
{
- return HLE::ReplaceFunctionIfPossible(address, [&](u32 hook_index, HLE::HookType type) {
- HLEFunction(hook_index);
+ const auto result = HLE::TryReplaceFunction(address);
+ if (!result)
+ return false;
+
+ HLEFunction(result.hook_index);
- if (type != HLE::HookType::Replace)
- return false;
+ if (result.type != HLE::HookType::Replace)
+ return false;
- LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
- js.downcountAmount += js.st.numCycles;
- WriteExit(DISPATCHER_PC);
- return true;
- });
+ LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
+ js.downcountAmount += js.st.numCycles;
+ WriteExit(DISPATCHER_PC);
+ return true;
}
void JitArm64::DumpCode(const u8* start, const u8* end)