OpCodeSimdMemSs.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. namespace ARMeilleure.Decoders
  2. {
  3. class OpCodeSimdMemSs : OpCodeMemReg, IOpCodeSimd
  4. {
  5. public int SElems { get; }
  6. public int Index { get; }
  7. public bool Replicate { get; }
  8. public bool WBack { get; }
  9. public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdMemSs(inst, address, opCode);
  10. public OpCodeSimdMemSs(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
  11. {
  12. int size = (opCode >> 10) & 3;
  13. int s = (opCode >> 12) & 1;
  14. int sElems = (opCode >> 12) & 2;
  15. int scale = (opCode >> 14) & 3;
  16. int l = (opCode >> 22) & 1;
  17. int q = (opCode >> 30) & 1;
  18. sElems |= (opCode >> 21) & 1;
  19. sElems++;
  20. int index = (q << 3) | (s << 2) | size;
  21. switch (scale)
  22. {
  23. case 1:
  24. {
  25. if ((size & 1) != 0)
  26. {
  27. Instruction = InstDescriptor.Undefined;
  28. return;
  29. }
  30. index >>= 1;
  31. break;
  32. }
  33. case 2:
  34. {
  35. if ((size & 2) != 0 ||
  36. ((size & 1) != 0 && s != 0))
  37. {
  38. Instruction = InstDescriptor.Undefined;
  39. return;
  40. }
  41. if ((size & 1) != 0)
  42. {
  43. index >>= 3;
  44. scale = 3;
  45. }
  46. else
  47. {
  48. index >>= 2;
  49. }
  50. break;
  51. }
  52. case 3:
  53. {
  54. if (l == 0 || s != 0)
  55. {
  56. Instruction = InstDescriptor.Undefined;
  57. return;
  58. }
  59. scale = size;
  60. Replicate = true;
  61. break;
  62. }
  63. }
  64. Index = index;
  65. SElems = sElems;
  66. Size = scale;
  67. Extend64 = false;
  68. WBack = ((opCode >> 23) & 1) != 0;
  69. RegisterSize = q != 0
  70. ? RegisterSize.Simd128
  71. : RegisterSize.Simd64;
  72. }
  73. }
  74. }