[AArch64] Fix loads with update.

Update register wasn't being loaded in to the cache prior pushing the address in to it.
Adds float push and pop routines around the calls that need it as well.
This commit is contained in:
Ryan Houdek 2015-01-07 14:27:46 -06:00
parent 52a532370a
commit 74de345b51
2 changed files with 12 additions and 9 deletions

View File

@ -25,7 +25,7 @@ static_assert((PPCSTATE_OFF(ps[0][0]) % 8) == 0, "LDR(64bit VFP) requires FPRs t
class JitArm64 : public JitBase, public Arm64Gen::ARM64CodeBlock class JitArm64 : public JitBase, public Arm64Gen::ARM64CodeBlock
{ {
public: public:
JitArm64() : code_buffer(32000) {} JitArm64() : code_buffer(32000), m_float_emit(this) {}
~JitArm64() {} ~JitArm64() {}
void Init(); void Init();
@ -112,6 +112,8 @@ private:
PPCAnalyst::CodeBuffer code_buffer; PPCAnalyst::CodeBuffer code_buffer;
ARM64FloatEmitter m_float_emit;
// The key is the backpatch flags // The key is the backpatch flags
std::map<u32, BackPatchInfo> m_backpatch_info; std::map<u32, BackPatchInfo> m_backpatch_info;

View File

@ -41,6 +41,7 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o
off_reg = gpr.R(offsetReg); off_reg = gpr.R(offsetReg);
BitSet32 regs_in_use = gpr.GetCallerSavedUsed(); BitSet32 regs_in_use = gpr.GetCallerSavedUsed();
BitSet32 fprs_in_use = fpr.GetCallerSavedUsed();
BitSet32 ignore_mask(0); BitSet32 ignore_mask(0);
regs_in_use[W0] = 0; regs_in_use[W0] = 0;
regs_in_use[W30] = 0; regs_in_use[W30] = 0;
@ -114,25 +115,24 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o
if (is_immediate) if (is_immediate)
MOVI2R(XA, imm_addr); MOVI2R(XA, imm_addr);
if (update)
MOV(gpr.R(addr), addr_reg);
if (is_immediate && Memory::IsRAMAddress(imm_addr)) if (is_immediate && Memory::IsRAMAddress(imm_addr))
{ {
EmitBackpatchRoutine(this, flags, true, false, dest_reg, XA); EmitBackpatchRoutine(this, flags, true, false, dest_reg, XA);
if (update)
MOVI2R(up_reg, imm_addr);
} }
else else
{ {
if (update)
MOV(up_reg, addr_reg);
// Has a chance of being backpatched which will destroy our state // Has a chance of being backpatched which will destroy our state
// push and pop everything in this instance // push and pop everything in this instance
ABI_PushRegisters(regs_in_use); ABI_PushRegisters(regs_in_use);
m_float_emit.ABI_PushRegisters(fprs_in_use);
EmitBackpatchRoutine(this, flags, EmitBackpatchRoutine(this, flags,
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
dest_reg, XA); dest_reg, XA);
m_float_emit.ABI_PopRegisters(fprs_in_use);
ABI_PopRegisters(regs_in_use, ignore_mask); ABI_PopRegisters(regs_in_use, ignore_mask);
} }
@ -155,6 +155,7 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s
reg_dest = gpr.R(dest); reg_dest = gpr.R(dest);
BitSet32 regs_in_use = gpr.GetCallerSavedUsed(); BitSet32 regs_in_use = gpr.GetCallerSavedUsed();
BitSet32 fprs_in_use = fpr.GetCallerSavedUsed();
regs_in_use[W0] = 0; regs_in_use[W0] = 0;
regs_in_use[W1] = 0; regs_in_use[W1] = 0;
regs_in_use[W30] = 0; regs_in_use[W30] = 0;
@ -237,10 +238,12 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s
// Has a chance of being backpatched which will destroy our state // Has a chance of being backpatched which will destroy our state
// push and pop everything in this instance // push and pop everything in this instance
ABI_PushRegisters(regs_in_use); ABI_PushRegisters(regs_in_use);
m_float_emit.ABI_PushRegisters(fprs_in_use);
EmitBackpatchRoutine(this, flags, EmitBackpatchRoutine(this, flags,
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
RS, XA); RS, XA);
m_float_emit.ABI_PopRegisters(fprs_in_use);
ABI_PopRegisters(regs_in_use); ABI_PopRegisters(regs_in_use);
} }
@ -321,8 +324,6 @@ void JitArm64::lXX(UGeckoInstruction inst)
break; break;
} }
FALLBACK_IF(update);
SafeLoadToReg(d, update ? a : (a ? a : -1), offsetReg, flags, offset, update); SafeLoadToReg(d, update ? a : (a ? a : -1), offsetReg, flags, offset, update);
// LWZ idle skipping // LWZ idle skipping