summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorFiora <fioraaeterna@gmail.com>2014-09-06 12:54:24 -0700
committerFiora <fioraaeterna@gmail.com>2014-09-13 13:53:19 -0700
commit32a67ef2649dba100a84f7db971f12691fee80ad (patch)
tree3c6c399207ef8de83728c3ee018a76ff6070cb4d /Source/Core
parentb3c1cec1976b912c3e18c6a53784edb3fd4f3ea1 (diff)
JIT: fix memcheck on float load/store, plus some corner cases
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp30
1 files changed, 24 insertions, 6 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp
index 8090c2499e..4e35c13caa 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStoreFloating.cpp
@@ -27,13 +27,18 @@ void Jit64::lfXXX(UGeckoInstruction inst)
int a = inst.RA;
int b = inst.RB;
- FALLBACK_IF(!indexed && !a);
+ FALLBACK_IF((!indexed && !a) || (update && a == d));
if (update)
gpr.BindToRegister(a, true, true);
s32 offset = 0;
OpArg addr = gpr.R(a);
+ if (update && js.memcheck)
+ {
+ addr = R(RSCRATCH2);
+ MOV(32, addr, gpr.R(a));
+ }
if (indexed)
{
if (update)
@@ -58,10 +63,13 @@ void Jit64::lfXXX(UGeckoInstruction inst)
if (update)
ADD(32, addr, Imm32((s32)(s16)inst.SIMM_16));
else
- offset = (s32)(s16)inst.SIMM_16;
+ offset = (s16)inst.SIMM_16;
}
- SafeLoadToReg(RSCRATCH, addr, single ? 32 : 64, offset, CallerSavedRegistersInUse(), false);
+ u32 registersInUse = CallerSavedRegistersInUse();
+ if (update && js.memcheck)
+ registersInUse |= (1 << RSCRATCH2);
+ SafeLoadToReg(RSCRATCH, addr, single ? 32 : 64, offset, registersInUse, false);
fpr.Lock(d);
fpr.BindToRegister(d, js.memcheck || !single);
@@ -75,6 +83,8 @@ void Jit64::lfXXX(UGeckoInstruction inst)
MOVQ_xmm(XMM0, R(RSCRATCH));
MOVSD(fpr.RX(d), R(XMM0));
}
+ if (update && js.memcheck)
+ MOV(32, gpr.R(a), addr);
MEMCHECK_END
fpr.UnlockAll();
gpr.UnlockAll();
@@ -93,9 +103,10 @@ void Jit64::stfXXX(UGeckoInstruction inst)
int a = inst.RA;
int b = inst.RB;
- FALLBACK_IF(!indexed && !a);
+ FALLBACK_IF((!indexed && !a) || (update && (a == s || a == b)));
s32 offset = 0;
+ s32 imm = (s16)inst.SIMM_16;
if (indexed)
{
if (update)
@@ -121,11 +132,11 @@ void Jit64::stfXXX(UGeckoInstruction inst)
if (update)
{
gpr.BindToRegister(a, true, true);
- ADD(32, gpr.R(a), Imm32((s32)(s16)inst.SIMM_16));
+ ADD(32, gpr.R(a), Imm32(imm));
}
else
{
- offset = (s32)(s16)inst.SIMM_16;
+ offset = imm;
}
MOV(32, R(RSCRATCH2), gpr.R(a));
}
@@ -145,6 +156,13 @@ void Jit64::stfXXX(UGeckoInstruction inst)
MOV(64, R(RSCRATCH), fpr.R(s));
SafeWriteRegToReg(RSCRATCH, RSCRATCH2, 64, offset, CallerSavedRegistersInUse());
}
+ if (js.memcheck && update)
+ {
+ // revert the address change if an exception occurred
+ MEMCHECK_START(true)
+ SUB(32, gpr.R(a), indexed ? gpr.R(b) : Imm32(imm));
+ MEMCHECK_END
+ }
gpr.UnlockAll();
gpr.UnlockAllX();
}