mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-11 08:39:13 +01:00
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.
This commit is contained in:
parent
304e601ad3
commit
da79ddbde7
@ -161,6 +161,7 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
|||||||
ARM64Reg WA = gpr.GetReg();
|
ARM64Reg WA = gpr.GetReg();
|
||||||
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(npc));
|
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(npc));
|
||||||
WriteExceptionExit(WA);
|
WriteExceptionExit(WA);
|
||||||
|
gpr.Unlock(WA);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -174,6 +175,7 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
|||||||
FixupBranch c = B(CC_EQ);
|
FixupBranch c = B(CC_EQ);
|
||||||
WriteExceptionExit(WA);
|
WriteExceptionExit(WA);
|
||||||
SetJumpTarget(c);
|
SetJumpTarget(c);
|
||||||
|
gpr.Unlock(WA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,6 +213,7 @@ void JitArm64::HLEFunction(UGeckoInstruction inst)
|
|||||||
ARM64Reg WA = gpr.GetReg();
|
ARM64Reg WA = gpr.GetReg();
|
||||||
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(npc));
|
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(npc));
|
||||||
WriteExit(WA);
|
WriteExit(WA);
|
||||||
|
gpr.Unlock(WA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::DoNothing(UGeckoInstruction inst)
|
void JitArm64::DoNothing(UGeckoInstruction inst)
|
||||||
@ -228,21 +231,16 @@ void JitArm64::Cleanup()
|
|||||||
{
|
{
|
||||||
if (jo.optimizeGatherPipe && js.fifoBytesSinceCheck > 0)
|
if (jo.optimizeGatherPipe && js.fifoBytesSinceCheck > 0)
|
||||||
{
|
{
|
||||||
gpr.Lock(W0);
|
|
||||||
MOVP2R(X0, &GPFifo::FastCheckGatherPipe);
|
MOVP2R(X0, &GPFifo::FastCheckGatherPipe);
|
||||||
BLR(X0);
|
BLR(X0);
|
||||||
gpr.Unlock(W0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::DoDownCount()
|
void JitArm64::DoDownCount()
|
||||||
{
|
{
|
||||||
ARM64Reg WA = gpr.GetReg();
|
LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(downcount));
|
||||||
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(downcount));
|
SUBSI2R(W0, W0, js.downcountAmount, W1);
|
||||||
ARM64Reg WB = gpr.GetReg();
|
STR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(downcount));
|
||||||
SUBSI2R(WA, WA, js.downcountAmount, WB);
|
|
||||||
STR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(downcount));
|
|
||||||
gpr.Unlock(WA, WB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::ResetStack()
|
void JitArm64::ResetStack()
|
||||||
@ -292,9 +290,7 @@ void JitArm64::WriteExit(u32 destination, bool LK, u32 exit_address_after_return
|
|||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
DoDownCount();
|
DoDownCount();
|
||||||
|
EndTimeProfile(js.curBlock);
|
||||||
if (Profiler::g_ProfileBlocks)
|
|
||||||
EndTimeProfile(js.curBlock);
|
|
||||||
|
|
||||||
LK &= m_enable_blr_optimization;
|
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)
|
void JitArm64::WriteExit(Arm64Gen::ARM64Reg dest, bool LK, u32 exit_address_after_return)
|
||||||
{
|
{
|
||||||
Cleanup();
|
|
||||||
DoDownCount();
|
|
||||||
|
|
||||||
LK &= m_enable_blr_optimization;
|
|
||||||
|
|
||||||
if (dest != DISPATCHER_PC)
|
if (dest != DISPATCHER_PC)
|
||||||
MOV(DISPATCHER_PC, dest);
|
MOV(DISPATCHER_PC, dest);
|
||||||
gpr.Unlock(dest);
|
|
||||||
|
|
||||||
if (Profiler::g_ProfileBlocks)
|
Cleanup();
|
||||||
EndTimeProfile(js.curBlock);
|
DoDownCount();
|
||||||
|
EndTimeProfile(js.curBlock);
|
||||||
|
|
||||||
|
LK &= m_enable_blr_optimization;
|
||||||
|
|
||||||
if (!LK)
|
if (!LK)
|
||||||
{
|
{
|
||||||
@ -407,35 +400,28 @@ void JitArm64::WriteBLRExit(Arm64Gen::ARM64Reg dest)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dest != DISPATCHER_PC)
|
||||||
|
MOV(DISPATCHER_PC, dest);
|
||||||
|
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
EndTimeProfile(js.curBlock);
|
||||||
if (Profiler::g_ProfileBlocks)
|
|
||||||
EndTimeProfile(js.curBlock);
|
|
||||||
|
|
||||||
ARM64Reg code = gpr.GetReg();
|
|
||||||
ARM64Reg pc = gpr.GetReg();
|
|
||||||
|
|
||||||
// Check if {ARM_PC, PPC_PC} matches the current state.
|
// Check if {ARM_PC, PPC_PC} matches the current state.
|
||||||
LDP(INDEX_POST, EncodeRegTo64(code), EncodeRegTo64(pc), SP, 16);
|
LDP(INDEX_POST, X2, X1, SP, 16);
|
||||||
CMP(pc, dest);
|
CMP(W1, DISPATCHER_PC);
|
||||||
FixupBranch no_match = B(CC_NEQ);
|
FixupBranch no_match = B(CC_NEQ);
|
||||||
|
|
||||||
DoDownCount();
|
DoDownCount(); // overwrites X0 + X1
|
||||||
|
|
||||||
RET(EncodeRegTo64(code));
|
RET(X2);
|
||||||
|
|
||||||
SetJumpTarget(no_match);
|
SetJumpTarget(no_match);
|
||||||
|
|
||||||
DoDownCount();
|
DoDownCount();
|
||||||
|
|
||||||
if (dest != DISPATCHER_PC)
|
|
||||||
MOV(DISPATCHER_PC, dest);
|
|
||||||
|
|
||||||
ResetStack();
|
ResetStack();
|
||||||
|
|
||||||
B(dispatcher);
|
B(dispatcher);
|
||||||
|
|
||||||
gpr.Unlock(dest, pc, code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::WriteExceptionExit(u32 destination, bool only_external)
|
void JitArm64::WriteExceptionExit(u32 destination, bool only_external)
|
||||||
@ -458,39 +444,34 @@ void JitArm64::WriteExceptionExit(u32 destination, bool only_external)
|
|||||||
|
|
||||||
SetJumpTarget(no_exceptions);
|
SetJumpTarget(no_exceptions);
|
||||||
|
|
||||||
if (Profiler::g_ProfileBlocks)
|
EndTimeProfile(js.curBlock);
|
||||||
EndTimeProfile(js.curBlock);
|
|
||||||
|
|
||||||
B(dispatcher);
|
B(dispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external)
|
void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external)
|
||||||
{
|
{
|
||||||
|
if (dest != DISPATCHER_PC)
|
||||||
|
MOV(DISPATCHER_PC, dest);
|
||||||
|
|
||||||
Cleanup();
|
Cleanup();
|
||||||
DoDownCount();
|
DoDownCount();
|
||||||
|
|
||||||
ARM64Reg WA = gpr.GetReg();
|
LDR(INDEX_UNSIGNED, W30, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||||
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
FixupBranch no_exceptions = CBZ(W30);
|
||||||
FixupBranch no_exceptions = CBZ(WA);
|
|
||||||
gpr.Unlock(WA);
|
|
||||||
|
|
||||||
STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(pc));
|
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||||
STR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(npc));
|
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
|
||||||
if (only_external)
|
if (only_external)
|
||||||
MOVP2R(EncodeRegTo64(dest), &PowerPC::CheckExternalExceptions);
|
MOVP2R(EncodeRegTo64(DISPATCHER_PC), &PowerPC::CheckExternalExceptions);
|
||||||
else
|
else
|
||||||
MOVP2R(EncodeRegTo64(dest), &PowerPC::CheckExceptions);
|
MOVP2R(EncodeRegTo64(DISPATCHER_PC), &PowerPC::CheckExceptions);
|
||||||
BLR(EncodeRegTo64(dest));
|
BLR(EncodeRegTo64(DISPATCHER_PC));
|
||||||
LDR(INDEX_UNSIGNED, dest, PPC_REG, PPCSTATE_OFF(npc));
|
LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
|
||||||
|
|
||||||
SetJumpTarget(no_exceptions);
|
SetJumpTarget(no_exceptions);
|
||||||
|
|
||||||
if (dest != DISPATCHER_PC)
|
EndTimeProfile(js.curBlock);
|
||||||
MOV(DISPATCHER_PC, dest);
|
|
||||||
gpr.Unlock(dest);
|
|
||||||
|
|
||||||
if (Profiler::g_ProfileBlocks)
|
|
||||||
EndTimeProfile(js.curBlock);
|
|
||||||
|
|
||||||
B(dispatcher);
|
B(dispatcher);
|
||||||
}
|
}
|
||||||
@ -518,32 +499,24 @@ void JitArm64::BeginTimeProfile(JitBlock* b)
|
|||||||
|
|
||||||
void JitArm64::EndTimeProfile(JitBlock* b)
|
void JitArm64::EndTimeProfile(JitBlock* b)
|
||||||
{
|
{
|
||||||
ARM64Reg WA = gpr.GetReg();
|
if (!Profiler::g_ProfileBlocks)
|
||||||
ARM64Reg XA = EncodeRegTo64(WA);
|
return;
|
||||||
ARM64Reg WB = gpr.GetReg();
|
|
||||||
ARM64Reg XB = EncodeRegTo64(WB);
|
|
||||||
ARM64Reg WC = gpr.GetReg();
|
|
||||||
ARM64Reg XC = EncodeRegTo64(WC);
|
|
||||||
ARM64Reg WD = gpr.GetReg();
|
|
||||||
ARM64Reg XD = EncodeRegTo64(WD);
|
|
||||||
|
|
||||||
// Fetch the current counter register
|
// 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));
|
LDR(INDEX_UNSIGNED, X2, X0, offsetof(JitBlock::ProfileData, ticStart));
|
||||||
SUB(XB, XB, XC);
|
SUB(X1, X1, X2);
|
||||||
|
|
||||||
// loads ticCounter and downcountCounter
|
// loads ticCounter and downcountCounter
|
||||||
LDP(INDEX_SIGNED, XC, XD, XA, offsetof(JitBlock::ProfileData, ticCounter));
|
LDP(INDEX_SIGNED, X2, X3, X0, offsetof(JitBlock::ProfileData, ticCounter));
|
||||||
ADD(XC, XC, XB);
|
ADD(X2, X2, X1);
|
||||||
ADDI2R(XD, XD, js.downcountAmount);
|
ADDI2R(X3, X3, js.downcountAmount, X1);
|
||||||
|
|
||||||
// stores ticCounter and downcountCounter
|
// stores ticCounter and downcountCounter
|
||||||
STP(INDEX_SIGNED, XC, XD, XA, offsetof(JitBlock::ProfileData, ticCounter));
|
STP(INDEX_SIGNED, X2, X3, X0, offsetof(JitBlock::ProfileData, ticCounter));
|
||||||
|
|
||||||
gpr.Unlock(WA, WB, WC, WD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::Run()
|
void JitArm64::Run()
|
||||||
|
@ -67,8 +67,8 @@ void JitArm64::rfi(UGeckoInstruction inst)
|
|||||||
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(spr[SPR_SRR0]));
|
LDR(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(spr[SPR_SRR0]));
|
||||||
gpr.Unlock(WB, WC);
|
gpr.Unlock(WB, WC);
|
||||||
|
|
||||||
// WA is unlocked in this function
|
|
||||||
WriteExceptionExit(WA);
|
WriteExceptionExit(WA);
|
||||||
|
gpr.Unlock(WA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::bx(UGeckoInstruction inst)
|
void JitArm64::bx(UGeckoInstruction inst)
|
||||||
@ -220,6 +220,8 @@ void JitArm64::bcctrx(UGeckoInstruction inst)
|
|||||||
AND(WA, WA, 30, 29); // Wipe the bottom 2 bits.
|
AND(WA, WA, 30, 29); // Wipe the bottom 2 bits.
|
||||||
|
|
||||||
WriteExit(WA, inst.LK_3, js.compilerPC + 4);
|
WriteExit(WA, inst.LK_3, js.compilerPC + 4);
|
||||||
|
|
||||||
|
gpr.Unlock(WA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::bclrx(UGeckoInstruction inst)
|
void JitArm64::bclrx(UGeckoInstruction inst)
|
||||||
@ -275,6 +277,8 @@ void JitArm64::bclrx(UGeckoInstruction inst)
|
|||||||
|
|
||||||
WriteBLRExit(WA);
|
WriteBLRExit(WA);
|
||||||
|
|
||||||
|
gpr.Unlock(WA);
|
||||||
|
|
||||||
if (conditional)
|
if (conditional)
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user