aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Decoders/OpCodeSimdMemSs.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Decoders/OpCodeSimdMemSs.cs')
-rw-r--r--ARMeilleure/Decoders/OpCodeSimdMemSs.cs95
1 files changed, 95 insertions, 0 deletions
diff --git a/ARMeilleure/Decoders/OpCodeSimdMemSs.cs b/ARMeilleure/Decoders/OpCodeSimdMemSs.cs
new file mode 100644
index 00000000..302decbc
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeSimdMemSs.cs
@@ -0,0 +1,95 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeSimdMemSs : OpCodeMemReg, IOpCodeSimd
+ {
+ public int SElems { get; private set; }
+ public int Index { get; private set; }
+ public bool Replicate { get; private set; }
+ public bool WBack { get; private set; }
+
+ public OpCodeSimdMemSs(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ int size = (opCode >> 10) & 3;
+ int s = (opCode >> 12) & 1;
+ int sElems = (opCode >> 12) & 2;
+ int scale = (opCode >> 14) & 3;
+ int l = (opCode >> 22) & 1;
+ int q = (opCode >> 30) & 1;
+
+ sElems |= (opCode >> 21) & 1;
+
+ sElems++;
+
+ int index = (q << 3) | (s << 2) | size;
+
+ switch (scale)
+ {
+ case 1:
+ {
+ if ((size & 1) != 0)
+ {
+ Instruction = InstDescriptor.Undefined;
+
+ return;
+ }
+
+ index >>= 1;
+
+ break;
+ }
+
+ case 2:
+ {
+ if ((size & 2) != 0 ||
+ ((size & 1) != 0 && s != 0))
+ {
+ Instruction = InstDescriptor.Undefined;
+
+ return;
+ }
+
+ if ((size & 1) != 0)
+ {
+ index >>= 3;
+
+ scale = 3;
+ }
+ else
+ {
+ index >>= 2;
+ }
+
+ break;
+ }
+
+ case 3:
+ {
+ if (l == 0 || s != 0)
+ {
+ Instruction = InstDescriptor.Undefined;
+
+ return;
+ }
+
+ scale = size;
+
+ Replicate = true;
+
+ break;
+ }
+ }
+
+ Index = index;
+ SElems = sElems;
+ Size = scale;
+
+ Extend64 = false;
+
+ WBack = ((opCode >> 23) & 1) != 0;
+
+ RegisterSize = q != 0
+ ? RegisterSize.Simd128
+ : RegisterSize.Simd64;
+ }
+ }
+} \ No newline at end of file