Jit64: divwx - Eliminate MOV for division by power of 2

Division by a power of two can be slightly improved when the
destination and dividend registers are the same.

Before:
8B C6                mov         eax,esi
85 C0                test        eax,eax
8D 70 03             lea         esi,[rax+3]
0F 49 F0             cmovns      esi,eax
C1 FE 02             sar         esi,2

After:
85 F6                test        esi,esi
8D 46 03             lea         eax,[rsi+3]
0F 48 F0             cmovs       esi,eax
C1 FE 02             sar         esi,2
This commit is contained in:
Sintendo 2021-04-24 19:28:18 +02:00
parent 246adf0d6d
commit abc4c8f601
1 changed files with 32 additions and 8 deletions

View File

@ -1493,15 +1493,39 @@ void Jit64::divwx(UGeckoInstruction inst)
{
u32 abs_val = std::abs(divisor);
X64Reg tmp = RSCRATCH;
if (Ra.IsSimpleReg() && Ra.GetSimpleReg() != Rd)
tmp = Ra.GetSimpleReg();
else
MOV(32, R(tmp), Ra);
X64Reg dividend, sum, src;
CCFlags cond = CC_NS;
TEST(32, R(tmp), R(tmp));
LEA(32, Rd, MDisp(tmp, abs_val - 1));
CMOVcc(32, Rd, R(tmp), CC_NS);
if (!Ra.IsSimpleReg())
{
dividend = RSCRATCH;
sum = Rd;
src = RSCRATCH;
// Load dividend from memory
MOV(32, R(dividend), Ra);
}
else if (d == a)
{
// Rd holds the dividend, while RSCRATCH holds the sum
// This is opposite of the other cases
dividend = Rd;
sum = RSCRATCH;
src = RSCRATCH;
// Negate condition to compensate the swapped values
cond = CC_S;
}
else
{
// Use dividend from register directly
dividend = Ra.GetSimpleReg();
sum = Rd;
src = dividend;
}
TEST(32, R(dividend), R(dividend));
LEA(32, sum, MDisp(dividend, abs_val - 1));
CMOVcc(32, Rd, R(src), cond);
SAR(32, Rd, Imm8(IntLog2(abs_val)));
if (divisor < 0)