OpCode32SimdBase.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. using System;
  2. namespace ARMeilleure.Decoders
  3. {
  4. abstract class OpCode32SimdBase : OpCode32, IOpCode32Simd
  5. {
  6. public int Vd { get; protected set; }
  7. public int Vm { get; protected set; }
  8. public int Size { get; protected set; }
  9. // Helpers to index doublewords within quad words. Essentially, looping over the vector starts at quadword Q and index Fx or Ix within it,
  10. // depending on instruction type.
  11. //
  12. // Qx: The quadword register that the target vector is contained in.
  13. // Ix: The starting index of the target vector within the quadword, with size treated as integer.
  14. // Fx: The starting index of the target vector within the quadword, with size treated as floating point. (16 or 32)
  15. public int Qd => GetQuadwordIndex(Vd);
  16. public int Id => GetQuadwordSubindex(Vd) << (3 - Size);
  17. 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.
  18. public int Qm => GetQuadwordIndex(Vm);
  19. public int Im => GetQuadwordSubindex(Vm) << (3 - Size);
  20. public int Fm => GetQuadwordSubindex(Vm) << (1 - (Size & 1));
  21. protected int GetQuadwordIndex(int index)
  22. {
  23. switch (RegisterSize)
  24. {
  25. case RegisterSize.Simd128:
  26. case RegisterSize.Simd64:
  27. return index >> 1;
  28. }
  29. throw new InvalidOperationException();
  30. }
  31. protected int GetQuadwordSubindex(int index)
  32. {
  33. switch (RegisterSize)
  34. {
  35. case RegisterSize.Simd128:
  36. return 0;
  37. case RegisterSize.Simd64:
  38. return index & 1;
  39. }
  40. throw new InvalidOperationException();
  41. }
  42. public OpCode32SimdBase(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { }
  43. }
  44. }