summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authornodchip <nodchip@gmail.com>2010-08-30 01:24:14 +0000
committernodchip <nodchip@gmail.com>2010-08-30 01:24:14 +0000
commitbaba7f54dc73c2c73ce9b7e3324f93dd02c882af (patch)
tree4ddd78f5df49a43c3b24b131339fe1a2db4e4f71 /Source/Core
parente4f9b6a5f8a92d838f54d0693a53ec70a1bc9a86 (diff)
JitIL: Fixed the Issue 3114. The bug was introduced because the usage of MOVSD/MOVSS was wrong. MOVSD/MOVSS don't clear the upper bits when they are used to transfer between registers. But they clear the upper bits when they are used to transfer between a register and memory.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6151 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp34
1 files changed, 25 insertions, 9 deletions
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp
index 11e2f7143f..629d844d33 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp
@@ -1362,9 +1362,17 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
// TODO: Optimize the case that the register of op1 can be
// recycled. (SHUFPD may not be so fast.)
X64Reg reg = fregBinRHSRegWithMov(RI, I);
- // TODO: Check whether the following code works
- // when the op1 is in the FSlotSet
- Jit->MOVSD(reg, fregLocForInst(RI, getOp1(I)));
+ OpArg loc1 = fregLocForInst(RI, getOp1(I));
+ if (loc1.IsSimpleReg()) {
+ Jit->MOVSD(reg, loc1);
+ } else {
+ // If op1 is in FSlotSet, we have to mov loc1 to XMM0
+ // before MOVSD/MOVSS.
+ // Because register<->memory transfer with MOVSD/MOVSS
+ // clears upper 64/96-bits of the destination register.
+ Jit->MOVAPD(XMM0, loc1);
+ Jit->MOVSD(reg, R(XMM0));
+ }
RI.fregs[reg] = I;
fregNormalRegClear(RI, I);
break;
@@ -1569,9 +1577,13 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
// TODO: Optimize the case that the register of only op1 can be
// recycled.
X64Reg reg = fregBinRHSRegWithMov(RI, I);
- // TODO: Check whether the following code works
- // when the op1 is in the FSlotSet
- Jit->MOVSS(reg, fregLocForInst(RI, getOp1(I)));
+ OpArg loc1 = fregLocForInst(RI, getOp1(I));
+ if (loc1.IsSimpleReg()) {
+ Jit->MOVSS(reg, loc1);
+ } else {
+ Jit->MOVAPD(XMM0, loc1);
+ Jit->MOVSS(reg, R(XMM0));
+ }
RI.fregs[reg] = I;
fregNormalRegClear(RI, I);
break;
@@ -1582,9 +1594,13 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
// TODO: Optimize the case that the register of only op2 can be
// recycled.
X64Reg reg = fregBinLHSRegWithMov(RI, I);
- // TODO: Check whether the following code works
- // when the op1 is in the FSlotSet
- Jit->MOVSS(reg, fregLocForInst(RI, getOp2(I)));
+ OpArg loc2 = fregLocForInst(RI, getOp2(I));
+ if (loc2.IsSimpleReg()) {
+ Jit->MOVSS(reg, loc2);
+ } else {
+ Jit->MOVAPD(XMM0, loc2);
+ Jit->MOVSS(reg, R(XMM0));
+ }
Jit->SHUFPS(reg, R(reg), 0xF1);
RI.fregs[reg] = I;
fregNormalRegClear(RI, I);