mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-12 22:56:52 +01:00
Jit: Move boolX to ConstantPropagation
This commit is contained in:
parent
0b81bd8412
commit
8a5cbe696f
@ -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);
|
||||
@ -756,53 +734,46 @@ void Jit64::boolX(UGeckoInstruction inst)
|
||||
}
|
||||
else if (is_and)
|
||||
{
|
||||
if (imm == 0)
|
||||
RCOpArg Rj = gpr.Use(j, RCMode::Read);
|
||||
RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
|
||||
RegCache::Realize(Rj, Ra);
|
||||
|
||||
if (imm == 0xFFFFFFFF)
|
||||
{
|
||||
gpr.SetImmediate32(a, final_not ? 0xFFFFFFFF : 0);
|
||||
if (a != j)
|
||||
MOV(32, Ra, Rj);
|
||||
if (final_not || complement_b)
|
||||
NOT(32, Ra);
|
||||
needs_test = true;
|
||||
}
|
||||
else if (complement_b)
|
||||
{
|
||||
if (a != j)
|
||||
MOV(32, Ra, Rj);
|
||||
NOT(32, Ra);
|
||||
AND(32, Ra, Imm32(imm));
|
||||
}
|
||||
else
|
||||
{
|
||||
RCOpArg Rj = gpr.Use(j, RCMode::Read);
|
||||
RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
|
||||
RegCache::Realize(Rj, Ra);
|
||||
|
||||
if (imm == 0xFFFFFFFF)
|
||||
if (a == j)
|
||||
{
|
||||
if (a != j)
|
||||
MOV(32, Ra, Rj);
|
||||
if (final_not || complement_b)
|
||||
NOT(32, Ra);
|
||||
needs_test = true;
|
||||
AND(32, Ra, Imm32(imm));
|
||||
}
|
||||
else if (complement_b)
|
||||
else if (s32(imm) >= -128 && s32(imm) <= 127)
|
||||
{
|
||||
if (a != j)
|
||||
MOV(32, Ra, Rj);
|
||||
NOT(32, Ra);
|
||||
MOV(32, Ra, Rj);
|
||||
AND(32, Ra, Imm32(imm));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a == j)
|
||||
{
|
||||
AND(32, Ra, Imm32(imm));
|
||||
}
|
||||
else if (s32(imm) >= -128 && s32(imm) <= 127)
|
||||
{
|
||||
MOV(32, Ra, Rj);
|
||||
AND(32, Ra, Imm32(imm));
|
||||
}
|
||||
else
|
||||
{
|
||||
MOV(32, Ra, Imm32(imm));
|
||||
AND(32, Ra, Rj);
|
||||
}
|
||||
MOV(32, Ra, Imm32(imm));
|
||||
AND(32, Ra, Rj);
|
||||
}
|
||||
|
||||
if (final_not)
|
||||
{
|
||||
NOT(32, Ra);
|
||||
needs_test = true;
|
||||
}
|
||||
if (final_not)
|
||||
{
|
||||
NOT(32, Ra);
|
||||
needs_test = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -235,29 +235,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 */))
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user