[ARM] Merge a bunch of arithmetic JIT instructions and rapid prototyping of a bunch more.
This commit is contained in:
parent
1b1cc82e5b
commit
a7f3264fed
|
@ -119,6 +119,7 @@ public:
|
|||
void ComputeRC(s32 value, int cr);
|
||||
|
||||
void ComputeCarry();
|
||||
void ComputeCarry(bool Carry);
|
||||
void GetCarryAndClear(ARMReg reg);
|
||||
void FinalizeCarry(ARMReg reg);
|
||||
|
||||
|
@ -149,29 +150,17 @@ public:
|
|||
void bcctrx(UGeckoInstruction _inst);
|
||||
|
||||
// Integer
|
||||
void addi(UGeckoInstruction _inst);
|
||||
void addis(UGeckoInstruction _inst);
|
||||
void addx(UGeckoInstruction _inst);
|
||||
void addcx(UGeckoInstruction _inst);
|
||||
void arith(UGeckoInstruction _inst);
|
||||
|
||||
void addex(UGeckoInstruction _inst);
|
||||
void cmp (UGeckoInstruction _inst);
|
||||
void cmpi(UGeckoInstruction _inst);
|
||||
void cmpl(UGeckoInstruction _inst);
|
||||
void cmpli(UGeckoInstruction _inst);
|
||||
void negx(UGeckoInstruction _inst);
|
||||
void mulli(UGeckoInstruction _inst);
|
||||
void mullwx(UGeckoInstruction _inst);
|
||||
void mulhwux(UGeckoInstruction _inst);
|
||||
void ori(UGeckoInstruction _inst);
|
||||
void oris(UGeckoInstruction _inst);
|
||||
void orx(UGeckoInstruction _inst);
|
||||
void xorx(UGeckoInstruction _inst);
|
||||
void andx(UGeckoInstruction _inst);
|
||||
void andi_rc(UGeckoInstruction _inst);
|
||||
void andis_rc(UGeckoInstruction _inst);
|
||||
void rlwimix(UGeckoInstruction _inst);
|
||||
void rlwinmx(UGeckoInstruction _inst);
|
||||
void subfx(UGeckoInstruction _inst);
|
||||
void srawix(UGeckoInstruction _inst);
|
||||
void extshx(UGeckoInstruction inst);
|
||||
void extsbx(UGeckoInstruction inst);
|
||||
|
|
|
@ -81,6 +81,19 @@ void JitArm::ComputeCarry()
|
|||
STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
|
||||
gpr.Unlock(tmp);
|
||||
}
|
||||
void JitArm::ComputeCarry(bool Carry)
|
||||
{
|
||||
ARMReg tmp = gpr.GetReg();
|
||||
Operand2 mask = Operand2(2, 2); // XER_CA_MASK
|
||||
LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
|
||||
if (Carry)
|
||||
ORR(tmp, tmp, mask);
|
||||
else
|
||||
BIC(tmp, tmp, mask);
|
||||
STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
|
||||
gpr.Unlock(tmp);
|
||||
|
||||
}
|
||||
|
||||
void JitArm::GetCarryAndClear(ARMReg reg)
|
||||
{
|
||||
|
@ -106,82 +119,401 @@ void JitArm::FinalizeCarry(ARMReg reg)
|
|||
gpr.Unlock(tmp);
|
||||
}
|
||||
|
||||
void JitArm::addi(UGeckoInstruction inst)
|
||||
u32 Add(u32 a, u32 b) {return a + b;}
|
||||
u32 Sub(u32 a, u32 b) {return a - b;}
|
||||
u32 Mul(u32 a, u32 b) {return a * b;}
|
||||
u32 Or (u32 a, u32 b) {return a | b;}
|
||||
u32 And(u32 a, u32 b) {return a & b;}
|
||||
u32 Xor(u32 a, u32 b) {return a ^ b;}
|
||||
|
||||
void JitArm::arith(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
|
||||
u32 d = inst.RD, a = inst.RA;
|
||||
u32 a = inst.RA, b = inst.RB, d = inst.RD, s = inst.RS;
|
||||
ARMReg RA, RB, RD, RS;
|
||||
bool isImm[2] = {false, false}; // Arg1 & Arg2
|
||||
u32 Imm[2] = {0, 0};
|
||||
bool Rc = false;
|
||||
bool carry = false;
|
||||
bool isUnsigned = false;
|
||||
bool shiftedImm = false;
|
||||
// printf("inst %s has OPCD %d subop10 %d\n", PPCTables::GetInstructionName(inst), inst.OPCD, inst.SUBOP10);
|
||||
|
||||
switch (inst.OPCD)
|
||||
{
|
||||
case 7: // mulli
|
||||
if (gpr.IsImm(a))
|
||||
{
|
||||
isImm[0] = true;
|
||||
Imm[0] = gpr.GetImm(a);
|
||||
}
|
||||
isImm[1] = true;
|
||||
Imm[1] = inst.SIMM_16;
|
||||
break;
|
||||
case 13: // addic_rc
|
||||
Rc = true;
|
||||
case 12: // addic
|
||||
if (gpr.IsImm(a))
|
||||
{
|
||||
isImm[0] = true;
|
||||
Imm[0] = gpr.GetImm(a);
|
||||
}
|
||||
isImm[1] = true;
|
||||
Imm[1] = inst.SIMM_16;
|
||||
carry = true;
|
||||
break;
|
||||
case 15: // addis
|
||||
shiftedImm = true;
|
||||
case 14: // addi
|
||||
if (a)
|
||||
{
|
||||
if (gpr.IsImm(a))
|
||||
{
|
||||
gpr.SetImmediate(d, gpr.GetImm(a) + inst.SIMM_16);
|
||||
return;
|
||||
isImm[0] = true;
|
||||
Imm[0] = gpr.GetImm(a);
|
||||
}
|
||||
ARMReg rA = gpr.GetReg(false);
|
||||
ARMReg RA = gpr.R(a);
|
||||
ARMReg RD = gpr.R(d);
|
||||
MOVI2R(rA, (u32)inst.SIMM_16);
|
||||
ADD(RD, RA, rA);
|
||||
}
|
||||
else
|
||||
gpr.SetImmediate(d, inst.SIMM_16);
|
||||
}
|
||||
void JitArm::addis(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
|
||||
u32 d = inst.RD, a = inst.RA;
|
||||
if (a)
|
||||
{
|
||||
isImm[0] = true;
|
||||
Imm[0] = 0;
|
||||
}
|
||||
isImm[1] = true;
|
||||
Imm[1] = inst.SIMM_16 << (shiftedImm ? 16 : 0);
|
||||
break;
|
||||
case 25: // oris
|
||||
shiftedImm = true;
|
||||
case 24: // ori
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
isImm[0] = true;
|
||||
Imm[0] = gpr.GetImm(s);
|
||||
}
|
||||
isImm[1] = true;
|
||||
Imm[1] = inst.UIMM << (shiftedImm ? 16 : 0);
|
||||
break;
|
||||
case 27: // xoris
|
||||
shiftedImm = true;
|
||||
case 26: // xori
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
isImm[0] = true;
|
||||
Imm[0] = gpr.GetImm(s);
|
||||
}
|
||||
isImm[1] = true;
|
||||
Imm[1] = inst.UIMM << (shiftedImm ? 16 : 0);
|
||||
break;
|
||||
case 29: // addis_rc
|
||||
shiftedImm = true;
|
||||
case 28: // addi_rc
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
isImm[0] = true;
|
||||
Imm[0] = gpr.GetImm(s);
|
||||
}
|
||||
isImm[1] = true;
|
||||
Imm[1] = inst.UIMM << (shiftedImm ? 16 : 0);
|
||||
Rc = true;
|
||||
break;
|
||||
|
||||
case 31: // addcx, addx, subfx
|
||||
switch(inst.SUBOP10)
|
||||
{
|
||||
case 28: // andx
|
||||
case 60: // andcx
|
||||
case 124: // norx
|
||||
case 284: // eqvx
|
||||
case 316: // xorx
|
||||
case 412: // orcx
|
||||
case 444: // orx
|
||||
case 476: // nandx
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
isImm[0] = true;
|
||||
Imm[0] = gpr.GetImm(s);
|
||||
}
|
||||
if (gpr.IsImm(b))
|
||||
{
|
||||
isImm[1] = true;
|
||||
Imm[1] = gpr.GetImm(b);
|
||||
}
|
||||
Rc = inst.Rc;
|
||||
break;
|
||||
case 10: // addcx
|
||||
carry = true;
|
||||
case 40: // subfx
|
||||
isUnsigned = true;
|
||||
case 235: // mullwx
|
||||
case 266:
|
||||
case 778: // both addx
|
||||
if (gpr.IsImm(a))
|
||||
{
|
||||
gpr.SetImmediate(d, gpr.GetImm(a) + (inst.SIMM_16 << 16));
|
||||
isImm[0] = true;
|
||||
Imm[0] = gpr.GetImm(a);
|
||||
}
|
||||
if (gpr.IsImm(b))
|
||||
{
|
||||
isImm[1] = true;
|
||||
Imm[1] = gpr.GetImm(b);
|
||||
}
|
||||
Rc = inst.Rc;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN_LOG(DYNA_REC, "Unkown OPCD %d with arith function", inst.OPCD);
|
||||
Default(inst); return;
|
||||
break;
|
||||
}
|
||||
if (isImm[0] && isImm[1]) // Immediate propagation
|
||||
{
|
||||
bool hasCarry = false;
|
||||
u32 dest = d;
|
||||
switch(inst.OPCD)
|
||||
{
|
||||
case 7:
|
||||
gpr.SetImmediate(d, Mul(Imm[0], Imm[1]));
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
gpr.SetImmediate(d, Add(Imm[0], Imm[1]));
|
||||
hasCarry = Interpreter::Helper_Carry(Imm[0], Imm[1]);
|
||||
break;
|
||||
case 14:
|
||||
case 15:
|
||||
gpr.SetImmediate(d, Add(Imm[0], Imm[1]));
|
||||
hasCarry = Interpreter::Helper_Carry(Imm[0], Imm[1]);
|
||||
break;
|
||||
case 24:
|
||||
case 25:
|
||||
gpr.SetImmediate(a, Or(Imm[0], Imm[1]));
|
||||
dest = a;
|
||||
break;
|
||||
case 26:
|
||||
case 27:
|
||||
gpr.SetImmediate(a, Xor(Imm[0], Imm[1]));
|
||||
dest = a;
|
||||
break;
|
||||
case 28:
|
||||
case 29:
|
||||
gpr.SetImmediate(a, And(Imm[0], Imm[1]));
|
||||
dest = a;
|
||||
break;
|
||||
case 31: // addcx, addx, subfx
|
||||
switch(inst.SUBOP10)
|
||||
{
|
||||
case 28:
|
||||
gpr.SetImmediate(a, And(Imm[0], Imm[1]));
|
||||
dest = a;
|
||||
break;
|
||||
case 40: // subfx
|
||||
gpr.SetImmediate(d, Sub(Imm[1], Imm[0]));
|
||||
break;
|
||||
case 60:
|
||||
gpr.SetImmediate(a, And(Imm[1], ~Imm[0]));
|
||||
dest = a;
|
||||
break;
|
||||
case 124:
|
||||
gpr.SetImmediate(a, ~Or(Imm[0], Imm[1]));
|
||||
dest = a;
|
||||
break;
|
||||
case 235:
|
||||
gpr.SetImmediate(d, Mul(Imm[0], Imm[1]));
|
||||
break;
|
||||
case 284:
|
||||
gpr.SetImmediate(a, ~Xor(Imm[0], Imm[1]));
|
||||
dest = a;
|
||||
break;
|
||||
case 316:
|
||||
gpr.SetImmediate(a, Xor(Imm[0], Imm[1]));
|
||||
dest = a;
|
||||
break;
|
||||
case 412:
|
||||
gpr.SetImmediate(a, Or(Imm[0], ~Imm[1]));
|
||||
dest = a;
|
||||
break;
|
||||
case 444:
|
||||
gpr.SetImmediate(a, Or(Imm[0], Imm[1]));
|
||||
dest = a;
|
||||
break;
|
||||
case 476:
|
||||
gpr.SetImmediate(a, ~And(Imm[1], Imm[0]));
|
||||
dest = a;
|
||||
break;
|
||||
case 10: // addcx
|
||||
case 266:
|
||||
case 778: // both addx
|
||||
gpr.SetImmediate(d, Add(Imm[0], Imm[1]));
|
||||
hasCarry = Interpreter::Helper_Carry(Imm[0], Imm[1]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (carry) ComputeCarry(hasCarry);
|
||||
if (Rc) ComputeRC(gpr.GetImm(dest), 0);
|
||||
return;
|
||||
}
|
||||
ARMReg rA = gpr.GetReg(false);
|
||||
ARMReg RA = gpr.R(a);
|
||||
ARMReg RD = gpr.R(d);
|
||||
MOVI2R(rA, inst.SIMM_16 << 16);
|
||||
// One or the other isn't a IMM
|
||||
switch(inst.OPCD)
|
||||
{
|
||||
case 7:
|
||||
{
|
||||
ARMReg rA = gpr.GetReg();
|
||||
RD = gpr.R(d);
|
||||
RA = gpr.R(a);
|
||||
MOVI2R(rA, Imm[1]);
|
||||
MUL(RD, RA, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
{
|
||||
ARMReg rA = gpr.GetReg();
|
||||
RD = gpr.R(d);
|
||||
RA = gpr.R(a);
|
||||
MOVI2R(rA, Imm[1]);
|
||||
ADDS(RD, RA, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
case 15: // Arg2 is always Imm
|
||||
if (!isImm[0])
|
||||
{
|
||||
ARMReg rA = gpr.GetReg();
|
||||
RD = gpr.R(d);
|
||||
RA = gpr.R(a);
|
||||
MOVI2R(rA, Imm[1]);
|
||||
ADD(RD, RA, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
else
|
||||
gpr.SetImmediate(d, inst.SIMM_16 << 16);
|
||||
}
|
||||
void JitArm::addx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
u32 a = inst.RA, b = inst.RB, d = inst.RD;
|
||||
|
||||
if (gpr.IsImm(a) && gpr.IsImm(b))
|
||||
gpr.SetImmediate(d, Imm[1]);
|
||||
break;
|
||||
case 24:
|
||||
case 25:
|
||||
{
|
||||
gpr.SetImmediate(d, gpr.GetImm(a) + gpr.GetImm(b));
|
||||
if (inst.Rc) ComputeRC(gpr.GetImm(d), 0);
|
||||
return;
|
||||
ARMReg rA = gpr.GetReg();
|
||||
RS = gpr.R(s);
|
||||
RA = gpr.R(a);
|
||||
MOVI2R(rA, Imm[1]);
|
||||
ORR(RA, RS, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
ARMReg RA = gpr.R(a);
|
||||
ARMReg RB = gpr.R(b);
|
||||
ARMReg RD = gpr.R(d);
|
||||
break;
|
||||
case 26:
|
||||
case 27:
|
||||
{
|
||||
ARMReg rA = gpr.GetReg();
|
||||
RS = gpr.R(s);
|
||||
RA = gpr.R(a);
|
||||
MOVI2R(rA, Imm[1]);
|
||||
EOR(RA, RS, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
|
||||
break;
|
||||
case 28:
|
||||
case 29:
|
||||
{
|
||||
ARMReg rA = gpr.GetReg();
|
||||
RS = gpr.R(s);
|
||||
RA = gpr.R(a);
|
||||
MOVI2R(rA, Imm[1]);
|
||||
ANDS(RA, RS, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
break;
|
||||
case 31:
|
||||
switch(inst.SUBOP10)
|
||||
{
|
||||
case 28:
|
||||
RA = gpr.R(a);
|
||||
RS = gpr.R(s);
|
||||
RB = gpr.R(b);
|
||||
ANDS(RA, RS, RB);
|
||||
break;
|
||||
case 40: // subfx
|
||||
RD = gpr.R(d);
|
||||
RA = gpr.R(a);
|
||||
RB = gpr.R(b);
|
||||
SUBS(RD, RB, RA);
|
||||
break;
|
||||
case 60:
|
||||
RA = gpr.R(a);
|
||||
RS = gpr.R(s);
|
||||
RB = gpr.R(b);
|
||||
BICS(RA, RS, RB);
|
||||
break;
|
||||
case 124:
|
||||
RA = gpr.R(a);
|
||||
RS = gpr.R(s);
|
||||
RB = gpr.R(b);
|
||||
ORR(RA, RS, RB);
|
||||
MVNS(RA, RA);
|
||||
break;
|
||||
case 235:
|
||||
RD = gpr.R(d);
|
||||
RA = gpr.R(a);
|
||||
RB = gpr.R(b);
|
||||
MULS(RD, RA, RB);
|
||||
break;
|
||||
case 284:
|
||||
RA = gpr.R(a);
|
||||
RS = gpr.R(s);
|
||||
RB = gpr.R(b);
|
||||
EOR(RA, RS, RB);
|
||||
MVNS(RA, RA);
|
||||
break;
|
||||
case 316:
|
||||
RA = gpr.R(a);
|
||||
RS = gpr.R(s);
|
||||
RB = gpr.R(b);
|
||||
EORS(RA, RS, RB);
|
||||
break;
|
||||
case 412:
|
||||
{
|
||||
ARMReg rA = gpr.GetReg();
|
||||
RA = gpr.R(a);
|
||||
RS = gpr.R(s);
|
||||
RB = gpr.R(b);
|
||||
MVN(rA, RB);
|
||||
ANDS(RA, RS, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
break;
|
||||
case 444:
|
||||
RA = gpr.R(a);
|
||||
RS = gpr.R(s);
|
||||
RB = gpr.R(b);
|
||||
ORRS(RA, RS, RB);
|
||||
break;
|
||||
case 476:
|
||||
RA = gpr.R(a);
|
||||
RS = gpr.R(s);
|
||||
RB = gpr.R(b);
|
||||
AND(RA, RS, RB);
|
||||
MVNS(RA, RA);
|
||||
break;
|
||||
|
||||
case 10: // addcx
|
||||
case 266:
|
||||
case 778: // both addx
|
||||
RD = gpr.R(d);
|
||||
RA = gpr.R(a);
|
||||
RB = gpr.R(b);
|
||||
ADDS(RD, RA, RB);
|
||||
if (inst.Rc) ComputeRC();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (carry) ComputeCarry();
|
||||
if (Rc) isUnsigned ? GenerateRC() : ComputeRC();
|
||||
}
|
||||
|
||||
void JitArm::addcx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
u32 a = inst.RA, b = inst.RB, d = inst.RD;
|
||||
|
||||
ARMReg RA = gpr.R(a);
|
||||
ARMReg RB = gpr.R(b);
|
||||
ARMReg RD = gpr.R(d);
|
||||
ADDS(RD, RA, RB);
|
||||
ComputeCarry();
|
||||
if (inst.Rc) ComputeRC();
|
||||
}
|
||||
void JitArm::addex(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
|
@ -199,61 +531,6 @@ void JitArm::addex(UGeckoInstruction inst)
|
|||
gpr.Unlock(rA);
|
||||
}
|
||||
|
||||
void JitArm::subfx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
|
||||
u32 a = inst.RA, b = inst.RB, d = inst.RD;
|
||||
|
||||
if (inst.OE) PanicAlert("OE: subfx");
|
||||
|
||||
if (gpr.IsImm(a) && gpr.IsImm(b))
|
||||
{
|
||||
gpr.SetImmediate(d, gpr.GetImm(b) - gpr.GetImm(a));
|
||||
if (inst.Rc) ComputeRC(gpr.GetImm(d), 0);
|
||||
return;
|
||||
}
|
||||
ARMReg RA = gpr.R(a);
|
||||
ARMReg RB = gpr.R(b);
|
||||
ARMReg RD = gpr.R(d);
|
||||
SUBS(RD, RB, RA);
|
||||
if (inst.Rc) GenerateRC();
|
||||
}
|
||||
void JitArm::mulli(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
u32 a = inst.RA, d = inst.RD;
|
||||
|
||||
if (gpr.IsImm(a))
|
||||
{
|
||||
gpr.SetImmediate(d, gpr.GetImm(a) * inst.SIMM_16);
|
||||
return;
|
||||
}
|
||||
ARMReg RA = gpr.R(a);
|
||||
ARMReg RD = gpr.R(d);
|
||||
ARMReg rA = gpr.GetReg();
|
||||
MOVI2R(rA, inst.SIMM_16);
|
||||
MUL(RD, RA, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
|
||||
void JitArm::mullwx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
|
||||
u32 a = inst.RA, b = inst.RB, d = inst.RD;
|
||||
|
||||
ARMReg RA = gpr.R(a);
|
||||
ARMReg RB = gpr.R(b);
|
||||
ARMReg RD = gpr.R(d);
|
||||
MULS(RD, RA, RB);
|
||||
if (inst.OE) PanicAlert("OE: mullwx");
|
||||
if (inst.Rc) ComputeRC();
|
||||
}
|
||||
|
||||
void JitArm::mulhwux(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
|
@ -269,145 +546,6 @@ void JitArm::mulhwux(UGeckoInstruction inst)
|
|||
if (inst.Rc) ComputeRC();
|
||||
}
|
||||
|
||||
void JitArm::ori(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
u32 a = inst.RA, s = inst.RS;
|
||||
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
gpr.SetImmediate(a, gpr.GetImm(s) | inst.UIMM);
|
||||
return;
|
||||
}
|
||||
ARMReg RA = gpr.R(a);
|
||||
ARMReg RS = gpr.R(s);
|
||||
ARMReg rA = gpr.GetReg();
|
||||
MOVI2R(rA, inst.UIMM);
|
||||
ORR(RA, RS, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
void JitArm::oris(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
u32 a = inst.RA, s = inst.RS;
|
||||
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
gpr.SetImmediate(a, gpr.GetImm(s) | (inst.UIMM << 16));
|
||||
return;
|
||||
}
|
||||
ARMReg RA = gpr.R(a);
|
||||
ARMReg RS = gpr.R(s);
|
||||
ARMReg rA = gpr.GetReg();
|
||||
MOVI2R(rA, inst.UIMM << 16);
|
||||
ORR(RA, RS, rA);
|
||||
gpr.Unlock(rA);
|
||||
}
|
||||
|
||||
void JitArm::orx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
u32 a = inst.RA, b = inst.RB, s = inst.RS;
|
||||
|
||||
if (gpr.IsImm(b) && gpr.IsImm(s))
|
||||
{
|
||||
gpr.SetImmediate(a, gpr.GetImm(s) | gpr.GetImm(b));
|
||||
if (inst.Rc) ComputeRC(gpr.GetImm(a), 0);
|
||||
return;
|
||||
}
|
||||
ARMReg rA = gpr.R(a);
|
||||
ARMReg rB = gpr.R(b);
|
||||
ARMReg rS = gpr.R(s);
|
||||
ORRS(rA, rS, rB);
|
||||
if (inst.Rc)
|
||||
ComputeRC();
|
||||
}
|
||||
|
||||
void JitArm::xorx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Integer)
|
||||
|
||||
u32 a = inst.RA, b = inst.RB, s = inst.RS;
|
||||
|
||||
if (gpr.IsImm(b) && gpr.IsImm(s))
|
||||
{
|
||||
gpr.SetImmediate(a, gpr.GetImm(s) ^ gpr.GetImm(b));
|
||||
if (inst.Rc) ComputeRC(gpr.GetImm(a), 0);
|
||||
return;
|
||||
}
|
||||
ARMReg rA = gpr.R(a);
|
||||
ARMReg rB = gpr.R(b);
|
||||
ARMReg rS = gpr.R(s);
|
||||
EORS(rA, rS, rB);
|
||||
if (inst.Rc)
|
||||
ComputeRC();
|
||||
}
|
||||
|
||||
void JitArm::andx(UGeckoInstruction inst)
|
||||
{
|
||||
u32 a = inst.RA, b = inst.RB, s = inst.RS;
|
||||
|
||||
if (gpr.IsImm(s) && gpr.IsImm(b))
|
||||
{
|
||||
gpr.SetImmediate(a, gpr.GetImm(s) & gpr.GetImm(b));
|
||||
if (inst.Rc) ComputeRC(gpr.GetImm(a), 0);
|
||||
return;
|
||||
}
|
||||
ARMReg rA = gpr.R(a);
|
||||
ARMReg rB = gpr.R(b);
|
||||
ARMReg rS = gpr.R(s);
|
||||
|
||||
ANDS(rA, rS, rB);
|
||||
|
||||
if (inst.Rc) ComputeRC();
|
||||
}
|
||||
|
||||
void JitArm::andi_rc(UGeckoInstruction inst)
|
||||
{
|
||||
u32 a = inst.RA, s = inst.RS;
|
||||
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
gpr.SetImmediate(a, gpr.GetImm(s) & inst.UIMM);
|
||||
ComputeRC(gpr.GetImm(a), 0);
|
||||
return;
|
||||
}
|
||||
ARMReg rA = gpr.R(a);
|
||||
ARMReg rS = gpr.R(s);
|
||||
ARMReg RA = gpr.GetReg();
|
||||
|
||||
MOVI2R(RA, inst.UIMM);
|
||||
ANDS(rA, rS, RA);
|
||||
|
||||
ComputeRC();
|
||||
gpr.Unlock(RA);
|
||||
}
|
||||
|
||||
void JitArm::andis_rc(UGeckoInstruction inst)
|
||||
{
|
||||
u32 a = inst.RA, s = inst.RS;
|
||||
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
gpr.SetImmediate(a, gpr.GetImm(s) & ((u32)inst.UIMM << 16));
|
||||
ComputeRC(gpr.GetImm(a), 0);
|
||||
return;
|
||||
}
|
||||
ARMReg rA = gpr.R(a);
|
||||
ARMReg rS = gpr.R(s);
|
||||
ARMReg RA = gpr.GetReg();
|
||||
|
||||
MOVI2R(RA, (u32)inst.UIMM << 16);
|
||||
ANDS(rA, rS, RA);
|
||||
|
||||
ComputeRC();
|
||||
gpr.Unlock(RA);
|
||||
}
|
||||
|
||||
void JitArm::extshx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
|
|
|
@ -58,25 +58,25 @@ static GekkoOPTemplate primarytable[] =
|
|||
{3, &JitArm::Break}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||
{17, &JitArm::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
||||
|
||||
{7, &JitArm::mulli}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}},
|
||||
{7, &JitArm::arith}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}},
|
||||
{8, &JitArm::Default}, //"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
|
||||
{10, &JitArm::cmpli}, //"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
|
||||
{11, &JitArm::cmpi}, //"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}},
|
||||
{12, &JitArm::Default}, //"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
|
||||
{13, &JitArm::Default}, //"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}},
|
||||
{14, &JitArm::addi}, //"addi", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}},
|
||||
{15, &JitArm::addis}, //"addis", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}},
|
||||
{12, &JitArm::arith}, //"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
|
||||
{13, &JitArm::arith}, //"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}},
|
||||
{14, &JitArm::arith}, //"addi", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}},
|
||||
{15, &JitArm::arith}, //"addis", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}},
|
||||
|
||||
{20, &JitArm::rlwimix}, //"rlwimix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_A | FL_IN_S | FL_RC_BIT}},
|
||||
{21, &JitArm::rlwinmx}, //"rlwinmx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
|
||||
{23, &JitArm::Default}, //"rlwnmx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_IN_B | FL_RC_BIT}},
|
||||
|
||||
{24, &JitArm::ori}, //"ori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}},
|
||||
{25, &JitArm::oris}, //"oris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}},
|
||||
{26, &JitArm::Default}, //"xori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}},
|
||||
{27, &JitArm::Default}, //"xoris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}},
|
||||
{28, &JitArm::andi_rc}, //"andi_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}},
|
||||
{29, &JitArm::andis_rc}, //"andis_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}},
|
||||
{24, &JitArm::arith}, //"ori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}},
|
||||
{25, &JitArm::arith}, //"oris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}},
|
||||
{26, &JitArm::arith}, //"xori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}},
|
||||
{27, &JitArm::arith}, //"xoris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}},
|
||||
{28, &JitArm::arith}, //"andi_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}},
|
||||
{29, &JitArm::arith}, //"andis_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}},
|
||||
|
||||
{32, &JitArm::lwz}, //"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}},
|
||||
{33, &JitArm::Default}, //"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}},
|
||||
|
@ -194,14 +194,14 @@ static GekkoOPTemplate table19[] =
|
|||
|
||||
static GekkoOPTemplate table31[] =
|
||||
{
|
||||
{28, &JitArm::andx}, //"andx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{60, &JitArm::Default}, //"andcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{444, &JitArm::orx}, //"orx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{124, &JitArm::Default}, //"norx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{316, &JitArm::xorx}, //"xorx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{412, &JitArm::Default}, //"orcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{476, &JitArm::Default}, //"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{284, &JitArm::Default}, //"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{28, &JitArm::arith}, //"andx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{60, &JitArm::arith}, //"andcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{444, &JitArm::arith}, //"orx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{124, &JitArm::arith}, //"norx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{316, &JitArm::arith}, //"xorx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{412, &JitArm::arith}, //"orcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{476, &JitArm::arith}, //"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{284, &JitArm::arith}, //"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{0, &JitArm::cmp}, //"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
|
||||
{32, &JitArm::cmpl}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
|
||||
{26, &JitArm::Default}, //"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
|
||||
|
@ -307,9 +307,9 @@ static GekkoOPTemplate table31[] =
|
|||
|
||||
static GekkoOPTemplate table31_2[] =
|
||||
{
|
||||
{266, &JitArm::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{778, &JitArm::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{10, &JitArm::addcx}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
|
||||
{266, &JitArm::arith}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{778, &JitArm::arith}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{10, &JitArm::arith}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
|
||||
{138, &JitArm::addex}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
|
||||
{234, &JitArm::Default}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
|
||||
{202, &JitArm::Default}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
|
||||
|
@ -319,11 +319,11 @@ static GekkoOPTemplate table31_2[] =
|
|||
{971, &JitArm::Default}, //"divwuox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}},
|
||||
{75, &JitArm::Default}, //"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
|
||||
{11, &JitArm::mulhwux}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
|
||||
{235, &JitArm::mullwx}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
|
||||
{235, &JitArm::arith}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
|
||||
{747, &JitArm::Default}, //"mullwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
|
||||
{104, &JitArm::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{40, &JitArm::subfx}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{552, &JitArm::Default}, //"subox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{40, &JitArm::arith}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{552, &JitArm::arith}, //"subox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{8, &JitArm::Default}, //"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
|
||||
{136, &JitArm::Default}, //"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
|
||||
{232, &JitArm::Default}, //"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
|
||||
|
|
Loading…
Reference in New Issue