JitArm64: Make WriteConditionalExceptionExit more flexible

You can now specify an already allocated register for it to use as a
temporary register, and it also supports being called while in farcode.
This commit is contained in:
JosJuice 2021-06-28 18:23:57 +02:00
parent e5a4a86672
commit 8c905e152a
2 changed files with 22 additions and 9 deletions

View File

@ -501,21 +501,33 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external, bool always
void JitArm64::WriteConditionalExceptionExit(int exception) void JitArm64::WriteConditionalExceptionExit(int exception)
{ {
ARM64Reg WA = gpr.GetReg(); ARM64Reg WA = gpr.GetReg();
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions)); WriteConditionalExceptionExit(exception, WA);
FixupBranch noException = TBZ(WA, IntLog2(exception)); gpr.Unlock(WA);
}
FixupBranch handleException = B(); void JitArm64::WriteConditionalExceptionExit(int exception, ARM64Reg temp_reg)
SwitchToFarCode(); {
SetJumpTarget(handleException); LDR(IndexType::Unsigned, temp_reg, PPC_REG, PPCSTATE_OFF(Exceptions));
FixupBranch no_exception = TBZ(temp_reg, IntLog2(exception));
gpr.Flush(FlushMode::MaintainState, WA); const bool switch_to_far_code = !IsInFarCode();
if (switch_to_far_code)
{
FixupBranch handle_exception = B();
SwitchToFarCode();
SetJumpTarget(handle_exception);
}
gpr.Flush(FlushMode::MaintainState, temp_reg);
fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG); fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG);
WriteExceptionExit(js.compilerPC, false, true); WriteExceptionExit(js.compilerPC, false, true);
SwitchToNearCode(); if (switch_to_far_code)
SetJumpTarget(noException); SwitchToNearCode();
gpr.Unlock(WA);
SetJumpTarget(no_exception);
} }
bool JitArm64::HandleFunctionHooking(u32 address) bool JitArm64::HandleFunctionHooking(u32 address)

View File

@ -266,6 +266,7 @@ protected:
void WriteExceptionExit(Arm64Gen::ARM64Reg dest, bool only_external = false, void WriteExceptionExit(Arm64Gen::ARM64Reg dest, bool only_external = false,
bool always_exception = false); bool always_exception = false);
void WriteConditionalExceptionExit(int exception); void WriteConditionalExceptionExit(int exception);
void WriteConditionalExceptionExit(int exception, Arm64Gen::ARM64Reg temp_reg);
void FakeLKExit(u32 exit_address_after_return); void FakeLKExit(u32 exit_address_after_return);
void WriteBLRExit(Arm64Gen::ARM64Reg dest); void WriteBLRExit(Arm64Gen::ARM64Reg dest);