From 18650357988c54727bb9eb9f8de864b6b2e528a2 Mon Sep 17 00:00:00 2001 From: Sintendo Date: Thu, 4 Mar 2021 22:29:15 +0100 Subject: [PATCH] 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 --- .../Core/Core/PowerPC/Jit64/Jit_Integer.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index e673a52b6d..464bcb4521 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -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);