summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMarkus Wick <degasus@users.noreply.github.com>2020-11-04 10:29:37 +0100
committerGitHub <noreply@github.com>2020-11-04 10:29:37 +0100
commit069840fb7efedf4623b7aa2c63f7a035e0d23bfd (patch)
tree2fc66cc5e73a9f970d08d4b89589c269fff0bcb6 /Source/Core
parent3cd4c56645541640f61a761dfde16464b1ef09df (diff)
parentfe986b6161656b03cf2d4372bc34c3dc43560bb3 (diff)
Merge pull request #9218 from JosJuice/aarch64-hle-hooks
JitArm64: Implement HLE function hooking
Diffstat (limited to 'Source/Core')
-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()
{