Jit: Move boolX to ConstantPropagation

This commit is contained in:
JosJuice 2023-08-23 15:22:34 +02:00
parent 3a6eea74dd
commit 77b46c30ad
4 changed files with 162 additions and 81 deletions

View File

@ -680,29 +680,7 @@ void Jit64::boolX(UGeckoInstruction inst)
bool needs_test = false;
DEBUG_ASSERT_MSG(DYNA_REC, inst.OPCD == 31, "Invalid boolX");
if (gpr.IsImm(s, b))
{
const u32 rs_offset = gpr.Imm32(s);
const u32 rb_offset = gpr.Imm32(b);
if (inst.SUBOP10 == 28) // andx
gpr.SetImmediate32(a, rs_offset & rb_offset);
else if (inst.SUBOP10 == 476) // nandx
gpr.SetImmediate32(a, ~(rs_offset & rb_offset));
else if (inst.SUBOP10 == 60) // andcx
gpr.SetImmediate32(a, rs_offset & (~rb_offset));
else if (inst.SUBOP10 == 444) // orx
gpr.SetImmediate32(a, rs_offset | rb_offset);
else if (inst.SUBOP10 == 124) // norx
gpr.SetImmediate32(a, ~(rs_offset | rb_offset));
else if (inst.SUBOP10 == 412) // orcx
gpr.SetImmediate32(a, rs_offset | (~rb_offset));
else if (inst.SUBOP10 == 316) // xorx
gpr.SetImmediate32(a, rs_offset ^ rb_offset);
else if (inst.SUBOP10 == 284) // eqvx
gpr.SetImmediate32(a, ~(rs_offset ^ rb_offset));
}
else if (gpr.IsImm(s) || gpr.IsImm(b))
if (gpr.IsImm(s) || gpr.IsImm(b))
{
const auto [i, j] = gpr.IsImm(s) ? std::pair(s, b) : std::pair(b, s);
u32 imm = gpr.Imm32(i);
@ -755,12 +733,6 @@ void Jit64::boolX(UGeckoInstruction inst)
}
}
else if (is_and)
{
if (imm == 0)
{
gpr.SetImmediate32(a, final_not ? 0xFFFFFFFF : 0);
}
else
{
RCOpArg Rj = gpr.Use(j, RCMode::Read);
RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
@ -805,7 +777,6 @@ void Jit64::boolX(UGeckoInstruction inst)
}
}
}
}
else if (is_or)
{
RCOpArg Rj = gpr.Use(j, RCMode::Read);

View File

@ -231,29 +231,7 @@ void JitArm64::boolX(UGeckoInstruction inst)
JITDISABLE(bJITIntegerOff);
int a = inst.RA, s = inst.RS, b = inst.RB;
if (gpr.IsImm(s) && gpr.IsImm(b))
{
if (inst.SUBOP10 == 28) // andx
gpr.SetImmediate(a, (u32)gpr.GetImm(s) & (u32)gpr.GetImm(b));
else if (inst.SUBOP10 == 476) // nandx
gpr.SetImmediate(a, ~((u32)gpr.GetImm(s) & (u32)gpr.GetImm(b)));
else if (inst.SUBOP10 == 60) // andcx
gpr.SetImmediate(a, (u32)gpr.GetImm(s) & (~(u32)gpr.GetImm(b)));
else if (inst.SUBOP10 == 444) // orx
gpr.SetImmediate(a, (u32)gpr.GetImm(s) | (u32)gpr.GetImm(b));
else if (inst.SUBOP10 == 124) // norx
gpr.SetImmediate(a, ~((u32)gpr.GetImm(s) | (u32)gpr.GetImm(b)));
else if (inst.SUBOP10 == 412) // orcx
gpr.SetImmediate(a, (u32)gpr.GetImm(s) | (~(u32)gpr.GetImm(b)));
else if (inst.SUBOP10 == 316) // xorx
gpr.SetImmediate(a, (u32)gpr.GetImm(s) ^ (u32)gpr.GetImm(b));
else if (inst.SUBOP10 == 284) // eqvx
gpr.SetImmediate(a, ~((u32)gpr.GetImm(s) ^ (u32)gpr.GetImm(b)));
if (inst.Rc)
ComputeRC0(gpr.GetImm(a));
}
else if (s == b)
if (s == b)
{
if ((inst.SUBOP10 == 28 /* andx */) || (inst.SUBOP10 == 444 /* orx */))
{

View File

@ -36,6 +36,8 @@ ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruc
case 28: // andi
case 29: // andis
return EvaluateBitwiseImm(inst, BitAND);
case 31:
return EvaluateTable31(inst);
default:
return {};
}
@ -69,6 +71,132 @@ ConstantPropagationResult ConstantPropagation::EvaluateBitwiseImm(UGeckoInstruct
return ConstantPropagationResult(inst.RA, do_op(m_gpr_values[inst.RS], immediate), is_and);
}
ConstantPropagationResult ConstantPropagation::EvaluateTable31(UGeckoInstruction inst) const
{
const bool has_s = HasGPR(inst.RS);
const bool has_b = HasGPR(inst.RB);
if (!has_s || !has_b)
{
if (has_s)
return EvaluateTable31OneRegisterKnown(inst, GetGPR(inst.RS), false);
else if (has_b)
return EvaluateTable31OneRegisterKnown(inst, GetGPR(inst.RB), true);
else if (inst.RS == inst.RB)
return EvaluateTable31IdenticalRegisters(inst);
else
return {};
}
u32 a;
const u32 s = GetGPR(inst.RS);
const u32 b = GetGPR(inst.RB);
switch (inst.SUBOP10)
{
case 28: // andx
a = s & b;
break;
case 60: // andcx
a = s & (~b);
break;
case 124: // norx
a = ~(s | b);
break;
case 284: // eqvx
a = ~(s ^ b);
break;
case 316: // xorx
a = s ^ b;
break;
case 412: // orcx
a = s | (~b);
break;
case 444: // orx
a = s | b;
break;
case 476: // nandx
a = ~(s & b);
break;
default:
return {};
}
return ConstantPropagationResult(inst.RA, a, inst.Rc);
}
ConstantPropagationResult
ConstantPropagation::EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32 value,
bool known_reg_is_b) const
{
u32 a;
switch (inst.SUBOP10)
{
case 60: // andcx
if (known_reg_is_b)
value = ~value;
[[fallthrough]];
case 28: // andx
if (value == 0)
a = 0;
else
return {};
break;
case 124: // norx
if (value == 0xFFFFFFFF)
a = 0;
else
return {};
break;
case 412: // orcx
if (known_reg_is_b)
value = ~value;
[[fallthrough]];
case 444: // orx
if (value == 0xFFFFFFFF)
a = 0xFFFFFFFF;
else
return {};
break;
case 476: // nandx
if (value == 0)
a = 0xFFFFFFFF;
else
return {};
break;
default:
return {};
}
return ConstantPropagationResult(inst.RA, a, inst.Rc);
}
ConstantPropagationResult
ConstantPropagation::EvaluateTable31IdenticalRegisters(UGeckoInstruction inst) const
{
u32 a;
switch (inst.SUBOP10)
{
case 60: // andcx
a = 0;
break;
case 284: // eqvx
a = 0xFFFFFFFF;
break;
case 316: // xorx
a = 0;
break;
case 412: // orcx
a = 0xFFFFFFFF;
break;
default:
return {};
}
return ConstantPropagationResult(inst.RA, a, inst.Rc);
}
void ConstantPropagation::Apply(ConstantPropagationResult result)
{
if (result.gpr >= 0)

View File

@ -80,6 +80,10 @@ private:
ConstantPropagationResult EvaluateAddImm(UGeckoInstruction inst) const;
ConstantPropagationResult EvaluateBitwiseImm(UGeckoInstruction inst,
u32 (*do_op)(u32, u32)) const;
ConstantPropagationResult EvaluateTable31(UGeckoInstruction inst) const;
ConstantPropagationResult EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32 value,
bool known_reg_is_b) const;
ConstantPropagationResult EvaluateTable31IdenticalRegisters(UGeckoInstruction inst) const;
static constexpr ConstantPropagationResult DO_NOTHING = [] {
ConstantPropagationResult result;