JitArm64: Implement HLE function hooking

Closely based on the x86-64 implementation.
Fixes https://bugs.dolphin-emu.org/issues/10965.
This commit is contained in:
JosJuice 2020-11-02 22:02:33 +01:00
parent c3bc079c81
commit fe986b6161
2 changed files with 24 additions and 8 deletions

View File

@ -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)

View File

@ -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()
{