OpCodeSimdMemSs64.cs 2.4 KB

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