diff options
author | gdkchan <gab.dark.100@gmail.com> | 2024-01-20 11:11:28 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-20 11:11:28 -0300 |
commit | 427b7d06b5ab6d2b06784a9d283eaf836a04c27e (patch) | |
tree | b69b500432626c89f6a4b7171a948b46c46b3723 /src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs | |
parent | 331c07807fd0db5d4452d6ef02962a6d19a56d7f (diff) |
Implement a new JIT for Arm devices (#6057)1.1.1117
* Implement a new JIT for Arm devices
* Auto-format
* Make a lot of Assembler members read-only
* More read-only
* Fix more warnings
* ObjectDisposedException.ThrowIf
* New JIT cache for platforms that enforce W^X, currently unused
* Remove unused using
* Fix assert
* Pass memory manager type around
* Safe memory manager mode support + other improvements
* Actual safe memory manager mode masking support
* PR feedback
Diffstat (limited to 'src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs')
-rw-r--r-- | src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs b/src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs new file mode 100644 index 00000000..6567efee --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs @@ -0,0 +1,96 @@ +using System.Collections.Generic; +using System.Numerics; + +namespace Ryujinx.Cpu.LightningJit.Table +{ + class InstTableLevel<T> where T : IInstInfo + { + private readonly int _shift; + private readonly uint _mask; + private readonly InstTableLevel<T>[] _childs; + private readonly List<T> _insts; + + private InstTableLevel(List<T> insts, uint baseMask) + { + uint commonEncodingMask = baseMask; + + foreach (T info in insts) + { + commonEncodingMask &= info.EncodingMask; + } + + if (commonEncodingMask != 0) + { + _shift = BitOperations.TrailingZeroCount(commonEncodingMask); + int bits = BitOperations.TrailingZeroCount(~(commonEncodingMask >> _shift)); + int count = 1 << bits; + _mask = uint.MaxValue >> (32 - bits); + + _childs = new InstTableLevel<T>[count]; + + List<T>[] splitList = new List<T>[count]; + + for (int index = 0; index < insts.Count; index++) + { + int splitIndex = (int)((insts[index].Encoding >> _shift) & _mask); + + (splitList[splitIndex] ??= new()).Add(insts[index]); + } + + for (int index = 0; index < count; index++) + { + if (splitList[index] == null) + { + continue; + } + + _childs[index] = new InstTableLevel<T>(splitList[index], baseMask & ~commonEncodingMask); + } + } + else + { + _insts = insts; + } + } + + public InstTableLevel(List<T> insts) : this(insts, uint.MaxValue) + { + } + + public bool TryFind(uint encoding, IsaVersion version, IsaFeature features, out T value) + { + if (_childs != null) + { + int index = (int)((encoding >> _shift) & _mask); + + if (_childs[index] == null) + { + value = default; + + return false; + } + + return _childs[index].TryFind(encoding, version, features, out value); + } + else + { + foreach (T info in _insts) + { + if ((encoding & info.EncodingMask) == info.Encoding && + !info.IsConstrained(encoding) && + info.Version <= version && + (info.Feature & features) == info.Feature) + { + value = info; + + return true; + } + } + + value = default; + + return false; + } + } + } +} |