diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2019-04-26 01:55:12 -0300 |
|---|---|---|
| committer | jduncanator <1518948+jduncanator@users.noreply.github.com> | 2019-04-26 14:55:12 +1000 |
| commit | 8a7d99cdeae2355511d4eb43aefb76d0d886bcf8 (patch) | |
| tree | 655d33f4db5dc3eb21c9c4ff5867b1179913585a /ChocolArm64/Decoders/Block.cs | |
| parent | 2b8eac1bcec6d4870776b4f302d9dd7794223642 (diff) | |
Refactoring and optimization on CPU translation (#661)
* Refactoring and optimization on CPU translation
* Remove now unused property
* Rename ilBlock -> block (local)
* Change equality comparison on RegisterMask for consistency
Co-Authored-By: gdkchan <gab.dark.100@gmail.com>
* Add back the aggressive inlining attribute to the Synchronize method
* Implement IEquatable on the Register struct
* Fix identation
Diffstat (limited to 'ChocolArm64/Decoders/Block.cs')
| -rw-r--r-- | ChocolArm64/Decoders/Block.cs | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/ChocolArm64/Decoders/Block.cs b/ChocolArm64/Decoders/Block.cs index c89ea7c6..fc87fd18 100644 --- a/ChocolArm64/Decoders/Block.cs +++ b/ChocolArm64/Decoders/Block.cs @@ -1,11 +1,12 @@ +using System; using System.Collections.Generic; namespace ChocolArm64.Decoders { class Block { - public long Position { get; set; } - public long EndPosition { get; set; } + public ulong Address { get; set; } + public ulong EndAddress { get; set; } public Block Next { get; set; } public Block Branch { get; set; } @@ -17,9 +18,72 @@ namespace ChocolArm64.Decoders OpCodes = new List<OpCode64>(); } - public Block(long position) : this() + public Block(ulong address) : this() { - Position = position; + Address = address; + } + + public void Split(Block rightBlock) + { + int splitIndex = BinarySearch(OpCodes, rightBlock.Address); + + if ((ulong)OpCodes[splitIndex].Position < rightBlock.Address) + { + splitIndex++; + } + + int splitCount = OpCodes.Count - splitIndex; + + if (splitCount <= 0) + { + throw new ArgumentException("Can't split at right block address."); + } + + rightBlock.EndAddress = EndAddress; + + rightBlock.Next = Next; + rightBlock.Branch = Branch; + + rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount)); + + EndAddress = rightBlock.Address; + + Next = rightBlock; + Branch = null; + + OpCodes.RemoveRange(splitIndex, splitCount); + } + + private static int BinarySearch(List<OpCode64> opCodes, ulong address) + { + int left = 0; + int middle = 0; + int right = opCodes.Count - 1; + + while (left <= right) + { + int size = right - left; + + middle = left + (size >> 1); + + OpCode64 opCode = opCodes[middle]; + + if (address == (ulong)opCode.Position) + { + break; + } + + if (address < (ulong)opCode.Position) + { + right = middle - 1; + } + else + { + left = middle + 1; + } + } + + return middle; } public OpCode64 GetLastOp() |
