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
This commit is contained in:
parent
e4f9b6a5f8
commit
baba7f54dc
|
@ -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
|
// TODO: Optimize the case that the register of op1 can be
|
||||||
// recycled. (SHUFPD may not be so fast.)
|
// recycled. (SHUFPD may not be so fast.)
|
||||||
X64Reg reg = fregBinRHSRegWithMov(RI, I);
|
X64Reg reg = fregBinRHSRegWithMov(RI, I);
|
||||||
// TODO: Check whether the following code works
|
OpArg loc1 = fregLocForInst(RI, getOp1(I));
|
||||||
// when the op1 is in the FSlotSet
|
if (loc1.IsSimpleReg()) {
|
||||||
Jit->MOVSD(reg, fregLocForInst(RI, getOp1(I)));
|
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;
|
RI.fregs[reg] = I;
|
||||||
fregNormalRegClear(RI, I);
|
fregNormalRegClear(RI, I);
|
||||||
break;
|
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
|
// TODO: Optimize the case that the register of only op1 can be
|
||||||
// recycled.
|
// recycled.
|
||||||
X64Reg reg = fregBinRHSRegWithMov(RI, I);
|
X64Reg reg = fregBinRHSRegWithMov(RI, I);
|
||||||
// TODO: Check whether the following code works
|
OpArg loc1 = fregLocForInst(RI, getOp1(I));
|
||||||
// when the op1 is in the FSlotSet
|
if (loc1.IsSimpleReg()) {
|
||||||
Jit->MOVSS(reg, fregLocForInst(RI, getOp1(I)));
|
Jit->MOVSS(reg, loc1);
|
||||||
|
} else {
|
||||||
|
Jit->MOVAPD(XMM0, loc1);
|
||||||
|
Jit->MOVSS(reg, R(XMM0));
|
||||||
|
}
|
||||||
RI.fregs[reg] = I;
|
RI.fregs[reg] = I;
|
||||||
fregNormalRegClear(RI, I);
|
fregNormalRegClear(RI, I);
|
||||||
break;
|
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
|
// TODO: Optimize the case that the register of only op2 can be
|
||||||
// recycled.
|
// recycled.
|
||||||
X64Reg reg = fregBinLHSRegWithMov(RI, I);
|
X64Reg reg = fregBinLHSRegWithMov(RI, I);
|
||||||
// TODO: Check whether the following code works
|
OpArg loc2 = fregLocForInst(RI, getOp2(I));
|
||||||
// when the op1 is in the FSlotSet
|
if (loc2.IsSimpleReg()) {
|
||||||
Jit->MOVSS(reg, fregLocForInst(RI, getOp2(I)));
|
Jit->MOVSS(reg, loc2);
|
||||||
|
} else {
|
||||||
|
Jit->MOVAPD(XMM0, loc2);
|
||||||
|
Jit->MOVSS(reg, R(XMM0));
|
||||||
|
}
|
||||||
Jit->SHUFPS(reg, R(reg), 0xF1);
|
Jit->SHUFPS(reg, R(reg), 0xF1);
|
||||||
RI.fregs[reg] = I;
|
RI.fregs[reg] = I;
|
||||||
fregNormalRegClear(RI, I);
|
fregNormalRegClear(RI, I);
|
||||||
|
|
Loading…
Reference in New Issue