[ARM] Merge a bunch of arithmetic JIT instructions and rapid prototyping of a bunch more.

This commit is contained in:
Ryan Houdek 2013-09-02 14:15:22 +00:00
parent 1b1cc82e5b
commit a7f3264fed
3 changed files with 424 additions and 297 deletions

View File

@ -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);

View File

@ -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);
{
isImm[0] = true;
Imm[0] = 0;
}
void JitArm::addis(UGeckoInstruction inst)
isImm[1] = true;
Imm[1] = inst.SIMM_16 << (shiftedImm ? 16 : 0);
break;
case 25: // oris
shiftedImm = true;
case 24: // ori
if (gpr.IsImm(s))
{
INSTRUCTION_START
JITDISABLE(Integer)
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;
u32 d = inst.RD, a = inst.RA;
if (a)
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)
gpr.SetImmediate(d, Imm[1]);
break;
case 24:
case 25:
{
INSTRUCTION_START
JITDISABLE(Integer)
u32 a = inst.RA, b = inst.RB, d = inst.RD;
ARMReg rA = gpr.GetReg();
RS = gpr.R(s);
RA = gpr.R(a);
MOVI2R(rA, Imm[1]);
ORR(RA, RS, rA);
gpr.Unlock(rA);
}
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);
}
if (gpr.IsImm(a) && gpr.IsImm(b))
break;
case 28:
case 29:
{
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]);
ANDS(RA, RS, rA);
gpr.Unlock(rA);
}
ARMReg RA = gpr.R(a);
ARMReg RB = gpr.R(b);
ARMReg RD = gpr.R(d);
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

View File

@ -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}},