Jit_Integer: Optimize common rlwimix cases

This commit is contained in:
MerryMage 2020-12-28 12:57:53 +00:00
parent 4a102186c7
commit cdcca72b61
1 changed files with 26 additions and 11 deletions

View File

@ -1726,7 +1726,7 @@ void Jit64::rlwimix(UGeckoInstruction inst)
} }
else if (inst.SH) else if (inst.SH)
{ {
// TODO: common cases of this might be faster with pinsrb or abuse of AH // TODO: perhaps consider pinsrb or abuse of AH
RCOpArg Rs = gpr.Use(s, RCMode::Read); RCOpArg Rs = gpr.Use(s, RCMode::Read);
RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite); RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite);
RegCache::Realize(Rs, Ra); RegCache::Realize(Rs, Ra);
@ -1735,22 +1735,28 @@ void Jit64::rlwimix(UGeckoInstruction inst)
{ {
MOV(32, R(RSCRATCH), Rs); MOV(32, R(RSCRATCH), Rs);
SHL(32, R(RSCRATCH), Imm8(inst.SH)); SHL(32, R(RSCRATCH), Imm8(inst.SH));
AndWithMask(Ra, ~mask);
OR(32, Ra, R(RSCRATCH));
} }
else if (right_shift) else if (right_shift)
{ {
MOV(32, R(RSCRATCH), Rs); MOV(32, R(RSCRATCH), Rs);
SHR(32, R(RSCRATCH), Imm8(32 - inst.SH)); SHR(32, R(RSCRATCH), Imm8(32 - inst.SH));
AndWithMask(Ra, ~mask);
OR(32, Ra, R(RSCRATCH));
} }
else else
{ {
RotateLeft(32, RSCRATCH, Rs, inst.SH); RotateLeft(32, RSCRATCH, Rs, inst.SH);
XOR(32, R(RSCRATCH), Ra); }
AndWithMask(RSCRATCH, mask);
XOR(32, Ra, R(RSCRATCH)); if (mask == 0xFF || mask == 0xFFFF)
{
MOV(mask == 0xFF ? 8 : 16, Ra, R(RSCRATCH));
needs_test = true;
}
else
{
if (!left_shift && !right_shift)
AndWithMask(RSCRATCH, mask);
AndWithMask(Ra, ~mask);
OR(32, Ra, R(RSCRATCH));
} }
} }
else else
@ -1758,9 +1764,18 @@ void Jit64::rlwimix(UGeckoInstruction inst)
RCX64Reg Rs = gpr.Bind(s, RCMode::Read); RCX64Reg Rs = gpr.Bind(s, RCMode::Read);
RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite); RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite);
RegCache::Realize(Rs, Ra); RegCache::Realize(Rs, Ra);
XOR(32, Ra, Rs);
AndWithMask(Ra, ~mask); if (mask == 0xFF || mask == 0xFFFF)
XOR(32, Ra, Rs); {
MOV(mask == 0xFF ? 8 : 16, Ra, Rs);
needs_test = true;
}
else
{
XOR(32, Ra, Rs);
AndWithMask(Ra, ~mask);
XOR(32, Ra, Rs);
}
} }
if (inst.Rc) if (inst.Rc)
ComputeRC(a, needs_test); ComputeRC(a, needs_test);