mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-09 14:08:58 +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
|
else
|
||||||
{
|
{
|
||||||
const JitCommon::ConstantPropagationResult constant_propagation_result =
|
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)
|
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;
|
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||||
bool carry = !(inst.SUBOP10 & (1 << 8));
|
bool carry = !(inst.SUBOP10 & (1 << 8));
|
||||||
|
|
||||||
if (gpr.IsImm(a, b))
|
if (gpr.IsImm(a) || gpr.IsImm(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))
|
|
||||||
{
|
{
|
||||||
const auto [i, j] = gpr.IsImm(a) ? std::pair(a, b) : std::pair(b, a);
|
const auto [i, j] = gpr.IsImm(a) ? std::pair(a, b) : std::pair(b, a);
|
||||||
const s32 imm = gpr.SImm32(i);
|
const s32 imm = gpr.SImm32(i);
|
||||||
|
@ -1348,7 +1348,7 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
const JitCommon::ConstantPropagationResult constant_propagation_result =
|
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)
|
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;
|
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||||
|
|
||||||
if (gpr.IsImm(a) && gpr.IsImm(b))
|
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))
|
|
||||||
{
|
{
|
||||||
int imm_reg = gpr.IsImm(a) ? a : b;
|
int imm_reg = gpr.IsImm(a) ? a : b;
|
||||||
int in_reg = gpr.IsImm(a) ? b : a;
|
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;
|
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||||
|
|
||||||
if (gpr.IsImm(a) && gpr.IsImm(b))
|
gpr.BindToRegister(d, d == a || d == b);
|
||||||
{
|
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
|
||||||
u32 i = gpr.GetImm(a), j = gpr.GetImm(b);
|
|
||||||
gpr.SetImmediate(d, i + j);
|
|
||||||
|
|
||||||
bool has_carry = Interpreter::Helper_Carry(i, j);
|
ComputeCarry();
|
||||||
ComputeCarry(has_carry);
|
if (inst.Rc)
|
||||||
if (inst.Rc)
|
ComputeRC0(gpr.R(d));
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::divwux(UGeckoInstruction inst)
|
void JitArm64::divwux(UGeckoInstruction inst)
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "Core/PowerPC/JitCommon/ConstantPropagation.h"
|
#include "Core/PowerPC/JitCommon/ConstantPropagation.h"
|
||||||
|
|
||||||
|
#include "Core/PowerPC/PPCTables.h"
|
||||||
|
|
||||||
namespace JitCommon
|
namespace JitCommon
|
||||||
{
|
{
|
||||||
static constexpr u32 BitOR(u32 a, u32 b)
|
static constexpr u32 BitOR(u32 a, u32 b)
|
||||||
@ -20,7 +22,8 @@ static constexpr u32 BitXOR(u32 a, u32 b)
|
|||||||
return a ^ b;
|
return a ^ b;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruction inst) const
|
ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruction inst,
|
||||||
|
u64 flags) const
|
||||||
{
|
{
|
||||||
switch (inst.OPCD)
|
switch (inst.OPCD)
|
||||||
{
|
{
|
||||||
@ -37,7 +40,7 @@ ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruc
|
|||||||
case 29: // andis
|
case 29: // andis
|
||||||
return EvaluateBitwiseImm(inst, BitAND);
|
return EvaluateBitwiseImm(inst, BitAND);
|
||||||
case 31:
|
case 31:
|
||||||
return EvaluateTable31(inst);
|
return EvaluateTable31(inst, flags);
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -71,18 +74,65 @@ 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
|
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_s = HasGPR(inst.RS);
|
||||||
const bool has_b = HasGPR(inst.RB);
|
const bool has_b = HasGPR(inst.RB);
|
||||||
if (!has_s || !has_b)
|
if (!has_s || !has_b)
|
||||||
{
|
{
|
||||||
if (has_s)
|
if (has_s)
|
||||||
return EvaluateTable31OneRegisterKnown(inst, GetGPR(inst.RS), false);
|
return EvaluateTable31SBOneRegisterKnown(inst, GetGPR(inst.RS), false);
|
||||||
else if (has_b)
|
else if (has_b)
|
||||||
return EvaluateTable31OneRegisterKnown(inst, GetGPR(inst.RB), true);
|
return EvaluateTable31SBOneRegisterKnown(inst, GetGPR(inst.RB), true);
|
||||||
else if (inst.RS == inst.RB)
|
else if (inst.RS == inst.RB)
|
||||||
return EvaluateTable31IdenticalRegisters(inst);
|
return EvaluateTable31SBIdenticalRegisters(inst);
|
||||||
else
|
else
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -125,8 +175,8 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31(UGeckoInstruction
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConstantPropagationResult
|
ConstantPropagationResult
|
||||||
ConstantPropagation::EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32 value,
|
ConstantPropagation::EvaluateTable31SBOneRegisterKnown(UGeckoInstruction inst, u32 value,
|
||||||
bool known_reg_is_b) const
|
bool known_reg_is_b) const
|
||||||
{
|
{
|
||||||
u32 a;
|
u32 a;
|
||||||
|
|
||||||
@ -172,7 +222,7 @@ ConstantPropagation::EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConstantPropagationResult
|
ConstantPropagationResult
|
||||||
ConstantPropagation::EvaluateTable31IdenticalRegisters(UGeckoInstruction inst) const
|
ConstantPropagation::EvaluateTable31SBIdenticalRegisters(UGeckoInstruction inst) const
|
||||||
{
|
{
|
||||||
u32 a;
|
u32 a;
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ struct ConstantPropagationResult final
|
|||||||
class ConstantPropagation final
|
class ConstantPropagation final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConstantPropagationResult EvaluateInstruction(UGeckoInstruction inst) const;
|
ConstantPropagationResult EvaluateInstruction(UGeckoInstruction inst, u64 flags) const;
|
||||||
|
|
||||||
void Apply(ConstantPropagationResult result);
|
void Apply(ConstantPropagationResult result);
|
||||||
|
|
||||||
@ -80,10 +80,12 @@ 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 EvaluateTable31(UGeckoInstruction inst, u64 flags) const;
|
||||||
ConstantPropagationResult EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32 value,
|
ConstantPropagationResult EvaluateTable31AB(UGeckoInstruction inst, u64 flags) const;
|
||||||
bool known_reg_is_b) const;
|
ConstantPropagationResult EvaluateTable31SB(UGeckoInstruction inst) const;
|
||||||
ConstantPropagationResult EvaluateTable31IdenticalRegisters(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 = [] {
|
static constexpr ConstantPropagationResult DO_NOTHING = [] {
|
||||||
ConstantPropagationResult result;
|
ConstantPropagationResult result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user