summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMerryMage <MerryMage@users.noreply.github.com>2020-12-28 22:27:41 +0000
committerMerryMage <MerryMage@users.noreply.github.com>2020-12-29 23:51:54 +0000
commitd3ca5d812b9bbdd42e2093576ab5ccde37ab93b1 (patch)
treee0dbe584c3374a302044b66d1cdd4316d081fb06 /Source/Core
parente509353eb04eafc5df0c659188be9680ba043759 (diff)
Jit_Integer: Use SHLX, SHRX, SARX
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp52
1 files changed, 52 insertions, 0 deletions
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