Jit64: divwx - Optimize division by 2

...and let's optimize a divisor of 2 ever so slightly for good measure.
I wouldn't have bothered, but most GameCube games seem to hit this on
launch.

- Division by 2
Before:
41 BE 02 00 00 00    mov         r14d,2
41 8B C2             mov         eax,r10d
45 85 F6             test        r14d,r14d
74 0D                je          overflow
3D 00 00 00 80       cmp         eax,80000000h
75 0E                jne         normal_path
41 83 FE FF          cmp         r14d,0FFFFFFFFh
75 08                jne         normal_path
overflow:
C1 F8 1F             sar         eax,1Fh
44 8B F0             mov         r14d,eax
EB 07                jmp         done
normal_path:
99                   cdq
41 F7 FE             idiv        eax,r14d
44 8B F0             mov         r14d,eax
done:

After:
45 8B F2             mov         r14d,r10d
41 C1 EE 1F          shr         r14d,1Fh
45 03 F2             add         r14d,r10d
41 D1 FE             sar         r14d,1
This commit is contained in:
Sintendo 2021-03-04 22:29:15 +01:00
parent 0637a7ec59
commit 1865035798
1 changed files with 19 additions and 0 deletions

View File

@ -1460,6 +1460,25 @@ void Jit64::divwx(UGeckoInstruction inst)
SetJumpTarget(done);
}
else if (divisor == 2 || divisor == -2)
{
X64Reg tmp = RSCRATCH;
if (Ra.IsSimpleReg() && Ra.GetSimpleReg() != Rd)
tmp = Ra.GetSimpleReg();
else
MOV(32, R(tmp), Ra);
MOV(32, Rd, R(tmp));
SHR(32, Rd, Imm8(31));
ADD(32, Rd, R(tmp));
SAR(32, Rd, Imm8(1));
if (divisor < 0)
NEG(32, Rd);
if (inst.OE)
GenerateConstantOverflow(false);
}
else if (MathUtil::IsPow2(divisor) || MathUtil::IsPow2(-divisor))
{
u32 abs_val = std::abs(divisor);