summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2020-11-02 22:02:33 +0100
committerJosJuice <josjuice@gmail.com>2020-11-03 09:48:22 +0100
commitfe986b6161656b03cf2d4372bc34c3dc43560bb3 (patch)
tree631a649194c35b269fcab6183b97d00e67ac85d4 /Source
parentc3bc079c815d739f5bb43f89df708ffc53b6efc0 (diff)
JitArm64: Implement HLE function hooking
Closely based on the x86-64 implementation. Fixes https://bugs.dolphin-emu.org/issues/10965.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.cpp28
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.h4
2 files changed, 24 insertions, 8 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
index 3a48ae7df4..83b35f4108 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
@@ -209,20 +209,16 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
}
}
-void JitArm64::HLEFunction(UGeckoInstruction inst)
+void JitArm64::HLEFunction(u32 hook_index)
{
+ FlushCarry();
gpr.Flush(FlushMode::FLUSH_ALL);
fpr.Flush(FlushMode::FLUSH_ALL);
MOVI2R(W0, js.compilerPC);
- MOVI2R(W1, inst.hex);
+ MOVI2R(W1, hook_index);
MOVP2R(X30, &HLE::Execute);
BLR(X30);
-
- ARM64Reg WA = gpr.GetReg();
- LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(npc));
- WriteExit(WA);
- gpr.Unlock(WA);
}
void JitArm64::DoNothing(UGeckoInstruction inst)
@@ -490,6 +486,21 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external)
B(dispatcher);
}
+bool JitArm64::HandleFunctionHooking(u32 address)
+{
+ return HLE::ReplaceFunctionIfPossible(address, [&](u32 hook_index, HLE::HookType type) {
+ HLEFunction(hook_index);
+
+ if (type != HLE::HookType::Replace)
+ return false;
+
+ LDR(INDEX_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)
{
std::string output;
@@ -748,6 +759,9 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
SetJumpTarget(exit);
}
+ if (HandleFunctionHooking(op.address))
+ break;
+
if (!op.skip)
{
if ((opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound)
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h
index a9a982ded4..a654109496 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.h
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h
@@ -46,7 +46,7 @@ public:
// OPCODES
void FallBackToInterpreter(UGeckoInstruction inst);
void DoNothing(UGeckoInstruction inst);
- void HLEFunction(UGeckoInstruction inst);
+ void HLEFunction(u32 hook_index);
void DynaRunTable4(UGeckoInstruction inst);
void DynaRunTable19(UGeckoInstruction inst);
@@ -175,6 +175,8 @@ private:
static void InitializeInstructionTables();
void CompileInstruction(PPCAnalyst::CodeOp& op);
+ bool HandleFunctionHooking(u32 address);
+
// Simple functions to switch between near and far code emitting
void SwitchToFarCode()
{