Jit: Move subfx to ConstantPropagation

This commit is contained in:
JosJuice 2024-08-31 16:03:02 +02:00
parent c64b981ed8
commit 7e33dd5459
4 changed files with 44 additions and 57 deletions

View File

@ -1097,24 +1097,7 @@ void Jit64::subfx(UGeckoInstruction inst)
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);
}
else if (gpr.IsImm(a, b))
{
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);
}
else if (gpr.IsImm(a))
if (gpr.IsImm(a))
{
s32 j = gpr.SImm32(a);
RCOpArg Rb = gpr.Use(b, RCMode::Read);

View File

@ -1031,26 +1031,10 @@ void JitArm64::subfx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD;
if (a == b)
{
gpr.SetImmediate(d, 0);
if (inst.Rc)
ComputeRC0(gpr.GetImm(d));
}
else if (gpr.IsImm(a) && gpr.IsImm(b))
{
u32 i = gpr.GetImm(a), j = gpr.GetImm(b);
gpr.SetImmediate(d, j - i);
if (inst.Rc)
ComputeRC0(gpr.GetImm(d));
}
else
{
gpr.BindToRegister(d, d == a || d == b);
SUB(gpr.R(d), gpr.R(b), gpr.R(a));
if (inst.Rc)
ComputeRC0(gpr.R(d));
}
gpr.BindToRegister(d, d == a || d == b);
SUB(gpr.R(d), gpr.R(b), gpr.R(a));
if (inst.Rc)
ComputeRC0(gpr.R(d));
}
void JitArm64::subfex(UGeckoInstruction inst)
@ -1153,28 +1137,15 @@ void JitArm64::subfcx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD;
if (gpr.IsImm(a) && gpr.IsImm(b))
{
u32 a_imm = gpr.GetImm(a), b_imm = gpr.GetImm(b);
gpr.BindToRegister(d, d == a || d == b);
gpr.SetImmediate(d, b_imm - a_imm);
ComputeCarry(a_imm == 0 || Interpreter::Helper_Carry(b_imm, 0u - a_imm));
// d = b - a
CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a));
if (inst.Rc)
ComputeRC0(gpr.GetImm(d));
}
else
{
gpr.BindToRegister(d, d == a || d == b);
ComputeCarry();
// d = b - a
CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a));
ComputeCarry();
if (inst.Rc)
ComputeRC0(gpr.R(d));
}
if (inst.Rc)
ComputeRC0(gpr.R(d));
}
void JitArm64::subfzex(UGeckoInstruction inst)

View File

@ -213,6 +213,8 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31AB(UGeckoInstructi
return EvaluateTable31ABOneRegisterKnown(inst, flags, GetGPR(inst.RA));
else if (has_b)
return EvaluateTable31ABOneRegisterKnown(inst, flags, GetGPR(inst.RB));
else if (inst.RA == inst.RB)
return EvaluateTable31ABIdenticalRegisters(inst, flags);
else
return {};
}
@ -224,6 +226,13 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31AB(UGeckoInstructi
switch (inst.SUBOP10)
{
case 8: // subfcx
case 40: // subfx
case 520: // subfcox
case 552: // subfox
d = u64(u32(~a)) + u64(b) + 1;
d_overflow = s64(s32(b)) - s64(s32(a));
break;
case 10: // addcx
case 522: // addcox
case 266: // addx
@ -276,6 +285,28 @@ ConstantPropagation::EvaluateTable31ABOneRegisterKnown(UGeckoInstruction inst, u
return {};
}
ConstantPropagationResult
ConstantPropagation::EvaluateTable31ABIdenticalRegisters(UGeckoInstruction inst, u64 flags) const
{
switch (inst.SUBOP10)
{
case 8: // subfcx
case 40: // subfx
case 520: // subfcox
case 552: // subfox
{
ConstantPropagationResult result(inst.RD, 0, inst.Rc);
if (flags & FL_SET_CA)
result.carry = true;
if (flags & FL_SET_OE)
result.overflow = false;
return result;
}
default:
return {};
}
}
ConstantPropagationResult ConstantPropagation::EvaluateTable31SB(UGeckoInstruction inst) const
{
const bool has_s = HasGPR(inst.RS);

View File

@ -89,6 +89,8 @@ private:
ConstantPropagationResult EvaluateTable31AB(UGeckoInstruction inst, u64 flags) const;
ConstantPropagationResult EvaluateTable31ABOneRegisterKnown(UGeckoInstruction inst, u64 flags,
u32 value) const;
ConstantPropagationResult EvaluateTable31ABIdenticalRegisters(UGeckoInstruction inst,
u64 flags) const;
ConstantPropagationResult EvaluateTable31SB(UGeckoInstruction inst) const;
ConstantPropagationResult EvaluateTable31SBOneRegisterKnown(UGeckoInstruction inst, u32 value,
bool known_reg_is_b) const;