AOpCodeSimdMemSs.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using ChocolArm64.Instruction;
  2. using ChocolArm64.State;
  3. namespace ChocolArm64.Decoder
  4. {
  5. class AOpCodeSimdMemSs : AOpCodeMemReg, IAOpCodeSimd
  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 AOpCodeSimdMemSs(AInst 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 0: Index >>= 0; break;
  25. case 1:
  26. {
  27. if ((Index & 1) != 0)
  28. {
  29. Inst = AInst.Undefined;
  30. return;
  31. }
  32. Index >>= 1;
  33. break;
  34. }
  35. case 2:
  36. {
  37. if ((Index & 2) != 0 ||
  38. ((Index & 1) != 0 && S != 0))
  39. {
  40. Inst = AInst.Undefined;
  41. return;
  42. }
  43. if ((Index & 1) != 0)
  44. {
  45. Index >>= 3;
  46. }
  47. else
  48. {
  49. Index >>= 2;
  50. Scale = 3;
  51. }
  52. break;
  53. }
  54. case 3:
  55. {
  56. if (L == 0 || S != 0)
  57. {
  58. Inst = AInst.Undefined;
  59. return;
  60. }
  61. Scale = Size;
  62. Replicate = true;
  63. break;
  64. }
  65. }
  66. this.SElems = SElems;
  67. this.Size = Scale;
  68. WBack = ((OpCode >> 23) & 0x1) != 0;
  69. RegisterSize = Q != 0
  70. ? ARegisterSize.SIMD128
  71. : ARegisterSize.SIMD64;
  72. }
  73. }
  74. }