aboutsummaryrefslogtreecommitdiff
path: root/src/ARMeilleure/Decoders/OpCode32SimdBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ARMeilleure/Decoders/OpCode32SimdBase.cs')
-rw-r--r--src/ARMeilleure/Decoders/OpCode32SimdBase.cs55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/ARMeilleure/Decoders/OpCode32SimdBase.cs b/src/ARMeilleure/Decoders/OpCode32SimdBase.cs
new file mode 100644
index 00000000..4382fc2a
--- /dev/null
+++ b/src/ARMeilleure/Decoders/OpCode32SimdBase.cs
@@ -0,0 +1,55 @@
+using System;
+
+namespace ARMeilleure.Decoders
+{
+ abstract class OpCode32SimdBase : OpCode32, IOpCode32Simd
+ {
+ public int Vd { get; protected set; }
+ public int Vm { get; protected set; }
+ public int Size { get; protected set; }
+
+ // Helpers to index doublewords within quad words. Essentially, looping over the vector starts at quadword Q and index Fx or Ix within it,
+ // depending on instruction type.
+ //
+ // Qx: The quadword register that the target vector is contained in.
+ // Ix: The starting index of the target vector within the quadword, with size treated as integer.
+ // Fx: The starting index of the target vector within the quadword, with size treated as floating point. (16 or 32)
+ public int Qd => GetQuadwordIndex(Vd);
+ public int Id => GetQuadwordSubindex(Vd) << (3 - Size);
+ public int Fd => GetQuadwordSubindex(Vd) << (1 - (Size & 1)); // When the top bit is truncated, 1 is fp16 which is an optional extension in ARMv8.2. We always assume 64.
+
+ public int Qm => GetQuadwordIndex(Vm);
+ public int Im => GetQuadwordSubindex(Vm) << (3 - Size);
+ public int Fm => GetQuadwordSubindex(Vm) << (1 - (Size & 1));
+
+ protected int GetQuadwordIndex(int index)
+ {
+ switch (RegisterSize)
+ {
+ case RegisterSize.Simd128:
+ case RegisterSize.Simd64:
+ return index >> 1;
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ protected int GetQuadwordSubindex(int index)
+ {
+ switch (RegisterSize)
+ {
+ case RegisterSize.Simd128:
+ return 0;
+ case RegisterSize.Simd64:
+ return index & 1;
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ protected OpCode32SimdBase(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode)
+ {
+ IsThumb = isThumb;
+ }
+ }
+}