OpCodeSimdMemSs64.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using ChocolArm64.Instructions;
  2. namespace ChocolArm64.Decoders
  3. {
  4. class OpCodeSimdMemSs64 : OpCodeMemReg64, IOpCodeSimd64
  5. {
  6. public int SElems { get; private set; }
  7. public int Index { get; private set; }
  8. public bool Replicate { get; private set; }
  9. public bool WBack { get; private set; }
  10. public OpCodeSimdMemSs64(Inst inst, long position, int opCode) : base(inst, position, 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. inst = Inst.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. inst = Inst.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. inst = Inst.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. ? State.RegisterSize.Simd128
  71. : State.RegisterSize.Simd64;
  72. }
  73. }
  74. }