Jit_LoadStore: stX

This commit is contained in:
MerryMage 2018-10-15 21:01:36 +01:00
parent 4a2efc8f5e
commit 90cef22d57

View File

@ -403,10 +403,14 @@ void Jit64::stX(UGeckoInstruction inst)
} }
// If we already know the address of the write // If we already know the address of the write
if (!a || gpr.R(a).IsImm()) if (!a || gpr.IsImm(a))
{ {
u32 addr = (a ? gpr.R(a).Imm32() : 0) + offset; const u32 addr = (a ? gpr.Imm32(a) : 0) + offset;
bool exception = WriteToConstAddress(accessSize, gpr.R(s), addr, CallerSavedRegistersInUse()); const bool exception = [&] {
RCOpArg Rs = gpr.Use(s, RCMode::Read);
RegCache::Realize(Rs);
return WriteToConstAddress(accessSize, Rs, addr, CallerSavedRegistersInUse());
}();
if (update) if (update)
{ {
if (!jo.memcheck || !exception) if (!jo.memcheck || !exception)
@ -415,42 +419,35 @@ void Jit64::stX(UGeckoInstruction inst)
} }
else else
{ {
gpr.KillImmediate(a, true, true); RCOpArg Ra = gpr.UseNoImm(a, RCMode::ReadWrite);
RegCache::Realize(Ra);
MemoryExceptionCheck(); MemoryExceptionCheck();
ADD(32, gpr.R(a), Imm32((u32)offset)); ADD(32, Ra, Imm32((u32)offset));
} }
} }
} }
else else
{ {
gpr.Lock(a, s); RCX64Reg Ra = gpr.Bind(a, update ? RCMode::ReadWrite : RCMode::Read);
gpr.BindToRegister(a, true, update); RCOpArg reg_value;
if (gpr.R(s).IsImm()) if (!gpr.IsImm(s) && WriteClobbersRegValue(accessSize, /* swap */ true))
{ {
SafeWriteRegToReg(gpr.R(s), gpr.RX(a), accessSize, offset, CallerSavedRegistersInUse(), RCOpArg Rs = gpr.Use(s, RCMode::Read);
RegCache::Realize(Rs);
reg_value = RCOpArg::R(RSCRATCH2);
MOV(32, reg_value, Rs);
}
else
{
reg_value = gpr.BindOrImm(s, RCMode::Read);
}
RegCache::Realize(Ra, reg_value);
SafeWriteRegToReg(reg_value, Ra, accessSize, offset, CallerSavedRegistersInUse(),
SAFE_LOADSTORE_CLOBBER_RSCRATCH_INSTEAD_OF_ADDR); SAFE_LOADSTORE_CLOBBER_RSCRATCH_INSTEAD_OF_ADDR);
}
else
{
X64Reg reg_value;
if (WriteClobbersRegValue(accessSize, /* swap */ true))
{
MOV(32, R(RSCRATCH2), gpr.R(s));
reg_value = RSCRATCH2;
}
else
{
gpr.BindToRegister(s, true, false);
reg_value = gpr.RX(s);
}
SafeWriteRegToReg(reg_value, gpr.RX(a), accessSize, offset, CallerSavedRegistersInUse(),
SAFE_LOADSTORE_CLOBBER_RSCRATCH_INSTEAD_OF_ADDR);
}
if (update) if (update)
ADD(32, gpr.R(a), Imm32((u32)offset)); ADD(32, Ra, Imm32((u32)offset));
} }
gpr.UnlockAll();
} }
void Jit64::stXx(UGeckoInstruction inst) void Jit64::stXx(UGeckoInstruction inst)