JitArm64: Use ScopedARM64Reg
This commit is contained in:
parent
c0a0746d65
commit
cb29a29866
|
@ -222,12 +222,11 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
|||
if (js.op->canEndBlock)
|
||||
{
|
||||
// also flush the program counter
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
auto WA = gpr.GetScopedReg();
|
||||
MOVI2R(WA, js.compilerPC);
|
||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(pc));
|
||||
ADD(WA, WA, 4);
|
||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(npc));
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
|
||||
Interpreter::Instruction instr = Interpreter::GetInterpreterOp(inst);
|
||||
|
@ -243,24 +242,23 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
|||
{
|
||||
if (js.isLastInstruction)
|
||||
{
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
auto WA = gpr.GetScopedReg();
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(npc));
|
||||
WriteExceptionExit(WA);
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
else
|
||||
{
|
||||
// only exit if ppcstate.npc was changed
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
auto WA = gpr.GetScopedReg();
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(npc));
|
||||
ARM64Reg WB = gpr.GetReg();
|
||||
MOVI2R(WB, js.compilerPC + 4);
|
||||
CMP(WB, WA);
|
||||
gpr.Unlock(WB);
|
||||
{
|
||||
auto WB = gpr.GetScopedReg();
|
||||
MOVI2R(WB, js.compilerPC + 4);
|
||||
CMP(WB, WA);
|
||||
}
|
||||
FixupBranch c = B(CC_EQ);
|
||||
WriteExceptionExit(WA);
|
||||
SetJumpTarget(c);
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
}
|
||||
else if (ShouldHandleFPExceptionForInstruction(js.op))
|
||||
|
@ -359,11 +357,12 @@ void JitArm64::IntializeSpeculativeConstants()
|
|||
SwitchToNearCode();
|
||||
}
|
||||
|
||||
ARM64Reg tmp = gpr.GetReg();
|
||||
ARM64Reg value = gpr.R(i);
|
||||
MOVI2R(tmp, compile_time_value);
|
||||
CMP(value, tmp);
|
||||
gpr.Unlock(tmp);
|
||||
{
|
||||
auto tmp = gpr.GetScopedReg();
|
||||
ARM64Reg value = gpr.R(i);
|
||||
MOVI2R(tmp, compile_time_value);
|
||||
CMP(value, tmp);
|
||||
}
|
||||
|
||||
FixupBranch no_fail = B(CCFlags::CC_EQ);
|
||||
B(fail);
|
||||
|
@ -402,16 +401,15 @@ void JitArm64::MSRUpdated(u32 msr)
|
|||
}
|
||||
else
|
||||
{
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
auto WA = gpr.GetScopedReg();
|
||||
MOVI2R(WA, feature_flags);
|
||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(feature_flags));
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
}
|
||||
|
||||
void JitArm64::MSRUpdated(ARM64Reg msr)
|
||||
{
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
auto WA = gpr.GetScopedReg();
|
||||
ARM64Reg XA = EncodeRegTo64(WA);
|
||||
|
||||
// Update mem_ptr
|
||||
|
@ -432,8 +430,6 @@ void JitArm64::MSRUpdated(ARM64Reg msr)
|
|||
if (other_feature_flags != 0)
|
||||
ORR(WA, WA, LogicalImm(other_feature_flags, GPRSize::B32));
|
||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(feature_flags));
|
||||
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
|
||||
void JitArm64::WriteExit(u32 destination, bool LK, u32 exit_address_after_return,
|
||||
|
@ -631,35 +627,37 @@ void JitArm64::FakeLKExit(u32 exit_address_after_return, ARM64Reg exit_address_a
|
|||
// function has been called!
|
||||
gpr.Lock(ARM64Reg::W30);
|
||||
}
|
||||
// Push {ARM_PC (64-bit); PPC_PC (32-bit); feature_flags (32-bit)} on the stack
|
||||
ARM64Reg after_reg = ARM64Reg::INVALID_REG;
|
||||
ARM64Reg reg_to_push;
|
||||
const u64 feature_flags = m_ppc_state.feature_flags;
|
||||
if (exit_address_after_return_reg == ARM64Reg::INVALID_REG)
|
||||
|
||||
const u8* host_address_after_return;
|
||||
{
|
||||
after_reg = gpr.GetReg();
|
||||
reg_to_push = EncodeRegTo64(after_reg);
|
||||
MOVI2R(reg_to_push, feature_flags << 32 | exit_address_after_return);
|
||||
// Push {ARM_PC (64-bit); PPC_PC (32-bit); feature_flags (32-bit)} on the stack
|
||||
Arm64RegCache::ScopedARM64Reg after_reg;
|
||||
ARM64Reg reg_to_push;
|
||||
const u64 feature_flags = m_ppc_state.feature_flags;
|
||||
if (exit_address_after_return_reg == ARM64Reg::INVALID_REG)
|
||||
{
|
||||
after_reg = gpr.GetScopedReg();
|
||||
reg_to_push = EncodeRegTo64(after_reg);
|
||||
MOVI2R(reg_to_push, feature_flags << 32 | exit_address_after_return);
|
||||
}
|
||||
else if (feature_flags == 0)
|
||||
{
|
||||
reg_to_push = EncodeRegTo64(exit_address_after_return_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
after_reg = gpr.GetScopedReg();
|
||||
reg_to_push = EncodeRegTo64(after_reg);
|
||||
ORRI2R(reg_to_push, EncodeRegTo64(exit_address_after_return_reg), feature_flags << 32,
|
||||
reg_to_push);
|
||||
}
|
||||
|
||||
auto code_reg = gpr.GetScopedReg();
|
||||
constexpr s32 adr_offset = sizeof(u32) * 3;
|
||||
host_address_after_return = GetCodePtr() + adr_offset;
|
||||
ADR(EncodeRegTo64(code_reg), adr_offset);
|
||||
STP(IndexType::Pre, EncodeRegTo64(code_reg), reg_to_push, ARM64Reg::SP, -16);
|
||||
}
|
||||
else if (feature_flags == 0)
|
||||
{
|
||||
reg_to_push = EncodeRegTo64(exit_address_after_return_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
after_reg = gpr.GetReg();
|
||||
reg_to_push = EncodeRegTo64(after_reg);
|
||||
ORRI2R(reg_to_push, EncodeRegTo64(exit_address_after_return_reg), feature_flags << 32,
|
||||
reg_to_push);
|
||||
}
|
||||
ARM64Reg code_reg = gpr.GetReg();
|
||||
constexpr s32 adr_offset = sizeof(u32) * 3;
|
||||
const u8* host_address_after_return = GetCodePtr() + adr_offset;
|
||||
ADR(EncodeRegTo64(code_reg), adr_offset);
|
||||
STP(IndexType::Pre, EncodeRegTo64(code_reg), reg_to_push, ARM64Reg::SP, -16);
|
||||
gpr.Unlock(code_reg);
|
||||
if (after_reg != ARM64Reg::INVALID_REG)
|
||||
gpr.Unlock(after_reg);
|
||||
|
||||
FixupBranch skip_exit = BL();
|
||||
DEBUG_ASSERT(GetCodePtr() == host_address_after_return || HasWriteFailed());
|
||||
|
@ -792,10 +790,9 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest, bool only_external, bool always
|
|||
|
||||
void JitArm64::WriteConditionalExceptionExit(int exception, u64 increment_sp_on_exit)
|
||||
{
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
auto WA = gpr.GetScopedReg();
|
||||
WriteConditionalExceptionExit(exception, WA, Arm64Gen::ARM64Reg::INVALID_REG,
|
||||
increment_sp_on_exit);
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
|
||||
void JitArm64::WriteConditionalExceptionExit(int exception, ARM64Reg temp_gpr, ARM64Reg temp_fpr,
|
||||
|
@ -1183,7 +1180,7 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||
// asynchronous.
|
||||
if (jo.optimizeGatherPipe && gatherPipeIntCheck)
|
||||
{
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
auto WA = gpr.GetScopedReg();
|
||||
ARM64Reg XA = EncodeRegTo64(WA);
|
||||
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
|
@ -1209,8 +1206,6 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||
SwitchToNearCode();
|
||||
SetJumpTarget(no_ext_exception);
|
||||
SetJumpTarget(exit);
|
||||
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1224,12 +1219,11 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||
// The only thing that currently sets op.skip is the BLR following optimization.
|
||||
// If any non-branch instruction starts setting that too, this will need to be changed.
|
||||
ASSERT(op.inst.hex == 0x4e800020);
|
||||
const ARM64Reg bw_reg_a = gpr.GetReg(), bw_reg_b = gpr.GetReg();
|
||||
const auto bw_reg_a = gpr.GetScopedReg(), bw_reg_b = gpr.GetScopedReg();
|
||||
const BitSet32 gpr_caller_save =
|
||||
gpr.GetCallerSavedUsed() & ~BitSet32{DecodeReg(bw_reg_a), DecodeReg(bw_reg_b)};
|
||||
WriteBranchWatch<true>(op.address, op.branchTo, op.inst, bw_reg_a, bw_reg_b,
|
||||
gpr_caller_save, fpr.GetCallerSavedUsed());
|
||||
gpr.Unlock(bw_reg_a, bw_reg_b);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1267,23 +1261,24 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||
|
||||
if ((opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound)
|
||||
{
|
||||
FixupBranch b1;
|
||||
// This instruction uses FPU - needs to add FP exception bailout
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(msr));
|
||||
FixupBranch b1 = TBNZ(WA, 13); // Test FP enabled bit
|
||||
{
|
||||
auto WA = gpr.GetScopedReg();
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(msr));
|
||||
b1 = TBNZ(WA, 13); // Test FP enabled bit
|
||||
|
||||
FixupBranch far_addr = B();
|
||||
SwitchToFarCode();
|
||||
SetJumpTarget(far_addr);
|
||||
FixupBranch far_addr = B();
|
||||
SwitchToFarCode();
|
||||
SetJumpTarget(far_addr);
|
||||
|
||||
gpr.Flush(FlushMode::MaintainState, WA);
|
||||
fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG);
|
||||
gpr.Flush(FlushMode::MaintainState, WA);
|
||||
fpr.Flush(FlushMode::MaintainState, ARM64Reg::INVALID_REG);
|
||||
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
ORR(WA, WA, LogicalImm(EXCEPTION_FPU_UNAVAILABLE, GPRSize::B32));
|
||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
|
||||
gpr.Unlock(WA);
|
||||
LDR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
ORR(WA, WA, LogicalImm(EXCEPTION_FPU_UNAVAILABLE, GPRSize::B32));
|
||||
STR(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(Exceptions));
|
||||
}
|
||||
|
||||
WriteExceptionExit(js.compilerPC, false, true);
|
||||
|
||||
|
|
Loading…
Reference in New Issue