Block.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using System;
  2. using System.Collections.Generic;
  3. namespace ARMeilleure.Decoders
  4. {
  5. class Block
  6. {
  7. public ulong Address { get; set; }
  8. public ulong EndAddress { get; set; }
  9. public Block Next { get; set; }
  10. public Block Branch { get; set; }
  11. public bool TailCall { get; set; }
  12. public bool Exit { get; set; }
  13. public List<OpCode> OpCodes { get; private set; }
  14. public Block()
  15. {
  16. OpCodes = new List<OpCode>();
  17. }
  18. public Block(ulong address) : this()
  19. {
  20. Address = address;
  21. }
  22. public void Split(Block rightBlock)
  23. {
  24. int splitIndex = BinarySearch(OpCodes, rightBlock.Address);
  25. if (OpCodes[splitIndex].Address < rightBlock.Address)
  26. {
  27. splitIndex++;
  28. }
  29. int splitCount = OpCodes.Count - splitIndex;
  30. if (splitCount <= 0)
  31. {
  32. throw new ArgumentException("Can't split at right block address.");
  33. }
  34. rightBlock.EndAddress = EndAddress;
  35. rightBlock.Next = Next;
  36. rightBlock.Branch = Branch;
  37. rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
  38. EndAddress = rightBlock.Address;
  39. Next = rightBlock;
  40. Branch = null;
  41. OpCodes.RemoveRange(splitIndex, splitCount);
  42. }
  43. private static int BinarySearch(List<OpCode> opCodes, ulong address)
  44. {
  45. int left = 0;
  46. int middle = 0;
  47. int right = opCodes.Count - 1;
  48. while (left <= right)
  49. {
  50. int size = right - left;
  51. middle = left + (size >> 1);
  52. OpCode opCode = opCodes[middle];
  53. if (address == (ulong)opCode.Address)
  54. {
  55. break;
  56. }
  57. if (address < (ulong)opCode.Address)
  58. {
  59. right = middle - 1;
  60. }
  61. else
  62. {
  63. left = middle + 1;
  64. }
  65. }
  66. return middle;
  67. }
  68. public OpCode GetLastOp()
  69. {
  70. if (OpCodes.Count > 0)
  71. {
  72. return OpCodes[OpCodes.Count - 1];
  73. }
  74. return null;
  75. }
  76. }
  77. }