diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index 22d515e32b..c06cc122b7 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -98,6 +98,7 @@ public: void subfx(UGeckoInstruction inst); void addcx(UGeckoInstruction inst); void slwx(UGeckoInstruction inst); + void srwx(UGeckoInstruction inst); void rlwimix(UGeckoInstruction inst); void subfex(UGeckoInstruction inst); void subfcx(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 70bed8e6c3..c9d6bafaef 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -1011,6 +1011,52 @@ void JitArm64::slwx(UGeckoInstruction inst) } } +void JitArm64::srwx(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), amount = gpr.GetImm(b); + gpr.SetImmediate(a, (amount & 0x20) ? 0 : i >> (amount & 0x1F)); + + if (inst.Rc) + ComputeRC(gpr.GetImm(a), 0); + } + else if (gpr.IsImm(b)) + { + u32 amount = gpr.GetImm(b); + if (amount & 0x20) + { + gpr.SetImmediate(a, 0); + if (inst.Rc) + ComputeRC(0, 0); + } + else + { + gpr.BindToRegister(a, a == s); + LSR(gpr.R(a), gpr.R(s), amount & 0x1F); + if (inst.Rc) + ComputeRC(gpr.R(a), 0); + } + } + else + { + gpr.BindToRegister(a, a == b || a == s); + + // wipe upper bits. TODO: get rid of it, but then no instruction is allowed to emit some higher bits. + MOV(gpr.R(s), gpr.R(s)); + + LSRV(EncodeRegTo64(gpr.R(a)), EncodeRegTo64(gpr.R(s)), EncodeRegTo64(gpr.R(b))); + + if (inst.Rc) + ComputeRC(gpr.R(a), 0); + } +} + void JitArm64::rlwimix(UGeckoInstruction inst) { INSTRUCTION_START diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index 80a8e9c22a..2aea4fc737 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -214,7 +214,7 @@ static GekkoOPTemplate table31[] = {26, &JitArm64::cntlzwx}, // cntlzwx {922, &JitArm64::extsXx}, // extshx {954, &JitArm64::extsXx}, // extsbx - {536, &JitArm64::FallBackToInterpreter}, // srwx + {536, &JitArm64::srwx}, // srwx {792, &JitArm64::FallBackToInterpreter}, // srawx {824, &JitArm64::srawix}, // srawix {24, &JitArm64::slwx}, // slwx