Merge pull request #9867 from JosJuice/jitarm64-unconditional-exception-exit

JitArm64: Add the ability to emit an unconditional exception exit
This commit is contained in:
Markus Wick 2021-07-08 13:08:05 +02:00 committed by GitHub
commit 9df6f65834
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 36 deletions

View file

@ -207,7 +207,7 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
gpr.Flush(FlushMode::MaintainState); gpr.Flush(FlushMode::MaintainState);
fpr.Flush(FlushMode::MaintainState); fpr.Flush(FlushMode::MaintainState);
WriteExceptionExit(js.compilerPC); WriteExceptionExit(js.compilerPC, false, true);
SwitchToNearCode(); SwitchToNearCode();
SetJumpTarget(noException); SetJumpTarget(noException);
@ -454,43 +454,25 @@ void JitArm64::WriteBLRExit(Arm64Gen::ARM64Reg dest)
B(dispatcher); 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); MOVI2R(DISPATCHER_PC, destination);
FixupBranch no_exceptions = CBZ(ARM64Reg::W30); WriteExceptionExit(DISPATCHER_PC, only_external, always_exception);
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);
} }
void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external) void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external, bool always_exception)
{ {
if (dest != DISPATCHER_PC) if (dest != DISPATCHER_PC)
MOV(DISPATCHER_PC, dest); MOV(DISPATCHER_PC, dest);
Cleanup(); Cleanup();
LDR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(Exceptions)); FixupBranch no_exceptions;
FixupBranch no_exceptions = CBZ(ARM64Reg::W30); 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) <= 252);
static_assert(PPCSTATE_OFF(pc) + 4 == PPCSTATE_OFF(npc)); 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)); LDR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
SetJumpTarget(no_exceptions); if (!always_exception)
SetJumpTarget(no_exceptions);
EndTimeProfile(js.curBlock); EndTimeProfile(js.curBlock);
DoDownCount(); DoDownCount();
@ -757,7 +740,7 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
gpr.Flush(FlushMode::MaintainState); gpr.Flush(FlushMode::MaintainState);
fpr.Flush(FlushMode::MaintainState); fpr.Flush(FlushMode::MaintainState);
WriteExceptionExit(js.compilerPC, true); WriteExceptionExit(js.compilerPC, true, true);
SwitchToNearCode(); SwitchToNearCode();
SetJumpTarget(no_ext_exception); SetJumpTarget(no_ext_exception);
SetJumpTarget(exit); SetJumpTarget(exit);
@ -790,7 +773,7 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
gpr.Flush(FlushMode::MaintainState); gpr.Flush(FlushMode::MaintainState);
fpr.Flush(FlushMode::MaintainState); fpr.Flush(FlushMode::MaintainState);
WriteExceptionExit(js.compilerPC, true); WriteExceptionExit(js.compilerPC, true, true);
SwitchToNearCode(); SwitchToNearCode();
SetJumpTarget(no_ext_exception); SetJumpTarget(no_ext_exception);
SetJumpTarget(exit); SetJumpTarget(exit);
@ -821,7 +804,7 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
gpr.Unlock(WA); gpr.Unlock(WA);
WriteExceptionExit(js.compilerPC); WriteExceptionExit(js.compilerPC, false, true);
SwitchToNearCode(); SwitchToNearCode();

View file

@ -250,8 +250,10 @@ protected:
// Exits // Exits
void WriteExit(u32 destination, bool LK = false, u32 exit_address_after_return = 0); 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 WriteExit(Arm64Gen::ARM64Reg dest, bool LK = false, u32 exit_address_after_return = 0);
void WriteExceptionExit(u32 destination, bool only_external = false); void WriteExceptionExit(u32 destination, bool only_external = false,
void WriteExceptionExit(Arm64Gen::ARM64Reg dest, 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 FakeLKExit(u32 exit_address_after_return);
void WriteBLRExit(Arm64Gen::ARM64Reg dest); void WriteBLRExit(Arm64Gen::ARM64Reg dest);

View file

@ -29,7 +29,7 @@ void JitArm64::sc(UGeckoInstruction inst)
gpr.Unlock(WA); gpr.Unlock(WA);
WriteExceptionExit(js.compilerPC + 4); WriteExceptionExit(js.compilerPC + 4, false, true);
} }
void JitArm64::rfi(UGeckoInstruction inst) void JitArm64::rfi(UGeckoInstruction inst)

View file

@ -221,7 +221,7 @@ void JitArm64::twx(UGeckoInstruction inst)
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
gpr.Unlock(WA); gpr.Unlock(WA);
WriteExceptionExit(js.compilerPC); WriteExceptionExit(js.compilerPC, false, true);
SwitchToNearCode(); SwitchToNearCode();