Block.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Ryujinx.Graphics.Shader.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<OpCode> OpCodes { get; }
  12. public List<OpCodeSsy> SsyOpCodes { get; }
  13. public Block(ulong address)
  14. {
  15. Address = address;
  16. OpCodes = new List<OpCode>();
  17. SsyOpCodes = new List<OpCodeSsy>();
  18. }
  19. public void Split(Block rightBlock)
  20. {
  21. int splitIndex = BinarySearch(OpCodes, rightBlock.Address);
  22. if (OpCodes[splitIndex].Address < rightBlock.Address)
  23. {
  24. splitIndex++;
  25. }
  26. int splitCount = OpCodes.Count - splitIndex;
  27. if (splitCount <= 0)
  28. {
  29. throw new ArgumentException("Can't split at right block address.");
  30. }
  31. rightBlock.EndAddress = EndAddress;
  32. rightBlock.Next = Next;
  33. rightBlock.Branch = Branch;
  34. rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
  35. rightBlock.UpdateSsyOpCodes();
  36. EndAddress = rightBlock.Address;
  37. Next = rightBlock;
  38. Branch = null;
  39. OpCodes.RemoveRange(splitIndex, splitCount);
  40. UpdateSsyOpCodes();
  41. }
  42. private static int BinarySearch(List<OpCode> opCodes, ulong address)
  43. {
  44. int left = 0;
  45. int middle = 0;
  46. int right = opCodes.Count - 1;
  47. while (left <= right)
  48. {
  49. int size = right - left;
  50. middle = left + (size >> 1);
  51. OpCode opCode = opCodes[middle];
  52. if (address == opCode.Address)
  53. {
  54. break;
  55. }
  56. if (address < opCode.Address)
  57. {
  58. right = middle - 1;
  59. }
  60. else
  61. {
  62. left = middle + 1;
  63. }
  64. }
  65. return middle;
  66. }
  67. public OpCode GetLastOp()
  68. {
  69. if (OpCodes.Count != 0)
  70. {
  71. return OpCodes[OpCodes.Count - 1];
  72. }
  73. return null;
  74. }
  75. public void UpdateSsyOpCodes()
  76. {
  77. SsyOpCodes.Clear();
  78. for (int index = 0; index < OpCodes.Count; index++)
  79. {
  80. if (!(OpCodes[index] is OpCodeSsy op))
  81. {
  82. continue;
  83. }
  84. SsyOpCodes.Add(op);
  85. }
  86. }
  87. }
  88. }