mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-03 11:32:43 +01:00
Jit: Move reg_imm to ConstantPropagation
This commit is contained in:
parent
96876044a6
commit
90c89ce533
@ -327,14 +327,6 @@ void Jit64::reg_imm(UGeckoInstruction inst)
|
||||
case 24: // ori
|
||||
case 25: // oris
|
||||
{
|
||||
// check for nop
|
||||
if (a == s && inst.UIMM == 0)
|
||||
{
|
||||
// Make the nop visible in the generated code. not much use but interesting if we see one.
|
||||
NOP();
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 immediate = inst.OPCD == 24 ? inst.UIMM : inst.UIMM << 16;
|
||||
regimmop(a, s, true, immediate, Or, &XEmitter::OR);
|
||||
break;
|
||||
@ -348,13 +340,6 @@ void Jit64::reg_imm(UGeckoInstruction inst)
|
||||
case 26: // xori
|
||||
case 27: // xoris
|
||||
{
|
||||
if (s == a && inst.UIMM == 0)
|
||||
{
|
||||
// Make the nop visible in the generated code.
|
||||
NOP();
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 immediate = inst.OPCD == 26 ? inst.UIMM : inst.UIMM << 16;
|
||||
regimmop(a, s, true, immediate, Xor, &XEmitter::XOR, false);
|
||||
break;
|
||||
|
@ -370,7 +370,7 @@ protected:
|
||||
void LoadCarry();
|
||||
void FlushCarry();
|
||||
|
||||
void reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
|
||||
void reg_imm(u32 d, u32 a, u32 value,
|
||||
void (ARM64XEmitter::*op)(Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, u64,
|
||||
Arm64Gen::ARM64Reg),
|
||||
bool Rc = false);
|
||||
|
@ -159,41 +159,17 @@ void JitArm64::FlushCarry()
|
||||
js.carryFlag = CarryFlag::InPPCState;
|
||||
}
|
||||
|
||||
void JitArm64::reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
|
||||
void JitArm64::reg_imm(u32 d, u32 a, u32 value,
|
||||
void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, u64, ARM64Reg), bool Rc)
|
||||
{
|
||||
if (gpr.IsImm(a))
|
||||
gpr.BindToRegister(d, d == a);
|
||||
{
|
||||
gpr.SetImmediate(d, do_op(gpr.GetImm(a), value));
|
||||
if (Rc)
|
||||
ComputeRC0(gpr.GetImm(d));
|
||||
auto WA = gpr.GetScopedReg();
|
||||
(this->*op)(gpr.R(d), gpr.R(a), value, WA);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpr.BindToRegister(d, d == a);
|
||||
{
|
||||
auto WA = gpr.GetScopedReg();
|
||||
(this->*op)(gpr.R(d), gpr.R(a), value, WA);
|
||||
}
|
||||
|
||||
if (Rc)
|
||||
ComputeRC0(gpr.R(d));
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr u32 BitOR(u32 a, u32 b)
|
||||
{
|
||||
return a | b;
|
||||
}
|
||||
|
||||
static constexpr u32 BitAND(u32 a, u32 b)
|
||||
{
|
||||
return a & b;
|
||||
}
|
||||
|
||||
static constexpr u32 BitXOR(u32 a, u32 b)
|
||||
{
|
||||
return a ^ b;
|
||||
if (Rc)
|
||||
ComputeRC0(gpr.R(d));
|
||||
}
|
||||
|
||||
void JitArm64::arith_imm(UGeckoInstruction inst)
|
||||
@ -207,34 +183,21 @@ void JitArm64::arith_imm(UGeckoInstruction inst)
|
||||
case 24: // ori
|
||||
case 25: // oris
|
||||
{
|
||||
// check for nop
|
||||
if (a == s && inst.UIMM == 0)
|
||||
{
|
||||
// NOP
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 immediate = inst.OPCD == 24 ? inst.UIMM : inst.UIMM << 16;
|
||||
reg_imm(a, s, immediate, BitOR, &ARM64XEmitter::ORRI2R);
|
||||
reg_imm(a, s, immediate, &ARM64XEmitter::ORRI2R);
|
||||
break;
|
||||
}
|
||||
case 28: // andi
|
||||
reg_imm(a, s, inst.UIMM, BitAND, &ARM64XEmitter::ANDI2R, true);
|
||||
reg_imm(a, s, inst.UIMM, &ARM64XEmitter::ANDI2R, true);
|
||||
break;
|
||||
case 29: // andis
|
||||
reg_imm(a, s, inst.UIMM << 16, BitAND, &ARM64XEmitter::ANDI2R, true);
|
||||
reg_imm(a, s, inst.UIMM << 16, &ARM64XEmitter::ANDI2R, true);
|
||||
break;
|
||||
case 26: // xori
|
||||
case 27: // xoris
|
||||
{
|
||||
if (a == s && inst.UIMM == 0)
|
||||
{
|
||||
// NOP
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 immediate = inst.OPCD == 26 ? inst.UIMM : inst.UIMM << 16;
|
||||
reg_imm(a, s, immediate, BitXOR, &ARM64XEmitter::EORI2R);
|
||||
reg_imm(a, s, immediate, &ARM64XEmitter::EORI2R);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,52 @@
|
||||
|
||||
namespace JitCommon
|
||||
{
|
||||
static constexpr u32 BitOR(u32 a, u32 b)
|
||||
{
|
||||
return a | b;
|
||||
}
|
||||
|
||||
static constexpr u32 BitAND(u32 a, u32 b)
|
||||
{
|
||||
return a & b;
|
||||
}
|
||||
|
||||
static constexpr u32 BitXOR(u32 a, u32 b)
|
||||
{
|
||||
return a ^ b;
|
||||
}
|
||||
|
||||
ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruction inst) const
|
||||
{
|
||||
return {};
|
||||
switch (inst.OPCD)
|
||||
{
|
||||
case 24: // ori
|
||||
case 25: // oris
|
||||
return EvaluateBitwiseImm(inst, BitOR);
|
||||
case 26: // xori
|
||||
case 27: // xoris
|
||||
return EvaluateBitwiseImm(inst, BitXOR);
|
||||
case 28: // andi
|
||||
case 29: // andis
|
||||
return EvaluateBitwiseImm(inst, BitAND);
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
ConstantPropagationResult ConstantPropagation::EvaluateBitwiseImm(UGeckoInstruction inst,
|
||||
u32 (*do_op)(u32, u32)) const
|
||||
{
|
||||
const bool is_and = do_op == &BitAND;
|
||||
const u32 immediate = inst.OPCD & 1 ? inst.UIMM << 16 : inst.UIMM;
|
||||
|
||||
if (inst.UIMM == 0 && !is_and && inst.RA == inst.RS)
|
||||
return DO_NOTHING;
|
||||
|
||||
if (!HasGPR(inst.RS))
|
||||
return {};
|
||||
|
||||
return ConstantPropagationResult(inst.RA, do_op(m_gpr_values[inst.RS], immediate), is_and);
|
||||
}
|
||||
|
||||
void ConstantPropagation::Apply(ConstantPropagationResult result)
|
||||
|
@ -77,6 +77,15 @@ public:
|
||||
void Clear() { m_gpr_values_known = BitSet32{}; }
|
||||
|
||||
private:
|
||||
ConstantPropagationResult EvaluateBitwiseImm(UGeckoInstruction inst,
|
||||
u32 (*do_op)(u32, u32)) const;
|
||||
|
||||
static constexpr ConstantPropagationResult DO_NOTHING = [] {
|
||||
ConstantPropagationResult result;
|
||||
result.instruction_fully_executed = true;
|
||||
return result;
|
||||
}();
|
||||
|
||||
static constexpr size_t GPR_COUNT = 32;
|
||||
|
||||
std::array<u32, GPR_COUNT> m_gpr_values;
|
||||
|
Loading…
x
Reference in New Issue
Block a user