summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2015-06-25 20:02:11 -0500
committerRyan Houdek <Sonicadvance1@gmail.com>2015-06-26 00:51:06 -0500
commit63a2180c1f047e7d139ce2a565eaad92dd90f984 (patch)
tree7a29c398a7d62f92af17c354a0ab73559c9f72d4 /Source/Core
parentda7ec7535053f853fb5056d697604dbc73f6ad6e (diff)
[AArch64] Implement slwx in the recompiler.
I streamed this implementation earlier today to get people to have a feel for implementing instructions in the AArch64 recompiler. This one was a fairly simple one to implement.
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.cpp48
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp2
3 files changed, 50 insertions, 1 deletions
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