mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-03 11:32:43 +01:00
Jit: Move addx to ConstantPropagation
This commit is contained in:
parent
8a5cbe696f
commit
b833ddc2b6
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,25 +1471,12 @@ 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);
|
||||
gpr.BindToRegister(d, d == a || d == b);
|
||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
|
||||
|
||||
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));
|
||||
|
||||
ComputeCarry();
|
||||
if (inst.Rc)
|
||||
ComputeRC0(gpr.R(d));
|
||||
}
|
||||
ComputeCarry();
|
||||
if (inst.Rc)
|
||||
ComputeRC0(gpr.R(d));
|
||||
}
|
||||
|
||||
void JitArm64::divwux(UGeckoInstruction inst)
|
||||
|
@ -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,8 +175,8 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31(UGeckoInstruction
|
||||
}
|
||||
|
||||
ConstantPropagationResult
|
||||
ConstantPropagation::EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32 value,
|
||||
bool known_reg_is_b) const
|
||||
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;
|
||||
|
||||
|
@ -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,
|
||||
bool known_reg_is_b) const;
|
||||
ConstantPropagationResult EvaluateTable31IdenticalRegisters(UGeckoInstruction inst) const;
|
||||
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 EvaluateTable31SBIdenticalRegisters(UGeckoInstruction inst) const;
|
||||
|
||||
static constexpr ConstantPropagationResult DO_NOTHING = [] {
|
||||
ConstantPropagationResult result;
|
||||
|
Loading…
x
Reference in New Issue
Block a user