JitArm64: Split addi from arith_imm.
They ARM assembly has different immediate versions for logic and additions, so there is no use in merging those instructions.
This commit is contained in:
parent
961901daae
commit
4478146c80
|
@ -83,6 +83,7 @@ public:
|
||||||
void arith_imm(UGeckoInstruction inst);
|
void arith_imm(UGeckoInstruction inst);
|
||||||
void boolX(UGeckoInstruction inst);
|
void boolX(UGeckoInstruction inst);
|
||||||
void addx(UGeckoInstruction inst);
|
void addx(UGeckoInstruction inst);
|
||||||
|
void addix(UGeckoInstruction inst);
|
||||||
void extsXx(UGeckoInstruction inst);
|
void extsXx(UGeckoInstruction inst);
|
||||||
void cntlzwx(UGeckoInstruction inst);
|
void cntlzwx(UGeckoInstruction inst);
|
||||||
void negx(UGeckoInstruction inst);
|
void negx(UGeckoInstruction inst);
|
||||||
|
@ -249,6 +250,6 @@ private:
|
||||||
void ComputeCarry();
|
void ComputeCarry();
|
||||||
|
|
||||||
typedef u32 (*Operation)(u32, u32);
|
typedef u32 (*Operation)(u32, u32);
|
||||||
void reg_imm(u32 d, u32 a, bool binary, u32 value, Operation do_op, void (ARM64XEmitter::*op)(Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, ArithOption), bool Rc = false);
|
void reg_imm(u32 d, u32 a, u32 value, Operation do_op, void (ARM64XEmitter::*op)(Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, ArithOption), bool Rc = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -77,11 +77,6 @@ void JitArm64::ComputeCarry()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Following static functions are used in conjunction with reg_imm
|
// Following static functions are used in conjunction with reg_imm
|
||||||
static u32 Add(u32 a, u32 b)
|
|
||||||
{
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 Or(u32 a, u32 b)
|
static u32 Or(u32 a, u32 b)
|
||||||
{
|
{
|
||||||
return a | b;
|
return a | b;
|
||||||
|
@ -97,38 +92,24 @@ static u32 Xor(u32 a, u32 b)
|
||||||
return a ^ b;
|
return a ^ b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm64::reg_imm(u32 d, u32 a, bool binary, u32 value, Operation do_op, void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, ARM64Reg, ArithOption), bool Rc)
|
void JitArm64::reg_imm(u32 d, u32 a, u32 value, Operation do_op, void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, ARM64Reg, ArithOption), bool Rc)
|
||||||
{
|
{
|
||||||
if (a || binary)
|
if (gpr.IsImm(a))
|
||||||
{
|
{
|
||||||
if (gpr.IsImm(a))
|
gpr.SetImmediate(d, do_op(gpr.GetImm(a), value));
|
||||||
{
|
|
||||||
gpr.SetImmediate(d, do_op(gpr.GetImm(a), value));
|
|
||||||
if (Rc)
|
|
||||||
ComputeRC(gpr.GetImm(d));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gpr.BindToRegister(d, d == a);
|
|
||||||
ARM64Reg WA = gpr.GetReg();
|
|
||||||
MOVI2R(WA, value);
|
|
||||||
(this->*op)(gpr.R(d), gpr.R(a), WA, ArithOption(WA, ST_LSL, 0));
|
|
||||||
gpr.Unlock(WA);
|
|
||||||
|
|
||||||
if (Rc)
|
|
||||||
ComputeRC(gpr.R(d), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (do_op == Add)
|
|
||||||
{
|
|
||||||
// a == 0, implies zero register
|
|
||||||
gpr.SetImmediate(d, value);
|
|
||||||
if (Rc)
|
if (Rc)
|
||||||
ComputeRC(value, 0);
|
ComputeRC(gpr.GetImm(d));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_assert_msg_(DYNA_REC, false, "Hit impossible condition in reg_imm!");
|
gpr.BindToRegister(d, d == a);
|
||||||
|
ARM64Reg WA = gpr.GetReg();
|
||||||
|
MOVI2R(WA, value);
|
||||||
|
(this->*op)(gpr.R(d), gpr.R(a), WA, ArithOption(WA, ST_LSL, 0));
|
||||||
|
gpr.Unlock(WA);
|
||||||
|
|
||||||
|
if (Rc)
|
||||||
|
ComputeRC(gpr.R(d), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,42 +117,70 @@ void JitArm64::arith_imm(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(bJITIntegerOff);
|
JITDISABLE(bJITIntegerOff);
|
||||||
u32 d = inst.RD, a = inst.RA, s = inst.RS;
|
u32 a = inst.RA, s = inst.RS;
|
||||||
|
|
||||||
switch (inst.OPCD)
|
switch (inst.OPCD)
|
||||||
{
|
{
|
||||||
case 14: // addi
|
|
||||||
reg_imm(d, a, false, (u32)(s32)inst.SIMM_16, Add, &ARM64XEmitter::ADD);
|
|
||||||
break;
|
|
||||||
case 15: // addis
|
|
||||||
reg_imm(d, a, false, (u32)inst.SIMM_16 << 16, Add, &ARM64XEmitter::ADD);
|
|
||||||
break;
|
|
||||||
case 24: // ori
|
case 24: // ori
|
||||||
if (a == 0 && s == 0 && inst.UIMM == 0 && !inst.Rc) //check for nop
|
if (a == 0 && s == 0 && inst.UIMM == 0 && !inst.Rc) //check for nop
|
||||||
{
|
{
|
||||||
// NOP
|
// NOP
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reg_imm(a, s, true, inst.UIMM, Or, &ARM64XEmitter::ORR);
|
reg_imm(a, s, inst.UIMM, Or, &ARM64XEmitter::ORR);
|
||||||
break;
|
break;
|
||||||
case 25: // oris
|
case 25: // oris
|
||||||
reg_imm(a, s, true, inst.UIMM << 16, Or, &ARM64XEmitter::ORR);
|
reg_imm(a, s, inst.UIMM << 16, Or, &ARM64XEmitter::ORR);
|
||||||
break;
|
break;
|
||||||
case 28: // andi
|
case 28: // andi
|
||||||
reg_imm(a, s, true, inst.UIMM, And, &ARM64XEmitter::AND, true);
|
reg_imm(a, s, inst.UIMM, And, &ARM64XEmitter::AND, true);
|
||||||
break;
|
break;
|
||||||
case 29: // andis
|
case 29: // andis
|
||||||
reg_imm(a, s, true, inst.UIMM << 16, And, &ARM64XEmitter::AND, true);
|
reg_imm(a, s, inst.UIMM << 16, And, &ARM64XEmitter::AND, true);
|
||||||
break;
|
break;
|
||||||
case 26: // xori
|
case 26: // xori
|
||||||
reg_imm(a, s, true, inst.UIMM, Xor, &ARM64XEmitter::EOR);
|
reg_imm(a, s, inst.UIMM, Xor, &ARM64XEmitter::EOR);
|
||||||
break;
|
break;
|
||||||
case 27: // xoris
|
case 27: // xoris
|
||||||
reg_imm(a, s, true, inst.UIMM << 16, Xor, &ARM64XEmitter::EOR);
|
reg_imm(a, s, inst.UIMM << 16, Xor, &ARM64XEmitter::EOR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm64::addix(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITIntegerOff);
|
||||||
|
u32 d = inst.RD, a = inst.RA;
|
||||||
|
|
||||||
|
u32 value = (u32)(s32)inst.SIMM_16;
|
||||||
|
|
||||||
|
if (inst.OPCD == 15)
|
||||||
|
value <<= 16;
|
||||||
|
|
||||||
|
if (a)
|
||||||
|
{
|
||||||
|
if (gpr.IsImm(a))
|
||||||
|
{
|
||||||
|
gpr.SetImmediate(d, gpr.GetImm(a) + value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpr.BindToRegister(d, d == a);
|
||||||
|
|
||||||
|
ARM64Reg WA = gpr.GetReg();
|
||||||
|
MOVI2R(WA, value);
|
||||||
|
ADD(gpr.R(d), gpr.R(a), WA);
|
||||||
|
gpr.Unlock(WA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// a == 0, implies zero register
|
||||||
|
gpr.SetImmediate(d, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void JitArm64::boolX(UGeckoInstruction inst)
|
void JitArm64::boolX(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
|
|
@ -49,8 +49,8 @@ static GekkoOPTemplate primarytable[] =
|
||||||
{11, &JitArm64::cmpi}, // cmpi
|
{11, &JitArm64::cmpi}, // cmpi
|
||||||
{12, &JitArm64::addic}, // addic
|
{12, &JitArm64::addic}, // addic
|
||||||
{13, &JitArm64::addic}, // addic_rc
|
{13, &JitArm64::addic}, // addic_rc
|
||||||
{14, &JitArm64::arith_imm}, // addi
|
{14, &JitArm64::addix}, // addi
|
||||||
{15, &JitArm64::arith_imm}, // addis
|
{15, &JitArm64::addix}, // addis
|
||||||
|
|
||||||
{20, &JitArm64::rlwimix}, // rlwimix
|
{20, &JitArm64::rlwimix}, // rlwimix
|
||||||
{21, &JitArm64::rlwinmx}, // rlwinmx
|
{21, &JitArm64::rlwinmx}, // rlwinmx
|
||||||
|
|
Loading…
Reference in New Issue