diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs index c738ad8b3f..af1629314c 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -696,7 +696,10 @@ namespace ARMeilleure.CodeGen.X86 Operand dividend = operation.GetSource(0); Operand divisor = operation.GetSource(1); - ValidateBinOp(dest, dividend, divisor); + if (!dest.Type.IsInteger()) + { + ValidateBinOp(dest, dividend, divisor); + } if (dest.Type.IsInteger()) { diff --git a/ARMeilleure/CodeGen/X86/PreAllocator.cs b/ARMeilleure/CodeGen/X86/PreAllocator.cs index e14b7fcf78..dfa074eaae 100644 --- a/ARMeilleure/CodeGen/X86/PreAllocator.cs +++ b/ARMeilleure/CodeGen/X86/PreAllocator.cs @@ -502,36 +502,29 @@ namespace ARMeilleure.CodeGen.X86 LLNode currentNode = node; - Operand temp = Local(OperandType.I32); + Operand temp1 = Local(OperandType.I32); + Operand temp2 = Local(OperandType.I32); - Operation vextOp = new Operation(Instruction.VectorExtract16, temp, src1, Const(index >> 1)); + node = nodes.AddAfter(node, new Operation(Instruction.Copy, temp2, src2)); + + Operation vextOp = new Operation(Instruction.VectorExtract16, temp1, src1, Const(index >> 1)); node = nodes.AddAfter(node, vextOp); if ((index & 1) != 0) { - Operand temp2 = Local(OperandType.I32); - - Operation copyOp = new Operation(Instruction.Copy, temp2, src2); - Operation andOp = new Operation(Instruction.ZeroExtend8, temp, temp); - Operation shlOp = new Operation(Instruction.ShiftLeft, temp2, temp2, Const(8)); - Operation orOp = new Operation(Instruction.BitwiseOr, temp, temp, temp2); - - node = nodes.AddAfter(node, copyOp); - node = nodes.AddAfter(node, andOp); - node = nodes.AddAfter(node, shlOp); - node = nodes.AddAfter(node, orOp); + node = nodes.AddAfter(node, new Operation(Instruction.ZeroExtend8, temp1, temp1)); + node = nodes.AddAfter(node, new Operation(Instruction.ShiftLeft, temp2, temp2, Const(8))); + node = nodes.AddAfter(node, new Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); } else { - Operation andOp = new Operation(Instruction.BitwiseAnd, temp, temp, Const(0xff00)); - Operation orOp = new Operation(Instruction.BitwiseOr, temp, temp, src2); - - node = nodes.AddAfter(node, andOp); - node = nodes.AddAfter(node, orOp); + node = nodes.AddAfter(node, new Operation(Instruction.ZeroExtend8, temp2, temp2)); + node = nodes.AddAfter(node, new Operation(Instruction.BitwiseAnd, temp1, temp1, Const(0xff00))); + node = nodes.AddAfter(node, new Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); } - Operation vinsOp = new Operation(Instruction.VectorInsert16, dest, src1, temp, Const(index >> 1)); + Operation vinsOp = new Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1)); node = nodes.AddAfter(node, vinsOp); diff --git a/ARMeilleure/IntermediateRepresentation/Node.cs b/ARMeilleure/IntermediateRepresentation/Node.cs index 15848f9e8c..8c1f1210b6 100644 --- a/ARMeilleure/IntermediateRepresentation/Node.cs +++ b/ARMeilleure/IntermediateRepresentation/Node.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace ARMeilleure.IntermediateRepresentation @@ -43,7 +44,7 @@ namespace ARMeilleure.IntermediateRepresentation public Node(Operand[] destinations, int sourcesCount) { - SetDestinations(destinations); + SetDestinations(destinations ?? throw new ArgumentNullException(nameof(destinations))); _sources = new Operand[sourcesCount]; @@ -62,69 +63,99 @@ namespace ARMeilleure.IntermediateRepresentation public void SetDestination(int index, Operand destination) { - Set(_destinations, _asgUseNodes, index, destination); + Operand oldOp = _destinations[index]; + + if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) + { + oldOp.Assignments.Remove(_asgUseNodes[index]); + } + + if (destination != null && destination.Kind == OperandKind.LocalVariable) + { + _asgUseNodes[index] = destination.Assignments.AddLast(this); + } + + _destinations[index] = destination; } public void SetSource(int index, Operand source) { - Set(_sources, _srcUseNodes, index, source); - } - - private void Set(Operand[] ops, LinkedListNode[] uses, int index, Operand newOp) - { - Operand oldOp = ops[index]; + Operand oldOp = _sources[index]; if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) { - oldOp.Uses.Remove(uses[index]); + oldOp.Uses.Remove(_srcUseNodes[index]); } - if (newOp != null && newOp.Kind == OperandKind.LocalVariable) + if (source != null && source.Kind == OperandKind.LocalVariable) { - uses[index] = newOp.Uses.AddLast(this); + _srcUseNodes[index] = source.Uses.AddLast(this); } - ops[index] = newOp; + _sources[index] = source; } public void SetDestinations(Operand[] destinations) { - Set(ref _destinations, ref _asgUseNodes, destinations); + if (_destinations != null) + { + for (int index = 0; index < _destinations.Length; index++) + { + Operand oldOp = _destinations[index]; + + if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) + { + oldOp.Assignments.Remove(_asgUseNodes[index]); + } + } + + _destinations = destinations; + } + else + { + _destinations = new Operand[destinations.Length]; + } + + _asgUseNodes = new LinkedListNode[destinations.Length]; + + for (int index = 0; index < destinations.Length; index++) + { + Operand newOp = destinations[index]; + + _destinations[index] = newOp; + + if (newOp.Kind == OperandKind.LocalVariable) + { + _asgUseNodes[index] = newOp.Assignments.AddLast(this); + } + } } public void SetSources(Operand[] sources) { - Set(ref _sources, ref _srcUseNodes, sources); - } - - private void Set(ref Operand[] ops, ref LinkedListNode[] uses, Operand[] newOps) - { - if (ops != null) + for (int index = 0; index < _sources.Length; index++) { - for (int index = 0; index < ops.Length; index++) - { - Operand oldOp = ops[index]; + Operand oldOp = _sources[index]; - if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) - { - oldOp.Uses.Remove(uses[index]); - } + if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) + { + oldOp.Uses.Remove(_srcUseNodes[index]); } } - ops = new Operand[newOps.Length]; + _sources = new Operand[sources.Length]; - uses = new LinkedListNode[newOps.Length]; + _srcUseNodes = new LinkedListNode[sources.Length]; - for (int index = 0; index < newOps.Length; index++) + for (int index = 0; index < sources.Length; index++) { - Operand newOp = newOps[index]; + Operand newOp = sources[index]; - ops[index] = newOp; + _sources[index] = newOp; if (newOp.Kind == OperandKind.LocalVariable) { - uses[index] = newOp.Uses.AddLast(this); + _srcUseNodes[index] = newOp.Uses.AddLast(this); } } } diff --git a/ARMeilleure/IntermediateRepresentation/Operation.cs b/ARMeilleure/IntermediateRepresentation/Operation.cs index be59887878..a17d7007ec 100644 --- a/ARMeilleure/IntermediateRepresentation/Operation.cs +++ b/ARMeilleure/IntermediateRepresentation/Operation.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; - namespace ARMeilleure.IntermediateRepresentation { class Operation : Node