Jit64: Merge subfx and subfcx
Again, logic and optimizations are mostly the same so it makes sense.
This commit is contained in:
parent
a725eb80ff
commit
da9546cb2f
|
@ -232,7 +232,6 @@ public:
|
|||
|
||||
void subfic(UGeckoInstruction inst);
|
||||
void subfx(UGeckoInstruction inst);
|
||||
void subfcx(UGeckoInstruction inst);
|
||||
|
||||
void twX(UGeckoInstruction inst);
|
||||
|
||||
|
|
|
@ -170,8 +170,8 @@ constexpr std::array<GekkoOPTemplate, 107> s_table31{{
|
|||
{616, &Jit64::negx}, // negox
|
||||
{40, &Jit64::subfx}, // subfx
|
||||
{552, &Jit64::subfx}, // subfox
|
||||
{8, &Jit64::subfcx}, // subfcx
|
||||
{520, &Jit64::subfcx}, // subfcox
|
||||
{8, &Jit64::subfx}, // subfcx
|
||||
{520, &Jit64::subfx}, // subfcox
|
||||
{136, &Jit64::arithXex}, // subfex
|
||||
{648, &Jit64::arithXex}, // subfeox
|
||||
{232, &Jit64::arithXex}, // subfmex
|
||||
|
|
|
@ -938,10 +938,13 @@ void Jit64::subfx(UGeckoInstruction inst)
|
|||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||
const bool carry = !(inst.SUBOP10 & (1 << 5));
|
||||
|
||||
if (a == b)
|
||||
{
|
||||
gpr.SetImmediate32(d, 0);
|
||||
if (carry)
|
||||
FinalizeCarry(true);
|
||||
if (inst.OE)
|
||||
GenerateConstantOverflow(false);
|
||||
}
|
||||
|
@ -949,6 +952,8 @@ void Jit64::subfx(UGeckoInstruction inst)
|
|||
{
|
||||
s32 i = gpr.SImm32(b), j = gpr.SImm32(a);
|
||||
gpr.SetImmediate32(d, i - j);
|
||||
if (carry)
|
||||
FinalizeCarry(j == 0 || Interpreter::Helper_Carry((u32)i, 0u - (u32)j));
|
||||
if (inst.OE)
|
||||
GenerateConstantOverflow((s64)i - (s64)j);
|
||||
}
|
||||
|
@ -963,16 +968,20 @@ void Jit64::subfx(UGeckoInstruction inst)
|
|||
{
|
||||
if (d != b)
|
||||
MOV(32, Rd, Rb);
|
||||
if (carry)
|
||||
FinalizeCarry(true);
|
||||
if (inst.OE)
|
||||
GenerateConstantOverflow(false);
|
||||
}
|
||||
else if (d == b)
|
||||
{
|
||||
SUB(32, Rd, Imm32(j));
|
||||
if (carry)
|
||||
FinalizeCarry(CC_NC);
|
||||
if (inst.OE)
|
||||
GenerateOverflow();
|
||||
}
|
||||
else if (Rb.IsSimpleReg() && !inst.OE)
|
||||
else if (Rb.IsSimpleReg() && !carry && !inst.OE)
|
||||
{
|
||||
LEA(32, Rd, MDisp(Rb.GetSimpleReg(), -j));
|
||||
}
|
||||
|
@ -980,6 +989,8 @@ void Jit64::subfx(UGeckoInstruction inst)
|
|||
{
|
||||
MOV(32, Rd, Rb);
|
||||
SUB(32, Rd, Imm32(j));
|
||||
if (carry)
|
||||
FinalizeCarry(CC_NC);
|
||||
if (inst.OE)
|
||||
GenerateOverflow();
|
||||
}
|
||||
|
@ -993,6 +1004,8 @@ void Jit64::subfx(UGeckoInstruction inst)
|
|||
if (d != a)
|
||||
MOV(32, Rd, Ra);
|
||||
NEG(32, Rd);
|
||||
if (carry)
|
||||
FinalizeCarry(CC_NC);
|
||||
if (inst.OE)
|
||||
GenerateOverflow();
|
||||
}
|
||||
|
@ -1003,21 +1016,21 @@ void Jit64::subfx(UGeckoInstruction inst)
|
|||
RCX64Reg Rd = gpr.Bind(d, RCMode::Write);
|
||||
RegCache::Realize(Ra, Rb, Rd);
|
||||
|
||||
if (d == b)
|
||||
{
|
||||
SUB(32, Rd, Ra);
|
||||
}
|
||||
else if (d == a)
|
||||
if (d == a && d != b)
|
||||
{
|
||||
// special case, because sub isn't reversible
|
||||
MOV(32, R(RSCRATCH), Ra);
|
||||
MOV(32, Rd, Rb);
|
||||
SUB(32, Rd, R(RSCRATCH));
|
||||
}
|
||||
else
|
||||
{
|
||||
MOV(32, Rd, Rb);
|
||||
if (d != b)
|
||||
MOV(32, Rd, Rb);
|
||||
SUB(32, Rd, Ra);
|
||||
}
|
||||
if (carry)
|
||||
FinalizeCarry(CC_NC);
|
||||
if (inst.OE)
|
||||
GenerateOverflow();
|
||||
}
|
||||
|
@ -1818,38 +1831,6 @@ void Jit64::arithXex(UGeckoInstruction inst)
|
|||
ComputeRC(d);
|
||||
}
|
||||
|
||||
void Jit64::subfcx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||
|
||||
{
|
||||
RCOpArg Ra = gpr.Use(a, RCMode::Read);
|
||||
RCOpArg Rb = gpr.Use(b, RCMode::Read);
|
||||
RCX64Reg Rd = gpr.Bind(d, RCMode::Write);
|
||||
RegCache::Realize(Ra, Rb, Rd);
|
||||
|
||||
if (d == a && d != b)
|
||||
{
|
||||
// special case, because sub isn't reversible
|
||||
MOV(32, R(RSCRATCH), Ra);
|
||||
MOV(32, Rd, Rb);
|
||||
SUB(32, Rd, R(RSCRATCH));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d != b)
|
||||
MOV(32, Rd, Rb);
|
||||
SUB(32, Rd, Ra);
|
||||
}
|
||||
}
|
||||
|
||||
FinalizeCarryOverflow(inst.OE, true);
|
||||
if (inst.Rc)
|
||||
ComputeRC(d);
|
||||
}
|
||||
|
||||
void Jit64::rlwinmx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
|
|
Loading…
Reference in New Issue