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:
commit
9df6f65834
|
@ -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();
|
||||||
|
|
||||||
|
FixupBranch no_exceptions;
|
||||||
|
if (!always_exception)
|
||||||
|
{
|
||||||
LDR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(Exceptions));
|
LDR(IndexType::Unsigned, ARM64Reg::W30, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||||
FixupBranch no_exceptions = CBZ(ARM64Reg::W30);
|
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,6 +486,7 @@ 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));
|
||||||
|
|
||||||
|
if (!always_exception)
|
||||||
SetJumpTarget(no_exceptions);
|
SetJumpTarget(no_exceptions);
|
||||||
|
|
||||||
EndTimeProfile(js.curBlock);
|
EndTimeProfile(js.curBlock);
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue