From d3ca5d812b9bbdd42e2093576ab5ccde37ab93b1 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 28 Dec 2020 22:27:41 +0000 Subject: [PATCH 1/2] Jit_Integer: Use SHLX, SHRX, SARX --- .../Core/Core/PowerPC/Jit64/Jit_Integer.cpp | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index bd4b20a2d3..d12141099d 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -1870,6 +1870,16 @@ void Jit64::srwx(UGeckoInstruction inst) SHR(32, Ra, Imm8(amount)); } } + else if (cpu_info.bBMI2) + { + RCX64Reg Ra = gpr.Bind(a, RCMode::Write); + RCX64Reg Rb = gpr.Bind(b, RCMode::Read); + RCX64Reg Rs = gpr.Bind(s, RCMode::Read); + RegCache::Realize(Ra, Rb, Rs); + + // Rs must be in register: This is a 64-bit operation, using an OpArg will have invalid results + SHRX(64, Ra, Rs, Rb); + } else { RCX64Reg ecx = gpr.Scratch(ECX); // no register choice @@ -1933,6 +1943,25 @@ void Jit64::slwx(UGeckoInstruction inst) if (inst.Rc) ComputeRC(a); } + else if (cpu_info.bBMI2) + { + RCX64Reg Ra = gpr.Bind(a, RCMode::Write); + RCX64Reg Rb = gpr.Bind(b, RCMode::Read); + RCOpArg Rs = gpr.UseNoImm(s, RCMode::Read); + RegCache::Realize(Ra, Rb, Rs); + + SHLX(64, Ra, Rs, Rb); + if (inst.Rc) + { + AND(32, Ra, Ra); + RegCache::Unlock(Ra, Rb, Rs); + ComputeRC(a, false); + } + else + { + MOVZX(64, 32, Ra, Ra); + } + } else { RCX64Reg ecx = gpr.Scratch(ECX); // no register choice @@ -2023,6 +2052,29 @@ void Jit64::srawx(UGeckoInstruction inst) gpr.SetImmediate32(a, 0); FinalizeCarry(false); } + else if (cpu_info.bBMI2 && a != b) + { + RCX64Reg Ra = gpr.Bind(a, RCMode::Write); + RCX64Reg Rb = gpr.Bind(b, RCMode::Read); + RCOpArg Rs = gpr.UseNoImm(s, RCMode::Read); + RegCache::Realize(Ra, Rb, Rs); + + if (a != s) + MOV(32, Ra, Rs); + SHL(64, Ra, Imm8(32)); + SARX(64, Ra, Ra, Rb); + if (js.op->wantsCA) + { + MOV(32, R(RSCRATCH), Ra); + SHR(64, Ra, Imm8(32)); + TEST(32, Ra, R(RSCRATCH)); + } + else + { + SHR(64, Ra, Imm8(32)); + } + FinalizeCarry(CC_NZ); + } else { RCX64Reg ecx = gpr.Scratch(ECX); // no register choice From 71a996e33b16ec68331ae529f201ce6c6ac87402 Mon Sep 17 00:00:00 2001 From: merry Date: Fri, 1 Jan 2021 10:20:50 +0000 Subject: [PATCH 2/2] Jit_Integer: srawx: Handle a != b case with SARX Suggested by @Sintendo Co-authored-by: Sintendo --- Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index d12141099d..f7b45ca4b0 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -2052,17 +2052,21 @@ void Jit64::srawx(UGeckoInstruction inst) gpr.SetImmediate32(a, 0); FinalizeCarry(false); } - else if (cpu_info.bBMI2 && a != b) + else if (cpu_info.bBMI2) { RCX64Reg Ra = gpr.Bind(a, RCMode::Write); RCX64Reg Rb = gpr.Bind(b, RCMode::Read); - RCOpArg Rs = gpr.UseNoImm(s, RCMode::Read); + RCOpArg Rs = gpr.Use(s, RCMode::Read); RegCache::Realize(Ra, Rb, Rs); - if (a != s) - MOV(32, Ra, Rs); - SHL(64, Ra, Imm8(32)); - SARX(64, Ra, Ra, Rb); + X64Reg tmp = RSCRATCH; + if (a == s && a != b) + tmp = Ra; + else + MOV(32, R(tmp), Rs); + + SHL(64, R(tmp), Imm8(32)); + SARX(64, Ra, R(tmp), Rb); if (js.op->wantsCA) { MOV(32, R(RSCRATCH), Ra);