OpCodeSimdMemSs.cs 2.3 KB

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