diff options
| author | Alex Barney <thealexbarney@gmail.com> | 2018-10-30 19:43:02 -0600 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-10-30 22:43:02 -0300 |
| commit | 9cb57fb4bb3bbae0ae052a5af4a96a49fc5d864d (patch) | |
| tree | 0c97425aeb311c142bc92a6fcc503cb2c07d4376 /ChocolArm64/Decoder/ADecoder.cs | |
| parent | 5a87e58183578f5b84ca8d01cbb76aed11820f78 (diff) | |
Adjust naming conventions for Ryujinx and ChocolArm64 projects (#484)
* Change naming convention for Ryujinx project
* Change naming convention for ChocolArm64 project
* Fix NaN
* Remove unneeded this. from Ryujinx project
* Adjust naming from new PRs
* Name changes based on feedback
* How did this get removed?
* Rebasing fix
* Change FP enum case
* Remove prefix from ChocolArm64 classes - Part 1
* Remove prefix from ChocolArm64 classes - Part 2
* Fix alignment from last commit's renaming
* Rename namespaces
* Rename stragglers
* Fix alignment
* Rename OpCode class
* Missed a few
* Adjust alignment
Diffstat (limited to 'ChocolArm64/Decoder/ADecoder.cs')
| -rw-r--r-- | ChocolArm64/Decoder/ADecoder.cs | 239 |
1 files changed, 0 insertions, 239 deletions
diff --git a/ChocolArm64/Decoder/ADecoder.cs b/ChocolArm64/Decoder/ADecoder.cs deleted file mode 100644 index 64beebd2..00000000 --- a/ChocolArm64/Decoder/ADecoder.cs +++ /dev/null @@ -1,239 +0,0 @@ -using ChocolArm64.Instruction; -using ChocolArm64.Memory; -using ChocolArm64.State; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Reflection.Emit; - -namespace ChocolArm64.Decoder -{ - static class ADecoder - { - private delegate object OpActivator(AInst Inst, long Position, int OpCode); - - private static ConcurrentDictionary<Type, OpActivator> OpActivators; - - static ADecoder() - { - OpActivators = new ConcurrentDictionary<Type, OpActivator>(); - } - - public static ABlock DecodeBasicBlock(AThreadState State, AMemory Memory, long Start) - { - ABlock Block = new ABlock(Start); - - FillBlock(State, Memory, Block); - - return Block; - } - - public static (ABlock[] Graph, ABlock Root) DecodeSubroutine( - ATranslatorCache Cache, - AThreadState State, - AMemory Memory, - long Start) - { - Dictionary<long, ABlock> Visited = new Dictionary<long, ABlock>(); - Dictionary<long, ABlock> VisitedEnd = new Dictionary<long, ABlock>(); - - Queue<ABlock> Blocks = new Queue<ABlock>(); - - ABlock Enqueue(long Position) - { - if (!Visited.TryGetValue(Position, out ABlock Output)) - { - Output = new ABlock(Position); - - Blocks.Enqueue(Output); - - Visited.Add(Position, Output); - } - - return Output; - } - - ABlock Root = Enqueue(Start); - - while (Blocks.Count > 0) - { - ABlock Current = Blocks.Dequeue(); - - FillBlock(State, Memory, Current); - - //Set child blocks. "Branch" is the block the branch instruction - //points to (when taken), "Next" is the block at the next address, - //executed when the branch is not taken. For Unconditional Branches - //(except BL/BLR that are sub calls) or end of executable, Next is null. - if (Current.OpCodes.Count > 0) - { - bool HasCachedSub = false; - - AOpCode LastOp = Current.GetLastOp(); - - if (LastOp is AOpCodeBImm Op) - { - if (Op.Emitter == AInstEmit.Bl) - { - HasCachedSub = Cache.HasSubroutine(Op.Imm); - } - else - { - Current.Branch = Enqueue(Op.Imm); - } - } - - if (!((LastOp is AOpCodeBImmAl) || - (LastOp is AOpCodeBReg)) || HasCachedSub) - { - Current.Next = Enqueue(Current.EndPosition); - } - } - - //If we have on the graph two blocks with the same end position, - //then we need to split the bigger block and have two small blocks, - //the end position of the bigger "Current" block should then be == to - //the position of the "Smaller" block. - while (VisitedEnd.TryGetValue(Current.EndPosition, out ABlock Smaller)) - { - if (Current.Position > Smaller.Position) - { - ABlock Temp = Smaller; - - Smaller = Current; - Current = Temp; - } - - Current.EndPosition = Smaller.Position; - Current.Next = Smaller; - Current.Branch = null; - - Current.OpCodes.RemoveRange( - Current.OpCodes.Count - Smaller.OpCodes.Count, - Smaller.OpCodes.Count); - - VisitedEnd[Smaller.EndPosition] = Smaller; - } - - VisitedEnd.Add(Current.EndPosition, Current); - } - - //Make and sort Graph blocks array by position. - ABlock[] Graph = new ABlock[Visited.Count]; - - while (Visited.Count > 0) - { - ulong FirstPos = ulong.MaxValue; - - foreach (ABlock Block in Visited.Values) - { - if (FirstPos > (ulong)Block.Position) - FirstPos = (ulong)Block.Position; - } - - ABlock Current = Visited[(long)FirstPos]; - - do - { - Graph[Graph.Length - Visited.Count] = Current; - - Visited.Remove(Current.Position); - - Current = Current.Next; - } - while (Current != null); - } - - return (Graph, Root); - } - - private static void FillBlock(AThreadState State, AMemory Memory, ABlock Block) - { - long Position = Block.Position; - - AOpCode OpCode; - - do - { - //TODO: This needs to be changed to support both AArch32 and AArch64, - //once JIT support is introduced on AArch32 aswell. - OpCode = DecodeOpCode(State, Memory, Position); - - Block.OpCodes.Add(OpCode); - - Position += 4; - } - while (!(IsBranch(OpCode) || IsException(OpCode))); - - Block.EndPosition = Position; - } - - private static bool IsBranch(AOpCode OpCode) - { - return OpCode is AOpCodeBImm || - OpCode is AOpCodeBReg; - } - - private static bool IsException(AOpCode OpCode) - { - return OpCode.Emitter == AInstEmit.Brk || - OpCode.Emitter == AInstEmit.Svc || - OpCode.Emitter == AInstEmit.Und; - } - - public static AOpCode DecodeOpCode(AThreadState State, AMemory Memory, long Position) - { - int OpCode = Memory.ReadInt32(Position); - - AInst Inst; - - if (State.ExecutionMode == AExecutionMode.AArch64) - { - Inst = AOpCodeTable.GetInstA64(OpCode); - } - else - { - //TODO: Thumb support. - Inst = AOpCodeTable.GetInstA32(OpCode); - } - - AOpCode DecodedOpCode = new AOpCode(AInst.Undefined, Position, OpCode); - - if (Inst.Type != null) - { - DecodedOpCode = MakeOpCode(Inst.Type, Inst, Position, OpCode); - } - - return DecodedOpCode; - } - - private static AOpCode MakeOpCode(Type Type, AInst Inst, long Position, int OpCode) - { - if (Type == null) - { - throw new ArgumentNullException(nameof(Type)); - } - - OpActivator CreateInstance = OpActivators.GetOrAdd(Type, CacheOpActivator); - - return (AOpCode)CreateInstance(Inst, Position, OpCode); - } - - private static OpActivator CacheOpActivator(Type Type) - { - Type[] ArgTypes = new Type[] { typeof(AInst), typeof(long), typeof(int) }; - - DynamicMethod Mthd = new DynamicMethod($"Make{Type.Name}", Type, ArgTypes); - - ILGenerator Generator = Mthd.GetILGenerator(); - - Generator.Emit(OpCodes.Ldarg_0); - Generator.Emit(OpCodes.Ldarg_1); - Generator.Emit(OpCodes.Ldarg_2); - Generator.Emit(OpCodes.Newobj, Type.GetConstructor(ArgTypes)); - Generator.Emit(OpCodes.Ret); - - return (OpActivator)Mthd.CreateDelegate(typeof(OpActivator)); - } - } -}
\ No newline at end of file |
