mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-21 03:54:57 +00:00
JitArm64: Add the ability to emit an unconditional exception exit
In cases where we already know that there is an exception, either because we just checked for it or because we were the ones that generated the exception to begin with, we can skip the branch inside WriteExceptionExit.
This commit is contained in:
parent
ffdc8538a1
commit
1a64364ae3
4 changed files with 21 additions and 36 deletions
|
@ -207,7 +207,7 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
|||
gpr.Flush(FlushMode::MaintainState);
|
||||
fpr.Flush(FlushMode::MaintainState);
|
||||
|
||||
WriteExceptionExit(js.compilerPC);
|
||||
WriteExceptionExit(js.compilerPC, false, true);
|
||||
|
||||
SwitchToNearCode();
|
||||
SetJumpTarget(noException);
|
||||
|
@ -454,43 +454,25 @@ void JitArm64::WriteBLRExit(Arm64Gen::ARM64Reg dest)
|
|||
B(dispatcher);
|
||||
}
|
||||
|
||||
void JitArm64::WriteExceptionExit(u32 destination, bool only_external)
|
||||
void JitArm64::WriteExceptionExit(u32 destination, bool only_external, bool always_exception)
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
LDR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
MOVI2R(DISPATCHER_PC, destination);
|
||||
FixupBranch no_exceptions = CBZ(ARM64Reg::W30);
|
||||
|
||||
static_assert(PPCSTATE_OFF(pc) <= 252);
|
||||
static_assert(PPCSTATE_OFF(pc) + 4 == PPCSTATE_OFF(npc));
|
||||
STP(IndexType::Signed, DISPATCHER_PC, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||
|
||||
if (only_external)
|
||||
MOVP2R(ARM64Reg::X8, &PowerPC::CheckExternalExceptions);
|
||||
else
|
||||
MOVP2R(ARM64Reg::X8, &PowerPC::CheckExceptions);
|
||||
BLR(ARM64Reg::X8);
|
||||
|
||||
LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
|
||||
|
||||
SetJumpTarget(no_exceptions);
|
||||
|
||||
EndTimeProfile(js.curBlock);
|
||||
DoDownCount();
|
||||
|
||||
B(dispatcher);
|
||||
WriteExceptionExit(DISPATCHER_PC, only_external, always_exception);
|
||||
}
|
||||
|
||||
void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external)
|
||||
void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external, bool always_exception)
|
||||
{
|
||||
if (dest != DISPATCHER_PC)
|
||||
MOV(DISPATCHER_PC, dest);
|
||||
|
||||
Cleanup();
|
||||
|
||||
LDR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
FixupBranch no_exceptions = CBZ(ARM64Reg::W30);
|
||||
FixupBranch no_exceptions;
|
||||
if (!always_exception)
|
||||
{
|
||||
LDR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
no_exceptions = CBZ(ARM64Reg::W30);
|
||||
}
|
||||
|
||||
static_assert(PPCSTATE_OFF(pc) <= 252);
|
||||
static_assert(PPCSTATE_OFF(pc) + 4 == PPCSTATE_OFF(npc));
|
||||
|
@ -504,7 +486,8 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external)
|
|||
|
||||
LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
|
||||
|
||||
SetJumpTarget(no_exceptions);
|
||||
if (!always_exception)
|
||||
SetJumpTarget(no_exceptions);
|
||||
|
||||
EndTimeProfile(js.curBlock);
|
||||
DoDownCount();
|
||||
|
@ -757,7 +740,7 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||
|
||||
gpr.Flush(FlushMode::MaintainState);
|
||||
fpr.Flush(FlushMode::MaintainState);
|
||||
WriteExceptionExit(js.compilerPC, true);
|
||||
WriteExceptionExit(js.compilerPC, true, true);
|
||||
SwitchToNearCode();
|
||||
SetJumpTarget(exit);
|
||||
gpr.Unlock(ARM64Reg::W30);
|
||||
|
@ -789,7 +772,7 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||
|
||||
gpr.Flush(FlushMode::MaintainState);
|
||||
fpr.Flush(FlushMode::MaintainState);
|
||||
WriteExceptionExit(js.compilerPC, true);
|
||||
WriteExceptionExit(js.compilerPC, true, true);
|
||||
SwitchToNearCode();
|
||||
SetJumpTarget(NoExtException);
|
||||
SetJumpTarget(exit);
|
||||
|
@ -820,7 +803,7 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||
|
||||
gpr.Unlock(WA);
|
||||
|
||||
WriteExceptionExit(js.compilerPC);
|
||||
WriteExceptionExit(js.compilerPC, false, true);
|
||||
|
||||
SwitchToNearCode();
|
||||
|
||||
|
|
|
@ -250,8 +250,10 @@ protected:
|
|||
// Exits
|
||||
void WriteExit(u32 destination, bool LK = false, u32 exit_address_after_return = 0);
|
||||
void WriteExit(Arm64Gen::ARM64Reg dest, bool LK = false, u32 exit_address_after_return = 0);
|
||||
void WriteExceptionExit(u32 destination, bool only_external = false);
|
||||
void WriteExceptionExit(Arm64Gen::ARM64Reg dest, bool only_external = false);
|
||||
void WriteExceptionExit(u32 destination, bool only_external = false,
|
||||
bool always_exception = false);
|
||||
void WriteExceptionExit(Arm64Gen::ARM64Reg dest, bool only_external = false,
|
||||
bool always_exception = false);
|
||||
void FakeLKExit(u32 exit_address_after_return);
|
||||
void WriteBLRExit(Arm64Gen::ARM64Reg dest);
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ void JitArm64::sc(UGeckoInstruction inst)
|
|||
|
||||
gpr.Unlock(WA);
|
||||
|
||||
WriteExceptionExit(js.compilerPC + 4);
|
||||
WriteExceptionExit(js.compilerPC + 4, false, true);
|
||||
}
|
||||
|
||||
void JitArm64::rfi(UGeckoInstruction inst)
|
||||
|
|
|
@ -221,7 +221,7 @@ void JitArm64::twx(UGeckoInstruction inst)
|
|||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
gpr.Unlock(WA);
|
||||
|
||||
WriteExceptionExit(js.compilerPC);
|
||||
WriteExceptionExit(js.compilerPC, false, true);
|
||||
|
||||
SwitchToNearCode();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue