From da79ddbde7457ca1c8d7c5eee9fd53c08c969f0a Mon Sep 17 00:00:00 2001 From: degasus Date: Tue, 22 Aug 2017 08:04:16 +0200 Subject: [PATCH] JitArm64: Rewrite Exit functions. The gpr must not be touched in the Exit functions as they are maybe conditional. So just allocate everything here manually. --- Source/Core/Core/PowerPC/JitArm64/Jit.cpp | 113 +++++++----------- .../Core/PowerPC/JitArm64/JitArm64_Branch.cpp | 6 +- 2 files changed, 48 insertions(+), 71 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 7cc2c476c2..4b27c13f00 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -161,6 +161,7 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst) ARM64Reg WA = gpr.GetReg(); LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(npc)); WriteExceptionExit(WA); + gpr.Unlock(WA); } else { @@ -174,6 +175,7 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst) FixupBranch c = B(CC_EQ); WriteExceptionExit(WA); SetJumpTarget(c); + gpr.Unlock(WA); } } @@ -211,6 +213,7 @@ void JitArm64::HLEFunction(UGeckoInstruction inst) ARM64Reg WA = gpr.GetReg(); LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(npc)); WriteExit(WA); + gpr.Unlock(WA); } void JitArm64::DoNothing(UGeckoInstruction inst) @@ -228,21 +231,16 @@ void JitArm64::Cleanup() { if (jo.optimizeGatherPipe && js.fifoBytesSinceCheck > 0) { - gpr.Lock(W0); MOVP2R(X0, &GPFifo::FastCheckGatherPipe); BLR(X0); - gpr.Unlock(W0); } } void JitArm64::DoDownCount() { - ARM64Reg WA = gpr.GetReg(); - LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(downcount)); - ARM64Reg WB = gpr.GetReg(); - SUBSI2R(WA, WA, js.downcountAmount, WB); - STR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(downcount)); - gpr.Unlock(WA, WB); + LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(downcount)); + SUBSI2R(W0, W0, js.downcountAmount, W1); + STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(downcount)); } void JitArm64::ResetStack() @@ -292,9 +290,7 @@ void JitArm64::WriteExit(u32 destination, bool LK, u32 exit_address_after_return { Cleanup(); DoDownCount(); - - if (Profiler::g_ProfileBlocks) - EndTimeProfile(js.curBlock); + EndTimeProfile(js.curBlock); LK &= m_enable_blr_optimization; @@ -331,17 +327,14 @@ void JitArm64::WriteExit(u32 destination, bool LK, u32 exit_address_after_return void JitArm64::WriteExit(Arm64Gen::ARM64Reg dest, bool LK, u32 exit_address_after_return) { - Cleanup(); - DoDownCount(); - - LK &= m_enable_blr_optimization; - if (dest != DISPATCHER_PC) MOV(DISPATCHER_PC, dest); - gpr.Unlock(dest); - if (Profiler::g_ProfileBlocks) - EndTimeProfile(js.curBlock); + Cleanup(); + DoDownCount(); + EndTimeProfile(js.curBlock); + + LK &= m_enable_blr_optimization; if (!LK) { @@ -407,35 +400,28 @@ void JitArm64::WriteBLRExit(Arm64Gen::ARM64Reg dest) return; } + if (dest != DISPATCHER_PC) + MOV(DISPATCHER_PC, dest); + Cleanup(); - - if (Profiler::g_ProfileBlocks) - EndTimeProfile(js.curBlock); - - ARM64Reg code = gpr.GetReg(); - ARM64Reg pc = gpr.GetReg(); + EndTimeProfile(js.curBlock); // Check if {ARM_PC, PPC_PC} matches the current state. - LDP(INDEX_POST, EncodeRegTo64(code), EncodeRegTo64(pc), SP, 16); - CMP(pc, dest); + LDP(INDEX_POST, X2, X1, SP, 16); + CMP(W1, DISPATCHER_PC); FixupBranch no_match = B(CC_NEQ); - DoDownCount(); + DoDownCount(); // overwrites X0 + X1 - RET(EncodeRegTo64(code)); + RET(X2); SetJumpTarget(no_match); DoDownCount(); - if (dest != DISPATCHER_PC) - MOV(DISPATCHER_PC, dest); - ResetStack(); B(dispatcher); - - gpr.Unlock(dest, pc, code); } void JitArm64::WriteExceptionExit(u32 destination, bool only_external) @@ -458,39 +444,34 @@ void JitArm64::WriteExceptionExit(u32 destination, bool only_external) SetJumpTarget(no_exceptions); - if (Profiler::g_ProfileBlocks) - EndTimeProfile(js.curBlock); + EndTimeProfile(js.curBlock); B(dispatcher); } void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external) { + if (dest != DISPATCHER_PC) + MOV(DISPATCHER_PC, dest); + Cleanup(); DoDownCount(); - ARM64Reg WA = gpr.GetReg(); - LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); - FixupBranch no_exceptions = CBZ(WA); - gpr.Unlock(WA); + LDR(INDEX_UNSIGNED, W30, PPC_REG, PPCSTATE_OFF(Exceptions)); + FixupBranch no_exceptions = CBZ(W30); - STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(pc)); - STR(INDEX_UNSIGNED, dest, 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)); if (only_external) - MOVP2R(EncodeRegTo64(dest), &PowerPC::CheckExternalExceptions); + MOVP2R(EncodeRegTo64(DISPATCHER_PC), &PowerPC::CheckExternalExceptions); else - MOVP2R(EncodeRegTo64(dest), &PowerPC::CheckExceptions); - BLR(EncodeRegTo64(dest)); - LDR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(npc)); + MOVP2R(EncodeRegTo64(DISPATCHER_PC), &PowerPC::CheckExceptions); + BLR(EncodeRegTo64(DISPATCHER_PC)); + LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc)); SetJumpTarget(no_exceptions); - if (dest != DISPATCHER_PC) - MOV(DISPATCHER_PC, dest); - gpr.Unlock(dest); - - if (Profiler::g_ProfileBlocks) - EndTimeProfile(js.curBlock); + EndTimeProfile(js.curBlock); B(dispatcher); } @@ -518,32 +499,24 @@ void JitArm64::BeginTimeProfile(JitBlock* b) void JitArm64::EndTimeProfile(JitBlock* b) { - ARM64Reg WA = gpr.GetReg(); - ARM64Reg XA = EncodeRegTo64(WA); - ARM64Reg WB = gpr.GetReg(); - ARM64Reg XB = EncodeRegTo64(WB); - ARM64Reg WC = gpr.GetReg(); - ARM64Reg XC = EncodeRegTo64(WC); - ARM64Reg WD = gpr.GetReg(); - ARM64Reg XD = EncodeRegTo64(WD); + if (!Profiler::g_ProfileBlocks) + return; // Fetch the current counter register - CNTVCT(XB); + CNTVCT(X1); - MOVP2R(XA, &b->profile_data); + MOVP2R(X0, &b->profile_data); - LDR(INDEX_UNSIGNED, XC, XA, offsetof(JitBlock::ProfileData, ticStart)); - SUB(XB, XB, XC); + LDR(INDEX_UNSIGNED, X2, X0, offsetof(JitBlock::ProfileData, ticStart)); + SUB(X1, X1, X2); // loads ticCounter and downcountCounter - LDP(INDEX_SIGNED, XC, XD, XA, offsetof(JitBlock::ProfileData, ticCounter)); - ADD(XC, XC, XB); - ADDI2R(XD, XD, js.downcountAmount); + LDP(INDEX_SIGNED, X2, X3, X0, offsetof(JitBlock::ProfileData, ticCounter)); + ADD(X2, X2, X1); + ADDI2R(X3, X3, js.downcountAmount, X1); // stores ticCounter and downcountCounter - STP(INDEX_SIGNED, XC, XD, XA, offsetof(JitBlock::ProfileData, ticCounter)); - - gpr.Unlock(WA, WB, WC, WD); + STP(INDEX_SIGNED, X2, X3, X0, offsetof(JitBlock::ProfileData, ticCounter)); } void JitArm64::Run() diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp index 82325b0f49..da49e0a3bf 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp @@ -67,8 +67,8 @@ void JitArm64::rfi(UGeckoInstruction inst) LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(spr[SPR_SRR0])); gpr.Unlock(WB, WC); - // WA is unlocked in this function WriteExceptionExit(WA); + gpr.Unlock(WA); } void JitArm64::bx(UGeckoInstruction inst) @@ -220,6 +220,8 @@ void JitArm64::bcctrx(UGeckoInstruction inst) AND(WA, WA, 30, 29); // Wipe the bottom 2 bits. WriteExit(WA, inst.LK_3, js.compilerPC + 4); + + gpr.Unlock(WA); } void JitArm64::bclrx(UGeckoInstruction inst) @@ -275,6 +277,8 @@ void JitArm64::bclrx(UGeckoInstruction inst) WriteBLRExit(WA); + gpr.Unlock(WA); + if (conditional) SwitchToNearCode();