JIT64: optimize some special cases of srawix

Shift by 31 and 1, both of which are pretty common, can be done in a few less
instructions. Tested with a hwtest.
This commit is contained in:
Fiora 2014-08-28 10:21:46 -07:00
parent 805be80f12
commit 10d691a277
1 changed files with 24 additions and 4 deletions

View File

@ -1842,11 +1842,31 @@ void Jit64::srawix(UGeckoInstruction inst)
MOV(32, R(EAX), gpr.R(s)); MOV(32, R(EAX), gpr.R(s));
if (a != s) if (a != s)
MOV(32, gpr.R(a), R(EAX)); MOV(32, gpr.R(a), R(EAX));
// some optimized common cases that can be done in slightly fewer ops
if (amount == 31)
{
SAR(32, gpr.R(a), Imm8(31));
NEG(32, R(EAX)); // EAX = input == INT_MIN ? INT_MIN : -input;
AND(32, R(EAX), Imm32(0x80000000)); // EAX = input < 0 && input != INT_MIN ? 0 : 0x80000000
SHR(32, R(EAX), Imm8(31 - XER_CA_SHIFT));
XOR(32, M(&PowerPC::ppcState.spr[SPR_XER]), R(EAX)); // XER.CA = (input < 0 && input != INT_MIN)
}
else if (amount == 1)
{
SHR(32, R(EAX), Imm8(31)); // sign
AND(32, R(EAX), gpr.R(a)); // (sign && carry)
SAR(32, gpr.R(a), Imm8(1));
SHL(32, R(EAX), Imm8(XER_CA_SHIFT));
OR(32, M(&PowerPC::ppcState.spr[SPR_XER]), R(EAX)); // XER.CA = sign && carry, aka (input&0x80000001) == 0x80000001
}
else
{
SAR(32, gpr.R(a), Imm8(amount)); SAR(32, gpr.R(a), Imm8(amount));
SHL(32, R(EAX), Imm8(32 - amount)); SHL(32, R(EAX), Imm8(32 - amount));
TEST(32, R(EAX), gpr.R(a)); TEST(32, R(EAX), gpr.R(a));
JitSetCAIf(CC_NZ); JitSetCAIf(CC_NZ);
} }
}
else else
{ {
// FIXME // FIXME