diff options
| author | JosJuice <josjuice@gmail.com> | 2020-11-02 22:02:33 +0100 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2020-11-03 09:48:22 +0100 |
| commit | fe986b6161656b03cf2d4372bc34c3dc43560bb3 (patch) | |
| tree | 631a649194c35b269fcab6183b97d00e67ac85d4 /Source | |
| parent | c3bc079c815d739f5bb43f89df708ffc53b6efc0 (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.cpp | 28 | ||||
| -rw-r--r-- | Source/Core/Core/PowerPC/JitArm64/Jit.h | 4 |
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() { |
