JIT: unify subfcx and addcx code

Again, shorter and should make future optimizations easier.
This commit is contained in:
Fiora 2014-09-06 22:34:40 -07:00
parent 5d80145dc0
commit a6c9515b00
3 changed files with 33 additions and 55 deletions

View File

@ -139,7 +139,7 @@ public:
void DynaRunTable63(UGeckoInstruction _inst);
void addx(UGeckoInstruction inst);
void addcx(UGeckoInstruction inst);
void arithcx(UGeckoInstruction inst);
void mulli(UGeckoInstruction inst);
void mulhwXx(UGeckoInstruction inst);
void mullwx(UGeckoInstruction inst);
@ -215,7 +215,6 @@ public:
void dcbz(UGeckoInstruction inst);
void subfic(UGeckoInstruction inst);
void subfcx(UGeckoInstruction inst);
void subfx(UGeckoInstruction inst);
void twx(UGeckoInstruction inst);

View File

@ -294,8 +294,8 @@ static GekkoOPTemplate table31_2[] =
{
{266, &Jit64::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
{778, &Jit64::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
{10, &Jit64::addcx}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
{522, &Jit64::addcx}, //"addcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
{10, &Jit64::arithcx}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
{522, &Jit64::arithcx}, //"addcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
{138, &Jit64::arithXex}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{650, &Jit64::arithXex}, //"addeox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{234, &Jit64::arithXex}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
@ -311,8 +311,8 @@ static GekkoOPTemplate table31_2[] =
{104, &Jit64::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
{40, &Jit64::subfx}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
{552, &Jit64::subfx}, //"subox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
{8, &Jit64::subfcx}, //"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
{520, &Jit64::subfcx}, //"subfcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
{8, &Jit64::arithcx}, //"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
{520, &Jit64::arithcx}, //"subfcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
{136, &Jit64::arithXex}, //"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{232, &Jit64::arithXex}, //"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{200, &Jit64::arithXex}, //"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},

View File

@ -750,36 +750,7 @@ void Jit64::subfic(UGeckoInstruction inst)
// This instruction has no RC flag
}
void Jit64::subfcx(UGeckoInstruction inst)
{
INSTRUCTION_START;
JITDISABLE(bJITIntegerOff);
int a = inst.RA, b = inst.RB, d = inst.RD;
gpr.Lock(a, b, d);
gpr.BindToRegister(d, (d == a || d == b), true);
JitClearCAOV(inst.OE);
if (d == b)
{
SUB(32, gpr.R(d), gpr.R(a));
}
else if (d == a)
{
MOV(32, R(RSCRATCH), gpr.R(a));
MOV(32, gpr.R(d), gpr.R(b));
SUB(32, gpr.R(d), R(RSCRATCH));
}
else
{
MOV(32, gpr.R(d), gpr.R(b));
SUB(32, gpr.R(d), gpr.R(a));
}
if (inst.Rc)
ComputeRC(gpr.R(d));
FinalizeCarryOverflow(inst.OE, true);
gpr.UnlockAll();
}
void Jit64::subfx(UGeckoInstruction inst)
{
@ -1285,36 +1256,44 @@ void Jit64::arithXex(UGeckoInstruction inst)
gpr.UnlockAll();
}
void Jit64::addcx(UGeckoInstruction inst)
void Jit64::arithcx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
bool add = !!(inst.SUBOP10 & 2); // add or sub
int a = inst.RA, b = inst.RB, d = inst.RD;
gpr.Lock(a, b, d);
gpr.BindToRegister(d, d == a || d == b, true);
JitClearCAOV(inst.OE);
if ((d == a) || (d == b))
if (d == a && d != b)
{
int operand = ((d == a) ? b : a);
gpr.Lock(a, b, d);
gpr.BindToRegister(d, true);
JitClearCAOV(inst.OE);
ADD(32, gpr.R(d), gpr.R(operand));
FinalizeCarryOverflow(inst.OE);
if (inst.Rc)
ComputeRC(gpr.R(d));
gpr.UnlockAll();
if (add)
{
ADD(32, gpr.R(d), gpr.R(b));
}
else
{
// special case, because sub isn't reversible
MOV(32, R(RSCRATCH), gpr.R(a));
MOV(32, gpr.R(d), gpr.R(b));
SUB(32, gpr.R(d), R(RSCRATCH));
}
}
else
{
gpr.Lock(a, b, d);
gpr.BindToRegister(d, false);
JitClearCAOV(inst.OE);
MOV(32, gpr.R(d), gpr.R(a));
ADD(32, gpr.R(d), gpr.R(b));
FinalizeCarryOverflow(inst.OE);
if (inst.Rc)
ComputeRC(gpr.R(d));
gpr.UnlockAll();
if (d != b)
MOV(32, gpr.R(d), gpr.R(b));
if (add)
ADD(32, gpr.R(d), gpr.R(a));
else
SUB(32, gpr.R(d), gpr.R(a));
}
FinalizeCarryOverflow(inst.OE, !add);
if (inst.Rc)
ComputeRC(gpr.R(d));
gpr.UnlockAll();
}
void Jit64::rlwinmx(UGeckoInstruction inst)