Jit64: Split arithcx into addcx and subfcx

JitArm64 also opts to separate the two. The shared logic makes less
sense once we start adding more optimizations.
This commit is contained in:
Sintendo
2021-09-17 22:59:00 +02:00
parent cc84799c7f
commit a9e0f21373
3 changed files with 42 additions and 23 deletions

View File

@ -150,7 +150,7 @@ public:
void DynaRunTable63(UGeckoInstruction inst); void DynaRunTable63(UGeckoInstruction inst);
void addx(UGeckoInstruction inst); void addx(UGeckoInstruction inst);
void arithcx(UGeckoInstruction inst); void addcx(UGeckoInstruction inst);
void mulli(UGeckoInstruction inst); void mulli(UGeckoInstruction inst);
void mulhwXx(UGeckoInstruction inst); void mulhwXx(UGeckoInstruction inst);
void mullwx(UGeckoInstruction inst); void mullwx(UGeckoInstruction inst);
@ -233,6 +233,7 @@ public:
void subfic(UGeckoInstruction inst); void subfic(UGeckoInstruction inst);
void subfx(UGeckoInstruction inst); void subfx(UGeckoInstruction inst);
void subfcx(UGeckoInstruction inst);
void twX(UGeckoInstruction inst); void twX(UGeckoInstruction inst);

View File

@ -150,8 +150,8 @@ constexpr std::array<GekkoOPTemplate, 13> s_table19{{
constexpr std::array<GekkoOPTemplate, 107> s_table31{{ constexpr std::array<GekkoOPTemplate, 107> s_table31{{
{266, &Jit64::addx}, // addx {266, &Jit64::addx}, // addx
{778, &Jit64::addx}, // addox {778, &Jit64::addx}, // addox
{10, &Jit64::arithcx}, // addcx {10, &Jit64::addcx}, // addcx
{522, &Jit64::arithcx}, // addcox {522, &Jit64::addcx}, // addcox
{138, &Jit64::arithXex}, // addex {138, &Jit64::arithXex}, // addex
{650, &Jit64::arithXex}, // addeox {650, &Jit64::arithXex}, // addeox
{234, &Jit64::arithXex}, // addmex {234, &Jit64::arithXex}, // addmex
@ -170,8 +170,8 @@ constexpr std::array<GekkoOPTemplate, 107> s_table31{{
{616, &Jit64::negx}, // negox {616, &Jit64::negx}, // negox
{40, &Jit64::subfx}, // subfx {40, &Jit64::subfx}, // subfx
{552, &Jit64::subfx}, // subfox {552, &Jit64::subfx}, // subfox
{8, &Jit64::arithcx}, // subfcx {8, &Jit64::subfcx}, // subfcx
{520, &Jit64::arithcx}, // subfcox {520, &Jit64::subfcx}, // subfcox
{136, &Jit64::arithXex}, // subfex {136, &Jit64::arithXex}, // subfex
{648, &Jit64::arithXex}, // subfeox {648, &Jit64::arithXex}, // subfeox
{232, &Jit64::arithXex}, // subfmex {232, &Jit64::arithXex}, // subfmex

View File

@ -1806,11 +1806,39 @@ void Jit64::arithXex(UGeckoInstruction inst)
ComputeRC(d); ComputeRC(d);
} }
void Jit64::arithcx(UGeckoInstruction inst) void Jit64::addcx(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)
{
ADD(32, Rd, Rb);
}
else
{
if (d != b)
MOV(32, Rd, Rb);
ADD(32, Rd, Ra);
}
}
FinalizeCarryOverflow(inst.OE);
if (inst.Rc)
ComputeRC(d);
}
void Jit64::subfcx(UGeckoInstruction inst)
{ {
INSTRUCTION_START INSTRUCTION_START
JITDISABLE(bJITIntegerOff); JITDISABLE(bJITIntegerOff);
bool add = !!(inst.SUBOP10 & 2); // add or sub
int a = inst.RA, b = inst.RB, d = inst.RD; int a = inst.RA, b = inst.RB, d = inst.RD;
{ {
@ -1821,30 +1849,20 @@ void Jit64::arithcx(UGeckoInstruction inst)
if (d == a && d != b) if (d == a && d != b)
{ {
if (add) // special case, because sub isn't reversible
{ MOV(32, R(RSCRATCH), Ra);
ADD(32, Rd, Rb); MOV(32, Rd, Rb);
} SUB(32, Rd, R(RSCRATCH));
else
{
// special case, because sub isn't reversible
MOV(32, R(RSCRATCH), Ra);
MOV(32, Rd, Rb);
SUB(32, Rd, R(RSCRATCH));
}
} }
else else
{ {
if (d != b) if (d != b)
MOV(32, Rd, Rb); MOV(32, Rd, Rb);
if (add) SUB(32, Rd, Ra);
ADD(32, Rd, Ra);
else
SUB(32, Rd, Ra);
} }
} }
FinalizeCarryOverflow(inst.OE, !add); FinalizeCarryOverflow(inst.OE, true);
if (inst.Rc) if (inst.Rc)
ComputeRC(d); ComputeRC(d);
} }