diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 99b6ba2ab1..d7dbf11729 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -193,31 +193,28 @@ void JitArm64::WriteExit(u32 destination) linkData.exitAddress = destination; linkData.exitPtrs = GetWritableCodePtr(); linkData.linkStatus = false; + b->linkData.push_back(linkData); // the code generated in JitArm64BlockCache::WriteDestroyBlock must fit in this block - ARM64Reg WA = gpr.GetReg(); - ARM64Reg XA = EncodeRegTo64(WA); - MOVI2R(WA, destination); - STR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(pc)); - MOVI2R(XA, (u64)asm_routines.dispatcher); - BR(XA); - gpr.Unlock(WA); - - b->linkData.push_back(linkData); + MOVI2R(X30, (u64)asm_routines.dispatcher); + MOVI2R(DISPATCHER_PC, destination); + BR(X30); } void JitArm64::WriteExit(ARM64Reg Reg) { - STR(INDEX_UNSIGNED, Reg, X29, PPCSTATE_OFF(pc)); Cleanup(); DoDownCount(); + if (Reg != DISPATCHER_PC) + MOV(DISPATCHER_PC, Reg); + gpr.Unlock(Reg); + if (Profiler::g_ProfileBlocks) EndTimeProfile(js.curBlock); - MOVI2R(EncodeRegTo64(Reg), (u64)asm_routines.dispatcher); - BR(EncodeRegTo64(Reg)); - gpr.Unlock(Reg); + MOVI2R(X30, (u64)asm_routines.dispatcher); + BR(X30); } void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external) @@ -227,10 +224,10 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external) ARM64Reg WA = gpr.GetReg(); LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); - STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(pc)); FixupBranch no_exceptions = CBZ(WA); gpr.Unlock(WA); + STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(pc)); STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(npc)); if (only_external) MOVI2R(EncodeRegTo64(dest), (u64)&PowerPC::CheckExternalExceptions); @@ -238,17 +235,18 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external) MOVI2R(EncodeRegTo64(dest), (u64)&PowerPC::CheckExceptions); BLR(EncodeRegTo64(dest)); LDR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(npc)); - STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(pc)); SetJumpTarget(no_exceptions); + if (dest != DISPATCHER_PC) + MOV(DISPATCHER_PC, dest); + gpr.Unlock(dest); + if (Profiler::g_ProfileBlocks) EndTimeProfile(js.curBlock); - MOVI2R(EncodeRegTo64(dest), (u64)asm_routines.dispatcher); - BR(EncodeRegTo64(dest)); - - gpr.Unlock(dest); + MOVI2R(X30, (u64)asm_routines.dispatcher); + BR(X30); } void JitArm64::DumpCode(const u8* start, const u8* end) @@ -389,8 +387,7 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB FixupBranch bail = B(CC_PL); ARM64Reg WA = gpr.GetReg(); ARM64Reg XA = EncodeRegTo64(WA); - MOVI2R(WA, js.blockStart); - STR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(pc)); + MOVI2R(DISPATCHER_PC, js.blockStart); MOVI2R(XA, (u64)asm_routines.doTiming); BR(XA); gpr.Unlock(WA); @@ -423,8 +420,8 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB FixupBranch fail = B(); SwitchToFarCode(); SetJumpTarget(fail); - MOVI2R(W0, js.blockStart); - STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(pc)); + MOVI2R(DISPATCHER_PC, js.blockStart); + STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); MOVI2R(W0, (u32)JitInterface::ExceptionType::EXCEPTIONS_PAIRED_QUANTIZE); MOVI2R(X1, (u64)&JitInterface::CompileExceptionCheck); BLR(X1); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.cpp index 0d76e3ecb5..cc416fc97e 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64Cache.cpp @@ -29,9 +29,8 @@ void JitArm64BlockCache::WriteDestroyBlock(const u8* location, u32 address) { // must fit within the code generated in JitArm64::WriteExit ARM64XEmitter emit((u8 *)location); - emit.MOVI2R(W0, address); emit.MOVI2R(X30, (u64)jit->GetAsmRoutines()->dispatcher); - emit.STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(pc)); + emit.MOVI2R(DISPATCHER_PC, address); emit.BR(X30); emit.FlushIcache(); } diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h index db6f63e292..2af6281a49 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h @@ -17,6 +17,7 @@ using namespace Arm64Gen; // Dedicated host registers static const ARM64Reg MEM_REG = X28; // memory base register static const ARM64Reg PPC_REG = X29; // ppcState pointer +static const ARM64Reg DISPATCHER_PC = W26; // register for PC when calling the dispatcher #define PPCSTATE_OFF(elem) (offsetof(PowerPC::PowerPCState, elem)) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp index d9ac75f5c6..2a40b9fce7 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp @@ -28,6 +28,9 @@ void JitArm64AsmRoutineManager::Generate() MOVI2R(PPC_REG, (u64)&PowerPC::ppcState); MOVI2R(MEM_REG, (u64)Memory::logical_base); + // Load the current PC into DISPATCHER_PC + LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); + FixupBranch to_dispatcher = B(); // If we align the dispatcher to a page then we can load its location with one ADRP instruction @@ -46,11 +49,10 @@ void JitArm64AsmRoutineManager::Generate() // This block of code gets the address of the compiled block of code // It runs though to the compiling portion if it isn't found - LDR(INDEX_UNSIGNED, W26, PPC_REG, PPCSTATE_OFF(pc)); // Load the current PC into W26 - BFM(W26, WSP, 3, 2); // Wipe the top 3 bits. Same as PC & JIT_ICACHE_MASK + BFM(DISPATCHER_PC, WSP, 3, 2); // Wipe the top 3 bits. Same as PC & JIT_ICACHE_MASK MOVI2R(X27, (u64)jit->GetBlockCache()->iCache.data()); - LDR(W27, X27, X26); + LDR(W27, X27, EncodeRegTo64(DISPATCHER_PC)); FixupBranch JitBlock = TBNZ(W27, 7); // Test the 7th bit // Success, it is our Jitblock. @@ -62,6 +64,8 @@ void JitArm64AsmRoutineManager::Generate() SetJumpTarget(JitBlock); + STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); + MOVI2R(X30, (u64)&Jit); BLR(X30); @@ -75,12 +79,11 @@ void JitArm64AsmRoutineManager::Generate() // Does exception checking LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(Exceptions)); FixupBranch no_exceptions = CBZ(W0); - LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(pc)); - STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(npc)); + STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); + STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc)); MOVI2R(X30, (u64)&PowerPC::CheckExceptions); BLR(X30); - LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(npc)); - STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(pc)); + LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc)); SetJumpTarget(no_exceptions); // Check the state pointer to see if we are exiting @@ -94,6 +97,7 @@ void JitArm64AsmRoutineManager::Generate() B(dispatcher); SetJumpTarget(Exit); + STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc)); // Let the waiting thread know we are done leaving MOVI2R(X0, (u64)&PowerPC::FinishStateMove);