diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h index 97ca0af716..9a54b3a3b5 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/PowerPC/Jit64/Jit.h @@ -243,7 +243,7 @@ private: // The default code buffer. We keep it around to not have to alloc/dealloc a // large chunk of memory for each recompiled block. PPCAnalyst::CodeBuffer code_buffer; - Jit64AsmRoutineManager asm_routines; + Jit64AsmRoutineManager asm_routines{*this}; bool m_enable_blr_optimization; bool m_cleanup_after_stackfault; diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp index 9c62303f50..872db4e46a 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp @@ -18,6 +18,10 @@ using namespace Gen; +Jit64AsmRoutineManager::Jit64AsmRoutineManager(JitBase& jit) : m_jit{jit} +{ +} + void Jit64AsmRoutineManager::Init(u8* stack_top) { m_const_pool.Init(AllocChildCodeSpace(4096), 4096); @@ -108,7 +112,7 @@ void Jit64AsmRoutineManager::Generate() // Fast block number lookup. // ((PC >> 2) & mask) * sizeof(JitBlock*) = (PC & (mask << 2)) * 2 MOV(32, R(RSCRATCH), PPCSTATE(pc)); - u64 icache = reinterpret_cast(g_jit->GetBlockCache()->GetFastBlockMap()); + u64 icache = reinterpret_cast(m_jit.GetBlockCache()->GetFastBlockMap()); AND(32, R(RSCRATCH), Imm32(JitBaseBlockCache::FAST_BLOCK_MAP_MASK << 2)); if (icache <= INT_MAX) { @@ -151,6 +155,7 @@ void Jit64AsmRoutineManager::Generate() // Ok, no block, let's call the slow dispatcher ABI_PushRegistersAndAdjustStack({}, 0); + MOV(64, R(ABI_PARAM1), Imm64(reinterpret_cast(&m_jit))); ABI_CallFunction(JitBase::Dispatch); ABI_PopRegistersAndAdjustStack({}, 0); @@ -175,7 +180,8 @@ void Jit64AsmRoutineManager::Generate() ResetStack(*this); ABI_PushRegistersAndAdjustStack({}, 0); - MOV(32, R(ABI_PARAM1), PPCSTATE(pc)); + MOV(64, R(ABI_PARAM1), Imm64(reinterpret_cast(&m_jit))); + MOV(32, R(ABI_PARAM2), PPCSTATE(pc)); ABI_CallFunction(JitTrampoline); ABI_PopRegistersAndAdjustStack({}, 0); diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.h b/Source/Core/Core/PowerPC/Jit64/JitAsm.h index 6aaad10031..1d1b2e534e 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.h +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.h @@ -12,6 +12,8 @@ namespace Gen class X64CodeBlock; } +class JitBase; + // In Dolphin, we don't use inline assembly. Instead, we generate all machine-near // code at runtime. In the case of fixed code like this, after writing it, we write // protect the memory, essentially making it work just like precompiled code. @@ -28,17 +30,21 @@ class X64CodeBlock; class Jit64AsmRoutineManager : public CommonAsmRoutines { -private: - void Generate(); - void GenerateCommon(); - u8* m_stack_top; - public: // NOTE: When making large additions to the AsmCommon code, you might // want to ensure this number is big enough. static constexpr size_t CODE_SIZE = 16384; + explicit Jit64AsmRoutineManager(JitBase& jit); + void Init(u8* stack_top); void ResetStack(Gen::X64CodeBlock& emitter); + +private: + void Generate(); + void GenerateCommon(); + + u8* m_stack_top = nullptr; + JitBase& m_jit; }; diff --git a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp index 316336b667..afb7a4031b 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp @@ -124,6 +124,7 @@ void JitArm64::GenerateAsm() // Call C version of Dispatch(). STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); + MOVP2R(X0, this); MOVP2R(X30, reinterpret_cast(&JitBase::Dispatch)); BLR(X30); @@ -141,7 +142,8 @@ void JitArm64::GenerateAsm() // Call JIT SetJumpTarget(no_block_available); ResetStack(); - MOV(W0, DISPATCHER_PC); + MOVP2R(X0, this); + MOV(W1, DISPATCHER_PC); MOVP2R(X30, reinterpret_cast(&JitTrampoline)); BLR(X30); LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); diff --git a/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp b/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp index aa111117b6..4f6b003fe4 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp @@ -12,9 +12,14 @@ JitBase* g_jit; -void JitTrampoline(u32 em_address) +const u8* JitBase::Dispatch(JitBase& jit) { - g_jit->Jit(em_address); + return jit.GetBlockCache()->Dispatch(); +} + +void JitTrampoline(JitBase& jit, u32 em_address) +{ + jit.Jit(em_address); } u32 Helper_Mask(u8 mb, u8 me) diff --git a/Source/Core/Core/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/PowerPC/JitCommon/JitBase.h index 0579e0a809..ac834090a3 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitBase.h +++ b/Source/Core/Core/PowerPC/JitCommon/JitBase.h @@ -116,7 +116,7 @@ public: JitBase(); ~JitBase() override; - static const u8* Dispatch() { return g_jit->GetBlockCache()->Dispatch(); } + static const u8* Dispatch(JitBase& jit); virtual JitBaseBlockCache* GetBlockCache() = 0; virtual void Jit(u32 em_address) = 0; @@ -127,7 +127,7 @@ public: virtual bool HandleStackFault() { return false; } }; -void JitTrampoline(u32 em_address); +void JitTrampoline(JitBase& jit, u32 em_address); // Merged routines that should be moved somewhere better u32 Helper_Mask(u8 mb, u8 me);