Skip to content

Commit

Permalink
Jit: Remove unsafe MOV optimization
Browse files Browse the repository at this point in the history
This optimization broke arithXex in rare cases by
emitting XOR where MOV was expected.
  • Loading branch information
hthh committed Jun 30, 2016
1 parent f8bf839 commit 161a025
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 11 deletions.
27 changes: 16 additions & 11 deletions Source/Core/Common/x64Emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1540,13 +1540,6 @@ void XEmitter::XOR(int bits, const OpArg& a1, const OpArg& a2)
}
void XEmitter::MOV(int bits, const OpArg& a1, const OpArg& a2)
{
// Shortcut to zero a register
if (a2.IsZero() && a1.IsSimpleReg() && !flags_locked)
{
XOR(bits, a1, a1);
return;
}

if (a1.IsSimpleReg() && a2.IsSimpleReg() && a1.GetSimpleReg() == a2.GetSimpleReg())
ERROR_LOG(DYNA_REC, "Redundant MOV @ %p - bug in JIT?", code);
WriteNormalOp(bits, nrmMOV, a1, a2);
Expand Down Expand Up @@ -1578,6 +1571,18 @@ void XEmitter::CMP_or_TEST(int bits, const OpArg& a1, const OpArg& a2)
WriteNormalOp(bits, nrmCMP, a1, a2);
}
}
void XEmitter::MOV_or_XOR(int bits, const OpArg& a1, const OpArg& a2)
{
if (a2.IsZero() && a1.IsSimpleReg() && !flags_locked)
{
// turn 'MOV reg, 0' into shorter 'XOR reg, reg'
XOR(bits, a1, a1);
}
else
{
MOV(bits, a1, a2);
}
}

void XEmitter::MOV_sum(int bits, X64Reg dest, const OpArg& a1, const OpArg& a2)
{
Expand All @@ -1590,15 +1595,15 @@ void XEmitter::MOV_sum(int bits, X64Reg dest, const OpArg& a1, const OpArg& a2)
{
if (!a2.IsSimpleReg() || a2.GetSimpleReg() != dest)
{
MOV(bits, R(dest), a2);
MOV_or_XOR(bits, R(dest), a2);
}
return;
}
if (a2.IsZero())
{
if (!a1.IsSimpleReg() || a1.GetSimpleReg() != dest)
{
MOV(bits, R(dest), a1);
MOV_or_XOR(bits, R(dest), a1);
}
return;
}
Expand All @@ -1621,7 +1626,7 @@ void XEmitter::MOV_sum(int bits, X64Reg dest, const OpArg& a1, const OpArg& a2)
{
if (a1.IsImm() && a2.IsImm())
{
MOV(32, R(dest), Imm32(a1.Imm32() + a2.Imm32()));
MOV_or_XOR(32, R(dest), Imm32(a1.Imm32() + a2.Imm32()));
return;
}

Expand All @@ -1645,7 +1650,7 @@ void XEmitter::MOV_sum(int bits, X64Reg dest, const OpArg& a1, const OpArg& a2)
}

// Fallback
MOV(bits, R(dest), a1);
MOV_or_XOR(bits, R(dest), a1);
ADD(bits, R(dest), a2);
}

Expand Down
1 change: 1 addition & 0 deletions Source/Core/Common/x64Emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ class XEmitter
void TEST(int bits, const OpArg& a1, const OpArg& a2);

void CMP_or_TEST(int bits, const OpArg& a1, const OpArg& a2);
void MOV_or_XOR(int bits, const OpArg& a1, const OpArg& a2);
void MOV_sum(int bits, X64Reg dest, const OpArg& a1, const OpArg& a2);

// Are these useful at all? Consider removing.
Expand Down

0 comments on commit 161a025

Please sign in to comment.