AOpCodeSimdMemSs.cs 2.3 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 1:
  25. {
  26. if ((Size & 1) != 0)
  27. {
  28. Inst = AInst.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 = AInst.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 = AInst.Undefined;
  58. return;
  59. }
  60. Scale = Size;
  61. Replicate = true;
  62. break;
  63. }
  64. }
  65. this.SElems = SElems;
  66. this.Size = Scale;
  67. Extend64 = false;
  68. WBack = ((OpCode >> 23) & 0x1) != 0;
  69. RegisterSize = Q != 0
  70. ? ARegisterSize.SIMD128
  71. : ARegisterSize.SIMD64;
  72. }
  73. }
  74. }