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