mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-12-16 04:09:39 +00:00
Jit: Move boolX to ConstantPropagation
This commit is contained in:
parent
3a6eea74dd
commit
77b46c30ad
@ -680,29 +680,7 @@ void Jit64::boolX(UGeckoInstruction inst)
|
|||||||
bool needs_test = false;
|
bool needs_test = false;
|
||||||
DEBUG_ASSERT_MSG(DYNA_REC, inst.OPCD == 31, "Invalid boolX");
|
DEBUG_ASSERT_MSG(DYNA_REC, inst.OPCD == 31, "Invalid boolX");
|
||||||
|
|
||||||
if (gpr.IsImm(s, b))
|
if (gpr.IsImm(s) || gpr.IsImm(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))
|
|
||||||
{
|
{
|
||||||
const auto [i, j] = gpr.IsImm(s) ? std::pair(s, b) : std::pair(b, s);
|
const auto [i, j] = gpr.IsImm(s) ? std::pair(s, b) : std::pair(b, s);
|
||||||
u32 imm = gpr.Imm32(i);
|
u32 imm = gpr.Imm32(i);
|
||||||
@ -756,53 +734,46 @@ void Jit64::boolX(UGeckoInstruction inst)
|
|||||||
}
|
}
|
||||||
else if (is_and)
|
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
|
else
|
||||||
{
|
{
|
||||||
RCOpArg Rj = gpr.Use(j, RCMode::Read);
|
if (a == j)
|
||||||
RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
|
|
||||||
RegCache::Realize(Rj, Ra);
|
|
||||||
|
|
||||||
if (imm == 0xFFFFFFFF)
|
|
||||||
{
|
{
|
||||||
if (a != j)
|
AND(32, Ra, Imm32(imm));
|
||||||
MOV(32, Ra, Rj);
|
|
||||||
if (final_not || complement_b)
|
|
||||||
NOT(32, Ra);
|
|
||||||
needs_test = true;
|
|
||||||
}
|
}
|
||||||
else if (complement_b)
|
else if (s32(imm) >= -128 && s32(imm) <= 127)
|
||||||
{
|
{
|
||||||
if (a != j)
|
MOV(32, Ra, Rj);
|
||||||
MOV(32, Ra, Rj);
|
|
||||||
NOT(32, Ra);
|
|
||||||
AND(32, Ra, Imm32(imm));
|
AND(32, Ra, Imm32(imm));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (a == j)
|
MOV(32, Ra, Imm32(imm));
|
||||||
{
|
AND(32, Ra, Rj);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (final_not)
|
if (final_not)
|
||||||
{
|
{
|
||||||
NOT(32, Ra);
|
NOT(32, Ra);
|
||||||
needs_test = true;
|
needs_test = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -231,29 +231,7 @@ void JitArm64::boolX(UGeckoInstruction inst)
|
|||||||
JITDISABLE(bJITIntegerOff);
|
JITDISABLE(bJITIntegerOff);
|
||||||
int a = inst.RA, s = inst.RS, b = inst.RB;
|
int a = inst.RA, s = inst.RS, b = inst.RB;
|
||||||
|
|
||||||
if (gpr.IsImm(s) && gpr.IsImm(b))
|
if (s == 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 ((inst.SUBOP10 == 28 /* andx */) || (inst.SUBOP10 == 444 /* orx */))
|
if ((inst.SUBOP10 == 28 /* andx */) || (inst.SUBOP10 == 444 /* orx */))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -36,6 +36,8 @@ ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruc
|
|||||||
case 28: // andi
|
case 28: // andi
|
||||||
case 29: // andis
|
case 29: // andis
|
||||||
return EvaluateBitwiseImm(inst, BitAND);
|
return EvaluateBitwiseImm(inst, BitAND);
|
||||||
|
case 31:
|
||||||
|
return EvaluateTable31(inst);
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -69,6 +71,132 @@ ConstantPropagationResult ConstantPropagation::EvaluateBitwiseImm(UGeckoInstruct
|
|||||||
return ConstantPropagationResult(inst.RA, do_op(m_gpr_values[inst.RS], immediate), is_and);
|
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)
|
void ConstantPropagation::Apply(ConstantPropagationResult result)
|
||||||
{
|
{
|
||||||
if (result.gpr >= 0)
|
if (result.gpr >= 0)
|
||||||
|
|||||||
@ -80,6 +80,10 @@ private:
|
|||||||
ConstantPropagationResult EvaluateAddImm(UGeckoInstruction inst) const;
|
ConstantPropagationResult EvaluateAddImm(UGeckoInstruction inst) const;
|
||||||
ConstantPropagationResult EvaluateBitwiseImm(UGeckoInstruction inst,
|
ConstantPropagationResult EvaluateBitwiseImm(UGeckoInstruction inst,
|
||||||
u32 (*do_op)(u32, u32)) const;
|
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 = [] {
|
static constexpr ConstantPropagationResult DO_NOTHING = [] {
|
||||||
ConstantPropagationResult result;
|
ConstantPropagationResult result;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user