Jit: Move addx to ConstantPropagation

This commit is contained in:
JosJuice 2023-08-24 13:16:08 +02:00
parent 8a5cbe696f
commit b833ddc2b6
6 changed files with 75 additions and 52 deletions

View File

@ -1109,7 +1109,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
else
{
const JitCommon::ConstantPropagationResult constant_propagation_result =
m_constant_propagation.EvaluateInstruction(op.inst);
m_constant_propagation.EvaluateInstruction(op.inst, opinfo->flags);
if (!constant_propagation_result.instruction_fully_executed)
{

View File

@ -1826,16 +1826,7 @@ void Jit64::addx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD;
bool carry = !(inst.SUBOP10 & (1 << 8));
if (gpr.IsImm(a, b))
{
const s32 i = gpr.SImm32(a), j = gpr.SImm32(b);
gpr.SetImmediate32(d, i + j);
if (carry)
FinalizeCarry(Interpreter::Helper_Carry(i, j));
if (inst.OE)
GenerateConstantOverflow((s64)i + (s64)j);
}
else if (gpr.IsImm(a) || gpr.IsImm(b))
if (gpr.IsImm(a) || gpr.IsImm(b))
{
const auto [i, j] = gpr.IsImm(a) ? std::pair(a, b) : std::pair(b, a);
const s32 imm = gpr.SImm32(i);

View File

@ -1348,7 +1348,7 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
else
{
const JitCommon::ConstantPropagationResult constant_propagation_result =
m_constant_propagation.EvaluateInstruction(op.inst);
m_constant_propagation.EvaluateInstruction(op.inst, opinfo->flags);
if (!constant_propagation_result.instruction_fully_executed)
{

View File

@ -480,14 +480,7 @@ void JitArm64::addx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD;
if (gpr.IsImm(a) && gpr.IsImm(b))
{
s32 i = (s32)gpr.GetImm(a), j = (s32)gpr.GetImm(b);
gpr.SetImmediate(d, i + j);
if (inst.Rc)
ComputeRC0(gpr.GetImm(d));
}
else if (gpr.IsImm(a) || gpr.IsImm(b))
if (gpr.IsImm(a) || gpr.IsImm(b))
{
int imm_reg = gpr.IsImm(a) ? a : b;
int in_reg = gpr.IsImm(a) ? b : a;
@ -1478,18 +1471,6 @@ void JitArm64::addcx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD;
if (gpr.IsImm(a) && gpr.IsImm(b))
{
u32 i = gpr.GetImm(a), j = gpr.GetImm(b);
gpr.SetImmediate(d, i + j);
bool has_carry = Interpreter::Helper_Carry(i, j);
ComputeCarry(has_carry);
if (inst.Rc)
ComputeRC0(gpr.GetImm(d));
}
else
{
gpr.BindToRegister(d, d == a || d == b);
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
@ -1497,7 +1478,6 @@ void JitArm64::addcx(UGeckoInstruction inst)
if (inst.Rc)
ComputeRC0(gpr.R(d));
}
}
void JitArm64::divwux(UGeckoInstruction inst)
{

View File

@ -3,6 +3,8 @@
#include "Core/PowerPC/JitCommon/ConstantPropagation.h"
#include "Core/PowerPC/PPCTables.h"
namespace JitCommon
{
static constexpr u32 BitOR(u32 a, u32 b)
@ -20,7 +22,8 @@ static constexpr u32 BitXOR(u32 a, u32 b)
return a ^ b;
}
ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruction inst) const
ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruction inst,
u64 flags) const
{
switch (inst.OPCD)
{
@ -37,7 +40,7 @@ ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruc
case 29: // andis
return EvaluateBitwiseImm(inst, BitAND);
case 31:
return EvaluateTable31(inst);
return EvaluateTable31(inst, flags);
default:
return {};
}
@ -71,18 +74,65 @@ ConstantPropagationResult ConstantPropagation::EvaluateBitwiseImm(UGeckoInstruct
return ConstantPropagationResult(inst.RA, do_op(m_gpr_values[inst.RS], immediate), is_and);
}
ConstantPropagationResult ConstantPropagation::EvaluateTable31(UGeckoInstruction inst) const
ConstantPropagationResult ConstantPropagation::EvaluateTable31(UGeckoInstruction inst,
u64 flags) const
{
if (flags & FL_OUT_D)
{
// input a, b -> output d
return EvaluateTable31AB(inst, flags);
}
else
{
// input s, b -> output a
return EvaluateTable31SB(inst);
}
}
ConstantPropagationResult ConstantPropagation::EvaluateTable31AB(UGeckoInstruction inst,
u64 flags) const
{
if (!HasGPR(inst.RA, inst.RB))
return {};
u64 d;
s64 d_overflow;
const u32 a = GetGPR(inst.RA);
const u32 b = GetGPR(inst.RB);
switch (inst.SUBOP10)
{
case 10: // addcx
case 522: // addcox
case 266: // addx
case 778: // addox
d = u64(a) + u64(b);
d_overflow = s64(s32(a)) + s64(s32(b));
break;
default:
return {};
}
ConstantPropagationResult result(inst.RD, u32(d), inst.Rc);
if (flags & FL_SET_CA)
result.carry = (d >> 32 != 0);
if (flags & FL_SET_OE)
result.overflow = (d_overflow != s64(s32(d_overflow)));
return result;
}
ConstantPropagationResult ConstantPropagation::EvaluateTable31SB(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);
return EvaluateTable31SBOneRegisterKnown(inst, GetGPR(inst.RS), false);
else if (has_b)
return EvaluateTable31OneRegisterKnown(inst, GetGPR(inst.RB), true);
return EvaluateTable31SBOneRegisterKnown(inst, GetGPR(inst.RB), true);
else if (inst.RS == inst.RB)
return EvaluateTable31IdenticalRegisters(inst);
return EvaluateTable31SBIdenticalRegisters(inst);
else
return {};
}
@ -125,7 +175,7 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31(UGeckoInstruction
}
ConstantPropagationResult
ConstantPropagation::EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32 value,
ConstantPropagation::EvaluateTable31SBOneRegisterKnown(UGeckoInstruction inst, u32 value,
bool known_reg_is_b) const
{
u32 a;
@ -172,7 +222,7 @@ ConstantPropagation::EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32
}
ConstantPropagationResult
ConstantPropagation::EvaluateTable31IdenticalRegisters(UGeckoInstruction inst) const
ConstantPropagation::EvaluateTable31SBIdenticalRegisters(UGeckoInstruction inst) const
{
u32 a;

View File

@ -46,7 +46,7 @@ struct ConstantPropagationResult final
class ConstantPropagation final
{
public:
ConstantPropagationResult EvaluateInstruction(UGeckoInstruction inst) const;
ConstantPropagationResult EvaluateInstruction(UGeckoInstruction inst, u64 flags) const;
void Apply(ConstantPropagationResult result);
@ -80,10 +80,12 @@ 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,
ConstantPropagationResult EvaluateTable31(UGeckoInstruction inst, u64 flags) const;
ConstantPropagationResult EvaluateTable31AB(UGeckoInstruction inst, u64 flags) const;
ConstantPropagationResult EvaluateTable31SB(UGeckoInstruction inst) const;
ConstantPropagationResult EvaluateTable31SBOneRegisterKnown(UGeckoInstruction inst, u32 value,
bool known_reg_is_b) const;
ConstantPropagationResult EvaluateTable31IdenticalRegisters(UGeckoInstruction inst) const;
ConstantPropagationResult EvaluateTable31SBIdenticalRegisters(UGeckoInstruction inst) const;
static constexpr ConstantPropagationResult DO_NOTHING = [] {
ConstantPropagationResult result;