summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLC <mathew1800@gmail.com>2021-01-14 21:40:45 -0500
committerGitHub <noreply@github.com>2021-01-14 21:40:45 -0500
commitaba179e4baa2c971ac81048364ff3a37c0d267fb (patch)
tree0b40ec4c9fd92258d1a2fb9644a2c3df9f63d6f3 /Source/Core
parent0c2bc3582db685db28254ffa8a901e61dc50b258 (diff)
parent71a996e33b16ec68331ae529f201ce6c6ac87402 (diff)
Merge pull request #9385 from MerryMage/more-bmi2
Jit_Integer: Use SHLX, SHRX, SARX
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index 7279f2e7f7..e60485e3ec 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -1908,6 +1908,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
@@ -1971,6 +1981,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
@@ -2061,6 +2090,33 @@ void Jit64::srawx(UGeckoInstruction inst)
gpr.SetImmediate32(a, 0);
FinalizeCarry(false);
}
+ else if (cpu_info.bBMI2)
+ {
+ RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
+ RCX64Reg Rb = gpr.Bind(b, RCMode::Read);
+ RCOpArg Rs = gpr.Use(s, RCMode::Read);
+ RegCache::Realize(Ra, Rb, Rs);
+
+ 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);
+ 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