diff options
Diffstat (limited to 'ARMeilleure/IntermediateRepresentation')
6 files changed, 303 insertions, 63 deletions
diff --git a/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs b/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs index 742842fa..56d07288 100644 --- a/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs +++ b/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs @@ -5,21 +5,25 @@ namespace ARMeilleure.IntermediateRepresentation public Operand BaseAddress { get; set; } public Operand Index { get; set; } - public Multiplier Scale { get; } + public Multiplier Scale { get; private set; } - public int Displacement { get; } + public int Displacement { get; private set; } - public MemoryOperand( + public MemoryOperand() { } + + public MemoryOperand With( OperandType type, Operand baseAddress, Operand index = null, Multiplier scale = Multiplier.x1, - int displacement = 0) : base(OperandKind.Memory, type) + int displacement = 0) { + With(OperandKind.Memory, type); BaseAddress = baseAddress; Index = index; Scale = scale; Displacement = displacement; + return this; } } }
\ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/Node.cs b/ARMeilleure/IntermediateRepresentation/Node.cs index 37647c56..9ce78c09 100644 --- a/ARMeilleure/IntermediateRepresentation/Node.cs +++ b/ARMeilleure/IntermediateRepresentation/Node.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace ARMeilleure.IntermediateRepresentation { @@ -11,39 +12,80 @@ namespace ARMeilleure.IntermediateRepresentation { get { - return _destinations.Length != 0 ? GetDestination(0) : null; + return _destinations.Count != 0 ? GetDestination(0) : null; } set { if (value != null) { - SetDestinations(new Operand[] { value }); + SetDestination(value); } else { - SetDestinations(new Operand[0]); + _destinations.Clear(); } } } - private Operand[] _destinations; - private Operand[] _sources; + private List<Operand> _destinations; + private List<Operand> _sources; + private bool _clearedDest; - public int DestinationsCount => _destinations.Length; - public int SourcesCount => _sources.Length; + public int DestinationsCount => _destinations.Count; + public int SourcesCount => _sources.Count; - public Node(Operand destination, int sourcesCount) + private void Resize(List<Operand> list, int size) { + if (list.Count > size) + { + list.RemoveRange(size, list.Count - size); + } + else + { + while (list.Count < size) + { + list.Add(null); + } + } + } + + public Node() + { + _destinations = new List<Operand>(); + _sources = new List<Operand>(); + } + + public Node(Operand destination, int sourcesCount) : this() + { + Destination = destination; + + Resize(_sources, sourcesCount); + } + + private void Reset(int sourcesCount) + { + _clearedDest = true; + _sources.Clear(); + ListPrevious = null; + ListNext = null; + + Resize(_sources, sourcesCount); + } + + public Node With(Operand destination, int sourcesCount) + { + Reset(sourcesCount); Destination = destination; - _sources = new Operand[sourcesCount]; + return this; } - public Node(Operand[] destinations, int sourcesCount) + public Node With(Operand[] destinations, int sourcesCount) { + Reset(sourcesCount); SetDestinations(destinations ?? throw new ArgumentNullException(nameof(destinations))); - _sources = new Operand[sourcesCount]; + return this; } public Operand GetDestination(int index) @@ -58,10 +100,15 @@ namespace ARMeilleure.IntermediateRepresentation public void SetDestination(int index, Operand destination) { - RemoveAssignment(_destinations[index]); + if (!_clearedDest) + { + RemoveAssignment(_destinations[index]); + } AddAssignment(destination); + _clearedDest = false; + _destinations[index] = destination; } @@ -74,21 +121,37 @@ namespace ARMeilleure.IntermediateRepresentation _sources[index] = source; } - public void SetDestinations(Operand[] destinations) + private void RemoveOldDestinations() { - if (_destinations != null) + if (_destinations != null && !_clearedDest) { - for (int index = 0; index < _destinations.Length; index++) + for (int index = 0; index < _destinations.Count; index++) { RemoveAssignment(_destinations[index]); } - - _destinations = destinations; } - else + _clearedDest = false; + } + + public void SetDestination(Operand destination) + { + RemoveOldDestinations(); + + Resize(_destinations, 1); + + _destinations[0] = destination; + + if (destination.Kind == OperandKind.LocalVariable) { - _destinations = new Operand[destinations.Length]; + destination.Assignments.Add(this); } + } + + public void SetDestinations(Operand[] destinations) + { + RemoveOldDestinations(); + + Resize(_destinations, destinations.Length); for (int index = 0; index < destinations.Length; index++) { @@ -100,14 +163,33 @@ namespace ARMeilleure.IntermediateRepresentation } } - public void SetSources(Operand[] sources) + private void RemoveOldSources() { - for (int index = 0; index < _sources.Length; index++) + for (int index = 0; index < _sources.Count; index++) { RemoveUse(_sources[index]); } + } + + public void SetSource(Operand source) + { + RemoveOldSources(); + + Resize(_sources, 1); + + _sources[0] = source; + + if (source.Kind == OperandKind.LocalVariable) + { + source.Uses.Add(this); + } + } + + public void SetSources(Operand[] sources) + { + RemoveOldSources(); - _sources = new Operand[sources.Length]; + Resize(_sources, sources.Length); for (int index = 0; index < sources.Length; index++) { diff --git a/ARMeilleure/IntermediateRepresentation/Operand.cs b/ARMeilleure/IntermediateRepresentation/Operand.cs index fe5bf073..2d5e762a 100644 --- a/ARMeilleure/IntermediateRepresentation/Operand.cs +++ b/ARMeilleure/IntermediateRepresentation/Operand.cs @@ -5,16 +5,16 @@ namespace ARMeilleure.IntermediateRepresentation { class Operand { - public OperandKind Kind { get; } + public OperandKind Kind { get; private set; } - public OperandType Type { get; } + public OperandType Type { get; private set; } public ulong Value { get; private set; } public List<Node> Assignments { get; } public List<Node> Uses { get; } - private Operand() + public Operand() { Assignments = new List<Node>(); Uses = new List<Node>(); @@ -26,42 +26,50 @@ namespace ARMeilleure.IntermediateRepresentation Type = type; } - public Operand(int value) : this(OperandKind.Constant, OperandType.I32) + public Operand With(OperandKind kind, OperandType type = OperandType.None, ulong value = 0) { - Value = (uint)value; + Kind = kind; + Type = type; + Value = value; + + Assignments.Clear(); + Uses.Clear(); + return this; } - public Operand(uint value) : this(OperandKind.Constant, OperandType.I32) + public Operand With(int value) { - Value = (uint)value; + return With(OperandKind.Constant, OperandType.I32, (uint)value); } - public Operand(long value) : this(OperandKind.Constant, OperandType.I64) + public Operand With(uint value) { - Value = (ulong)value; + return With(OperandKind.Constant, OperandType.I32, value); } - public Operand(ulong value) : this(OperandKind.Constant, OperandType.I64) + public Operand With(long value) { - Value = value; + return With(OperandKind.Constant, OperandType.I64, (ulong)value); } - public Operand(float value) : this(OperandKind.Constant, OperandType.FP32) + public Operand With(ulong value) { - Value = (ulong)BitConverter.SingleToInt32Bits(value); + return With(OperandKind.Constant, OperandType.I64, value); } - public Operand(double value) : this(OperandKind.Constant, OperandType.FP64) + public Operand With(float value) { - Value = (ulong)BitConverter.DoubleToInt64Bits(value); + return With(OperandKind.Constant, OperandType.FP32, (ulong)BitConverter.SingleToInt32Bits(value)); } - public Operand(int index, RegisterType regType, OperandType type) : this() + public Operand With(double value) { - Kind = OperandKind.Register; - Type = type; + return With(OperandKind.Constant, OperandType.FP64, (ulong)BitConverter.DoubleToInt64Bits(value)); + } - Value = (ulong)((int)regType << 24 | index); + public Operand With(int index, RegisterType regType, OperandType type) + { + return With(OperandKind.Register, type, (ulong)((int)regType << 24 | index)); } public Register GetRegister() diff --git a/ARMeilleure/IntermediateRepresentation/OperandHelper.cs b/ARMeilleure/IntermediateRepresentation/OperandHelper.cs index 4a930e03..cfdb32d9 100644 --- a/ARMeilleure/IntermediateRepresentation/OperandHelper.cs +++ b/ARMeilleure/IntermediateRepresentation/OperandHelper.cs @@ -1,68 +1,99 @@ -using ARMeilleure.State; -using System; +using ARMeilleure.Common; namespace ARMeilleure.IntermediateRepresentation { static class OperandHelper { + private static MemoryOperand MemoryOperand() + { + return ThreadStaticPool<MemoryOperand>.Instance.Allocate(); + } + + private static Operand Operand() + { + return ThreadStaticPool<Operand>.Instance.Allocate(); + } + public static Operand Const(OperandType type, long value) { - return type == OperandType.I32 ? new Operand((int)value) : new Operand(value); + return type == OperandType.I32 ? Operand().With((int)value) : Operand().With(value); } public static Operand Const(bool value) { - return new Operand(value ? 1 : 0); + return Operand().With(value ? 1 : 0); } public static Operand Const(int value) { - return new Operand(value); + return Operand().With(value); } public static Operand Const(uint value) { - return new Operand(value); + return Operand().With(value); } public static Operand Const(long value) { - return new Operand(value); + return Operand().With(value); } public static Operand Const(ulong value) { - return new Operand(value); + return Operand().With(value); } public static Operand ConstF(float value) { - return new Operand(value); + return Operand().With(value); } public static Operand ConstF(double value) { - return new Operand(value); + return Operand().With(value); } public static Operand Label() { - return new Operand(OperandKind.Label); + return Operand().With(OperandKind.Label); } public static Operand Local(OperandType type) { - return new Operand(OperandKind.LocalVariable, type); + return Operand().With(OperandKind.LocalVariable, type); } public static Operand Register(int index, RegisterType regType, OperandType type) { - return new Operand(index, regType, type); + return Operand().With(index, regType, type); } public static Operand Undef() { - return new Operand(OperandKind.Undefined); + return Operand().With(OperandKind.Undefined); + } + + public static MemoryOperand MemoryOp( + OperandType type, + Operand baseAddress, + Operand index = null, + Multiplier scale = Multiplier.x1, + int displacement = 0) + { + return MemoryOperand().With(type, baseAddress, index, scale, displacement); + } + + public static void PrepareOperandPool(bool highCq) + { + ThreadStaticPool<Operand>.PreparePool(highCq ? 1 : 0); + ThreadStaticPool<MemoryOperand>.PreparePool(highCq ? 1 : 0); + } + + public static void ResetOperandPool(bool highCq) + { + ThreadStaticPool<Operand>.ReturnPool(highCq ? 1 : 0); + ThreadStaticPool<MemoryOperand>.ReturnPool(highCq ? 1 : 0); } } }
\ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/Operation.cs b/ARMeilleure/IntermediateRepresentation/Operation.cs index 620bf3f6..4cdbe326 100644 --- a/ARMeilleure/IntermediateRepresentation/Operation.cs +++ b/ARMeilleure/IntermediateRepresentation/Operation.cs @@ -4,10 +4,12 @@ namespace ARMeilleure.IntermediateRepresentation { public Instruction Instruction { get; private set; } + public Operation() : base() { } + public Operation( Instruction instruction, Operand destination, - params Operand[] sources) : base(destination, sources.Length) + Operand[] sources) : base(destination, sources.Length) { Instruction = instruction; @@ -17,24 +19,78 @@ namespace ARMeilleure.IntermediateRepresentation } } - public Operation( + public Operation With(Instruction instruction, Operand destination) + { + With(destination, 0); + Instruction = instruction; + return this; + } + + public Operation With(Instruction instruction, Operand destination, Operand[] sources) + { + With(destination, sources.Length); + Instruction = instruction; + + for (int index = 0; index < sources.Length; index++) + { + SetSource(index, sources[index]); + } + return this; + } + + public Operation With(Instruction instruction, Operand destination, + Operand source0) + { + With(destination, 1); + Instruction = instruction; + + SetSource(0, source0); + return this; + } + + public Operation With(Instruction instruction, Operand destination, + Operand source0, Operand source1) + { + With(destination, 2); + Instruction = instruction; + + SetSource(0, source0); + SetSource(1, source1); + return this; + } + + public Operation With(Instruction instruction, Operand destination, + Operand source0, Operand source1, Operand source2) + { + With(destination, 3); + Instruction = instruction; + + SetSource(0, source0); + SetSource(1, source1); + SetSource(2, source2); + return this; + } + + public Operation With( Instruction instruction, Operand[] destinations, - Operand[] sources) : base(destinations, sources.Length) + Operand[] sources) { + With(destinations, sources.Length); Instruction = instruction; for (int index = 0; index < sources.Length; index++) { SetSource(index, sources[index]); } + return this; } public void TurnIntoCopy(Operand source) { Instruction = Instruction.Copy; - SetSources(new Operand[] { source }); + SetSource(source); } } }
\ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/OperationHelper.cs b/ARMeilleure/IntermediateRepresentation/OperationHelper.cs new file mode 100644 index 00000000..20c7d4ef --- /dev/null +++ b/ARMeilleure/IntermediateRepresentation/OperationHelper.cs @@ -0,0 +1,59 @@ +using ARMeilleure.Common; + +namespace ARMeilleure.IntermediateRepresentation +{ + static class OperationHelper + { + public static Operation Operation() + { + return ThreadStaticPool<Operation>.Instance.Allocate(); + } + + public static Operation Operation(Instruction instruction, Operand destination) + { + return Operation().With(instruction, destination); + } + + public static Operation Operation(Instruction instruction, Operand destination, + Operand[] sources) + { + return Operation().With(instruction, destination, sources); + } + + public static Operation Operation(Instruction instruction, Operand destination, + Operand source0) + { + return Operation().With(instruction, destination, source0); + } + + public static Operation Operation(Instruction instruction, Operand destination, + Operand source0, Operand source1) + { + return Operation().With(instruction, destination, source0, source1); + } + + public static Operation Operation(Instruction instruction, Operand destination, + Operand source0, Operand source1, Operand source2) + { + return Operation().With(instruction, destination, source0, source1, source2); + } + + public static Operation Operation( + Instruction instruction, + Operand[] destinations, + Operand[] sources) + { + return Operation().With(instruction, destinations, sources); + } + + public static void PrepareOperationPool(bool highCq) + { + ThreadStaticPool<Operation>.PreparePool(highCq ? 1 : 0); + } + + public static void ResetOperationPool(bool highCq) + { + ThreadStaticPool<Operation>.ReturnPool(highCq ? 1 : 0); + } + } +} |
