Block.cs 2.3 KB

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