mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-31 09:33:06 +00:00
Jit_LoadStore: stX
This commit is contained in:
parent
4a2efc8f5e
commit
90cef22d57
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user