diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index 55c7b86435..639892e441 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -97,6 +97,7 @@ public: void addzex(UGeckoInstruction inst); void subfx(UGeckoInstruction inst); void addcx(UGeckoInstruction inst); + void slwx(UGeckoInstruction inst); // System Registers void mtmsr(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index e20f07a61d..86d85cedb8 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -718,3 +718,51 @@ void JitArm64::addcx(UGeckoInstruction inst) ComputeRC(gpr.R(d), 0); } } + +void JitArm64::slwx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITIntegerOff); + + int a = inst.RA, b = inst.RB, s = inst.RS; + + if (gpr.IsImm(b) && gpr.IsImm(s)) + { + u32 i = gpr.GetImm(s), j = gpr.GetImm(b); + gpr.SetImmediate(a, (j & 0x20) ? 0 : i << (j & 0x1F)); + + if (inst.Rc) + ComputeRC(gpr.GetImm(a), 0); + } + else if (gpr.IsImm(b)) + { + u32 i = gpr.GetImm(b); + if (i & 0x20) + { + gpr.SetImmediate(a, 0); + if (inst.Rc) + ComputeRC(0, 0); + } + else + { + gpr.BindToRegister(a, a == s); + LSL(gpr.R(a), gpr.R(s), i & 0x1F); + if (inst.Rc) + ComputeRC(gpr.R(a), 0); + } + } + else + { + gpr.BindToRegister(a, a == b || a == s); + + // PowerPC any shift in the 32-63 register range results in zero + // Since it has 32bit registers + // AArch64 it will use a mask of the register size for determining what shift amount + // So if we use a 64bit so the bits will end up in the high 32bits, and + // Later instructions will just eat high 32bits since it'll run 32bit operations for everything. + LSLV(EncodeRegTo64(gpr.R(a)), EncodeRegTo64(gpr.R(s)), EncodeRegTo64(gpr.R(b))); + + if (inst.Rc) + ComputeRC(gpr.R(a), 0); + } +} diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index fa5ed296ff..b25eb6ec50 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -218,7 +218,7 @@ static GekkoOPTemplate table31[] = {536, &JitArm64::FallBackToInterpreter}, // srwx {792, &JitArm64::FallBackToInterpreter}, // srawx {824, &JitArm64::srawix}, // srawix - {24, &JitArm64::FallBackToInterpreter}, // slwx + {24, &JitArm64::slwx}, // slwx {54, &JitArm64::FallBackToInterpreter}, // dcbst {86, &JitArm64::FallBackToInterpreter}, // dcbf