JitArm64: Optimize logic immediate instructions.

Try to use also the immediate instruction on ARM.
This commit is contained in:
degasus
2016-09-11 11:15:50 +02:00
parent e7aad130e9
commit 1f94abea18
2 changed files with 12 additions and 32 deletions

View File

@ -238,9 +238,6 @@ private:
void ComputeCarry(bool Carry); void ComputeCarry(bool Carry);
void ComputeCarry(); void ComputeCarry();
typedef u32 (*Operation)(u32, u32); void reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
void reg_imm(u32 d, u32 a, u32 value, Operation do_op, void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, u64, ARM64Reg), bool Rc = false);
void (ARM64XEmitter::*op)(Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg,
ArithOption),
bool Rc = false);
}; };

View File

@ -75,25 +75,8 @@ void JitArm64::ComputeCarry()
gpr.Unlock(WA); gpr.Unlock(WA);
} }
// Following static functions are used in conjunction with reg_imm void JitArm64::reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
static u32 Or(u32 a, u32 b) void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, u64, ARM64Reg), bool Rc)
{
return a | b;
}
static u32 And(u32 a, u32 b)
{
return a & b;
}
static u32 Xor(u32 a, u32 b)
{
return a ^ b;
}
void JitArm64::reg_imm(u32 d, u32 a, u32 value, Operation do_op,
void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, ARM64Reg, ArithOption),
bool Rc)
{ {
if (gpr.IsImm(a)) if (gpr.IsImm(a))
{ {
@ -105,8 +88,7 @@ void JitArm64::reg_imm(u32 d, u32 a, u32 value, Operation do_op,
{ {
gpr.BindToRegister(d, d == a); gpr.BindToRegister(d, d == a);
ARM64Reg WA = gpr.GetReg(); ARM64Reg WA = gpr.GetReg();
MOVI2R(WA, value); (this->*op)(gpr.R(d), gpr.R(a), value, WA);
(this->*op)(gpr.R(d), gpr.R(a), WA, ArithOption(WA, ST_LSL, 0));
gpr.Unlock(WA); gpr.Unlock(WA);
if (Rc) if (Rc)
@ -128,22 +110,23 @@ void JitArm64::arith_imm(UGeckoInstruction inst)
// NOP // NOP
return; return;
} }
reg_imm(a, s, inst.UIMM, Or, &ARM64XEmitter::ORR); reg_imm(a, s, inst.UIMM, [](u32 a, u32 b) { return a | b; }, &ARM64XEmitter::ORRI2R);
break; break;
case 25: // oris case 25: // oris
reg_imm(a, s, inst.UIMM << 16, Or, &ARM64XEmitter::ORR); reg_imm(a, s, inst.UIMM << 16, [](u32 a, u32 b) { return a | b; }, &ARM64XEmitter::ORRI2R);
break; break;
case 28: // andi case 28: // andi
reg_imm(a, s, inst.UIMM, And, &ARM64XEmitter::AND, true); reg_imm(a, s, inst.UIMM, [](u32 a, u32 b) { return a & b; }, &ARM64XEmitter::ANDI2R, true);
break; break;
case 29: // andis case 29: // andis
reg_imm(a, s, inst.UIMM << 16, And, &ARM64XEmitter::AND, true); reg_imm(a, s, inst.UIMM << 16, [](u32 a, u32 b) { return a & b; }, &ARM64XEmitter::ANDI2R,
true);
break; break;
case 26: // xori case 26: // xori
reg_imm(a, s, inst.UIMM, Xor, &ARM64XEmitter::EOR); reg_imm(a, s, inst.UIMM, [](u32 a, u32 b) { return a ^ b; }, &ARM64XEmitter::EORI2R);
break; break;
case 27: // xoris case 27: // xoris
reg_imm(a, s, inst.UIMM << 16, Xor, &ARM64XEmitter::EOR); reg_imm(a, s, inst.UIMM << 16, [](u32 a, u32 b) { return a ^ b; }, &ARM64XEmitter::EORI2R);
break; break;
} }
} }