OpCode32SimdMemMult.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. namespace ARMeilleure.Decoders
  2. {
  3. class OpCode32SimdMemMult : OpCode32
  4. {
  5. public int Rn { get; private set; }
  6. public int Vd { get; private set; }
  7. public int RegisterRange { get; private set; }
  8. public int Offset { get; private set; }
  9. public int PostOffset { get; private set; }
  10. public bool IsLoad { get; private set; }
  11. public bool DoubleWidth { get; private set; }
  12. public bool Add { get; private set; }
  13. public OpCode32SimdMemMult(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
  14. {
  15. Rn = (opCode >> 16) & 0xf;
  16. bool isLoad = (opCode & (1 << 20)) != 0;
  17. bool w = (opCode & (1 << 21)) != 0;
  18. bool u = (opCode & (1 << 23)) != 0;
  19. bool p = (opCode & (1 << 24)) != 0;
  20. if (p == u && w)
  21. {
  22. Instruction = InstDescriptor.Undefined;
  23. return;
  24. }
  25. DoubleWidth = (opCode & (1 << 8)) != 0;
  26. if (!DoubleWidth)
  27. {
  28. Vd = ((opCode >> 22) & 0x1) | ((opCode >> 11) & 0x1e);
  29. }
  30. else
  31. {
  32. Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf);
  33. }
  34. Add = u;
  35. RegisterRange = opCode & 0xff;
  36. int regsSize = RegisterRange * 4; // Double mode is still measured in single register size.
  37. if (!u)
  38. {
  39. Offset -= regsSize;
  40. }
  41. if (w)
  42. {
  43. PostOffset = u ? regsSize : -regsSize;
  44. }
  45. else
  46. {
  47. PostOffset = 0;
  48. }
  49. IsLoad = isLoad;
  50. int regs = DoubleWidth ? RegisterRange / 2 : RegisterRange;
  51. if (RegisterRange == 0 || RegisterRange > 32 || Vd + regs > 32)
  52. {
  53. Instruction = InstDescriptor.Undefined;
  54. }
  55. }
  56. }
  57. }