Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[ARM] Implement subfic with optimizations stolen from JIT64.
  • Loading branch information
Sonicadvance1 committed Sep 24, 2013
1 parent 405aa30 commit 482170c
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
1 change: 1 addition & 0 deletions Source/Core/Core/Src/PowerPC/JitArm32/Jit.h
Expand Up @@ -159,6 +159,7 @@ class JitArm : public JitBase, public ArmGen::ARMXCodeBlock
void arith(UGeckoInstruction _inst);

void addex(UGeckoInstruction _inst);
void subfic(UGeckoInstruction _inst);
void cntlzwx(UGeckoInstruction _inst);
void cmp (UGeckoInstruction _inst);
void cmpi(UGeckoInstruction _inst);
Expand Down
73 changes: 73 additions & 0 deletions Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp
Expand Up @@ -117,6 +117,79 @@ void JitArm::FinalizeCarry(ARMReg reg)
STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
gpr.Unlock(tmp);
}
void JitArm::subfic(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITIntegerOff)
int a = inst.RA, d = inst.RD;

int imm = inst.SIMM_16;
if (d == a)
{
if (imm == 0)
{
ARMReg tmp = gpr.GetReg();
Operand2 mask = Operand2(2, 2); // XER_CA_MASK
LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
BIC(tmp, tmp, mask);
// Flags act exactly like subtracting from 0
RSBS(gpr.R(d), gpr.R(d), 0);
// Output carry is inverted
SetCC(CC_CC);
ORR(tmp, tmp, mask);
SetCC();
STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
gpr.Unlock(tmp);
}
else if (imm == -1)
{
// CA is always set in this case
ARMReg tmp = gpr.GetReg();
Operand2 mask = Operand2(2, 2); // XER_CA_MASK
LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
ORR(tmp, tmp, mask);
STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
gpr.Unlock(tmp);

MVN(gpr.R(d), gpr.R(d));
}
else
{
ARMReg tmp = gpr.GetReg();
ARMReg rA = gpr.GetReg();
Operand2 mask = Operand2(2, 2); // XER_CA_MASK
MOVI2R(rA, imm + 1);
LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
BIC(tmp, tmp, mask);
// Flags act exactly like subtracting from 0
MVN(gpr.R(d), gpr.R(d));
ADDS(gpr.R(d), gpr.R(d), rA);
// Output carry is inverted
SetCC(CC_CS);
ORR(tmp, tmp, mask);
SetCC();
STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
gpr.Unlock(tmp, rA);
}
}
else
{
ARMReg tmp = gpr.GetReg();
Operand2 mask = Operand2(2, 2); // XER_CA_MASK
MOVI2R(gpr.R(d), imm);
LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
BIC(tmp, tmp, mask);
// Flags act exactly like subtracting from 0
SUBS(gpr.R(d), gpr.R(d), gpr.R(a));
// Output carry is inverted
SetCC(CC_CC);
ORR(tmp, tmp, mask);
SetCC();
STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
gpr.Unlock(tmp);
}
// This instruction has no RC flag
}

u32 Add(u32 a, u32 b) {return a + b;}
u32 Sub(u32 a, u32 b) {return a - b;}
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp
Expand Up @@ -59,7 +59,7 @@ static GekkoOPTemplate primarytable[] =
{17, &JitArm::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},

{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}},
{8, &JitArm::subfic}, //"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::arith}, //"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}},
Expand Down

0 comments on commit 482170c

Please sign in to comment.