AOpCodeSimdMemSs.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. Extend64 = false;
  69. WBack = ((OpCode >> 23) & 0x1) != 0;
  70. RegisterSize = Q != 0
  71. ? ARegisterSize.SIMD128
  72. : ARegisterSize.SIMD64;
  73. }
  74. }
  75. }