From 8a7d99cdeae2355511d4eb43aefb76d0d886bcf8 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Fri, 26 Apr 2019 01:55:12 -0300 Subject: 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 * Add back the aggressive inlining attribute to the Synchronize method * Implement IEquatable on the Register struct * Fix identation --- .../IntermediateRepresentation/BasicBlock.cs | 122 +++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 ChocolArm64/IntermediateRepresentation/BasicBlock.cs (limited to 'ChocolArm64/IntermediateRepresentation/BasicBlock.cs') diff --git a/ChocolArm64/IntermediateRepresentation/BasicBlock.cs b/ChocolArm64/IntermediateRepresentation/BasicBlock.cs new file mode 100644 index 00000000..ce39fddb --- /dev/null +++ b/ChocolArm64/IntermediateRepresentation/BasicBlock.cs @@ -0,0 +1,122 @@ +using ChocolArm64.State; +using System; +using System.Collections.Generic; + +using static ChocolArm64.State.RegisterConsts; + +namespace ChocolArm64.IntermediateRepresentation +{ + class BasicBlock + { + public int Index { get; set; } + + public RegisterMask RegInputs { get; private set; } + public RegisterMask RegOutputs { get; private set; } + + public bool HasStateLoad { get; private set; } + + private List _operations; + + public int Count => _operations.Count; + + private BasicBlock _next; + private BasicBlock _branch; + + public BasicBlock Next + { + get => _next; + set => _next = AddSuccessor(_next, value); + } + + public BasicBlock Branch + { + get => _branch; + set => _branch = AddSuccessor(_branch, value); + } + + public List Predecessors { get; } + + public BasicBlock(int index = 0) + { + Index = index; + + _operations = new List(); + + Predecessors = new List(); + } + + private BasicBlock AddSuccessor(BasicBlock oldBlock, BasicBlock newBlock) + { + oldBlock?.Predecessors.Remove(this); + newBlock?.Predecessors.Add(this); + + return newBlock; + } + + public void Add(Operation operation) + { + if (operation.Type == OperationType.LoadLocal || + operation.Type == OperationType.StoreLocal) + { + int index = operation.GetArg(0); + + if (IsRegIndex(index)) + { + long intMask = 0; + long vecMask = 0; + + switch (operation.GetArg(1)) + { + case RegisterType.Flag: intMask = (1L << RegsCount) << index; break; + case RegisterType.Int: intMask = 1L << index; break; + case RegisterType.Vector: vecMask = 1L << index; break; + } + + RegisterMask mask = new RegisterMask(intMask, vecMask); + + if (operation.Type == OperationType.LoadLocal) + { + RegInputs |= mask & ~RegOutputs; + } + else + { + RegOutputs |= mask; + } + } + } + else if (operation.Type == OperationType.LoadContext) + { + HasStateLoad = true; + } + + operation.Parent = this; + + _operations.Add(operation); + } + + public static bool IsRegIndex(int index) + { + return (uint)index < RegsCount; + } + + public Operation GetOperation(int index) + { + if ((uint)index >= _operations.Count) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + return _operations[index]; + } + + public Operation GetLastOp() + { + if (Count == 0) + { + return null; + } + + return _operations[Count - 1]; + } + } +} \ No newline at end of file -- cgit v1.2.3