diff options
| author | degasus <wickmarkus@web.de> | 2015-08-26 19:26:07 +0200 |
|---|---|---|
| committer | degasus <wickmarkus@web.de> | 2015-08-26 21:59:10 +0200 |
| commit | e516d4ef590afc013e7bc81f3f7fe89bf3766cf5 (patch) | |
| tree | cead4464575c1a0f0666e42bfcdff833b0de9d9a /Source/Core | |
| parent | 3e9dac39101798e51228e4396adfc4b5241ba472 (diff) | |
JitArm64: Implement rlwnmx
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/PowerPC/JitArm64/Jit.h | 1 | ||||
| -rw-r--r-- | Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 37 | ||||
| -rw-r--r-- | Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp | 2 |
3 files changed, 39 insertions, 1 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index 81087588cc..1d7276bc0b 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -90,6 +90,7 @@ public: void cmpi(UGeckoInstruction inst); void cmpli(UGeckoInstruction inst); void rlwinmx(UGeckoInstruction inst); + void rlwnmx(UGeckoInstruction inst); void srawix(UGeckoInstruction inst); void mullwx(UGeckoInstruction inst); void addic(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index c9d6bafaef..befcf84643 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -533,6 +533,43 @@ void JitArm64::rlwinmx(UGeckoInstruction inst) ComputeRC(gpr.R(a), 0); } +void JitArm64::rlwnmx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITIntegerOff); + u32 a = inst.RA, b = inst.RB, s = inst.RS; + u32 mask = Helper_Mask(inst.MB, inst.ME); + + if (gpr.IsImm(b) && gpr.IsImm(s)) + { + gpr.SetImmediate(a, _rotl(gpr.GetImm(s), gpr.GetImm(b) & 0x1F) & mask); + if (inst.Rc) + ComputeRC(gpr.GetImm(a), 0); + } + else if (gpr.IsImm(b)) + { + gpr.BindToRegister(a, a == s); + ARM64Reg WA = gpr.GetReg(); + ArithOption Shift(gpr.R(s), ST_ROR, 32 - (gpr.GetImm(b) & 0x1f)); + MOVI2R(WA, mask); + AND(gpr.R(a), WA, gpr.R(s), Shift); + gpr.Unlock(WA); + if (inst.Rc) + ComputeRC(gpr.R(a), 0); + } + else + { + gpr.BindToRegister(a, a == s || a == b); + ARM64Reg WA = gpr.GetReg(); + NEG(WA, gpr.R(b)); + RORV(gpr.R(a), gpr.R(s), WA); + ANDI2R(gpr.R(a), gpr.R(a), mask, WA); + gpr.Unlock(WA); + if (inst.Rc) + ComputeRC(gpr.R(a), 0); + } +} + void JitArm64::srawix(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 a3383f5678..8e0432658e 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -54,7 +54,7 @@ static GekkoOPTemplate primarytable[] = {20, &JitArm64::rlwimix}, // rlwimix {21, &JitArm64::rlwinmx}, // rlwinmx - {23, &JitArm64::FallBackToInterpreter}, // rlwnmx + {23, &JitArm64::rlwnmx}, // rlwnmx {24, &JitArm64::arith_imm}, // ori {25, &JitArm64::arith_imm}, // oris |
