[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 GenerateRC(int cr = 0);
void ComputeRC(int cr = 0); void ComputeRC(int cr = 0);
void ComputeRC(s32 value, int cr);
// OPCODES // OPCODES
void unknown_instruction(UGeckoInstruction _inst); void unknown_instruction(UGeckoInstruction _inst);

View File

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