[ARM] IMM support for all integer instructions that call ComputeRC. Small FPS gains everywhere.

This commit is contained in:
Ryan Houdek 2013-08-11 07:41:23 +00:00
parent ef83d03dc0
commit 42aef24d78
2 changed files with 115 additions and 39 deletions

View file

@ -116,6 +116,7 @@ public:
void GenerateRC(int cr = 0);
void ComputeRC(int cr = 0);
void ComputeRC(s32 value, int cr);
// OPCODES
void unknown_instruction(UGeckoInstruction _inst);

View file

@ -54,7 +54,19 @@ void JitArm::ComputeRC(int cr) {
STRB(rB, R9, PPCSTATE_OFF(cr_fast) + cr);
gpr.Unlock(rB);
}
void JitArm::ComputeRC(s32 value, int cr) {
ARMReg rB = gpr.GetReg();
if (value < 0)
MOV(rB, 0x8);
else if (value > 0)
MOV(rB, 0x4);
else
MOV(rB, 0x2);
STRB(rB, R9, PPCSTATE_OFF(cr_fast) + cr);
gpr.Unlock(rB);
}
void JitArm::addi(UGeckoInstruction inst)
{
INSTRUCTION_START
@ -103,10 +115,17 @@ void JitArm::addx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(Integer)
ARMReg RA = gpr.R(inst.RA);
ARMReg RB = gpr.R(inst.RB);
ARMReg RD = gpr.R(inst.RD);
u32 a = inst.RA, b = inst.RB, d = inst.RD;
if (gpr.IsImm(a) && gpr.IsImm(b))
{
gpr.SetImmediate(d, gpr.GetImm(a) + gpr.GetImm(b));
if (inst.Rc) ComputeRC(gpr.GetImm(d), 0);
return;
}
ARMReg RA = gpr.R(a);
ARMReg RB = gpr.R(b);
ARMReg RD = gpr.R(d);
ADDS(RD, RA, RB);
if (inst.Rc) ComputeRC();
}
@ -115,11 +134,20 @@ void JitArm::subfx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(Integer)
ARMReg RA = gpr.R(inst.RA);
ARMReg RB = gpr.R(inst.RB);
ARMReg RD = gpr.R(inst.RD);
SUBS(RD, RB, RA);
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)
@ -163,9 +191,15 @@ void JitArm::oris(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(Integer)
u32 a = inst.RA, s = inst.RS;
ARMReg RA = gpr.R(inst.RA);
ARMReg RS = gpr.R(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);
@ -176,10 +210,17 @@ void JitArm::orx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(Integer)
u32 a = inst.RA, b = inst.RB, s = inst.RS;
ARMReg rA = gpr.R(inst.RA);
ARMReg rS = gpr.R(inst.RS);
ARMReg rB = gpr.R(inst.RB);
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();
@ -190,9 +231,17 @@ void JitArm::xorx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(Integer)
ARMReg rA = gpr.R(inst.RA);
ARMReg rS = gpr.R(inst.RS);
ARMReg rB = gpr.R(inst.RB);
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();
@ -201,12 +250,19 @@ void JitArm::extshx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(Integer)
ARMReg RA, RS;
RA = gpr.R(inst.RA);
RS = gpr.R(inst.RS);
SXTH(RA, RS);
u32 a = inst.RA, s = inst.RS;
if (gpr.IsImm(s))
{
gpr.SetImmediate(a, (u32)(s32)(s16)gpr.GetImm(s));
if (inst.Rc) ComputeRC(gpr.GetImm(a), 0);
return;
}
ARMReg rA = gpr.R(a);
ARMReg rS = gpr.R(s);
SXTH(rA, rS);
if (inst.Rc){
CMP(RA, 0);
CMP(rA, 0);
ComputeRC();
}
}
@ -214,12 +270,19 @@ void JitArm::extsbx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(Integer)
ARMReg RA, RS;
RA = gpr.R(inst.RA);
RS = gpr.R(inst.RS);
SXTB(RA, RS);
u32 a = inst.RA, s = inst.RS;
if (gpr.IsImm(s))
{
gpr.SetImmediate(a, (u32)(s32)(s8)gpr.GetImm(s));
if (inst.Rc) ComputeRC(gpr.GetImm(a), 0);
return;
}
ARMReg rA = gpr.R(a);
ARMReg rS = gpr.R(s);
SXTB(rA, rS);
if (inst.Rc){
CMP(RA, 0);
CMP(rA, 0);
ComputeRC();
}
}
@ -228,31 +291,43 @@ void JitArm::cmp (UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(Integer)
ARMReg RA = gpr.R(inst.RA);
ARMReg RB = gpr.R(inst.RB);
int crf = inst.CRFD;
u32 a = inst.RA, b = inst.RB;
if (gpr.IsImm(a) && gpr.IsImm(b))
{
ComputeRC((s32)gpr.GetImm(a) - (s32)gpr.GetImm(b), crf);
return;
}
ARMReg RA = gpr.R(a);
ARMReg RB = gpr.R(b);
CMP(RA, RB);
ComputeRC(crf);
}
void JitArm::cmpi(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(Integer)
ARMReg RA = gpr.R(inst.RA);
u32 a = inst.RA;
int crf = inst.CRFD;
if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 256)
{
CMP(RA, inst.SIMM_16);
}
if (gpr.IsImm(a))
ComputeRC((s32)gpr.GetImm(a) - inst.SIMM_16, crf);
else
{
ARMReg rA = gpr.GetReg();
MOVI2R(rA, inst.SIMM_16);
CMP(RA, rA);
gpr.Unlock(rA);
ARMReg RA = gpr.R(a);
if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 256)
CMP(RA, inst.SIMM_16);
else
{
ARMReg rA = gpr.GetReg();
MOVI2R(rA, inst.SIMM_16);
CMP(RA, rA);
gpr.Unlock(rA);
}
ComputeRC(crf);
}
ComputeRC(crf);
}
void JitArm::cmpl(UGeckoInstruction inst)
{