summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2015-08-26 19:26:07 +0200
committerdegasus <wickmarkus@web.de>2015-08-26 21:59:10 +0200
commite516d4ef590afc013e7bc81f3f7fe89bf3766cf5 (patch)
treecead4464575c1a0f0666e42bfcdff833b0de9d9a /Source/Core
parent3e9dac39101798e51228e4396adfc4b5241ba472 (diff)
JitArm64: Implement rlwnmx
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.h1
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp37
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp2
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