diff options
Diffstat (limited to 'ARMeilleure/CodeGen/X86/PreAllocator.cs')
| -rw-r--r-- | ARMeilleure/CodeGen/X86/PreAllocator.cs | 395 |
1 files changed, 187 insertions, 208 deletions
diff --git a/ARMeilleure/CodeGen/X86/PreAllocator.cs b/ARMeilleure/CodeGen/X86/PreAllocator.cs index 3b3fd683..334f8f7e 100644 --- a/ARMeilleure/CodeGen/X86/PreAllocator.cs +++ b/ARMeilleure/CodeGen/X86/PreAllocator.cs @@ -4,9 +4,8 @@ using ARMeilleure.Translation; using System; using System.Collections.Generic; using System.Diagnostics; - -using static ARMeilleure.IntermediateRepresentation.OperandHelper; -using static ARMeilleure.IntermediateRepresentation.OperationHelper; +using static ARMeilleure.IntermediateRepresentation.Operand.Factory; +using static ARMeilleure.IntermediateRepresentation.Operation.Factory; namespace ARMeilleure.CodeGen.X86 { @@ -22,31 +21,31 @@ namespace ARMeilleure.CodeGen.X86 for (BasicBlock block = cctx.Cfg.Blocks.First; block != null; block = block.ListNext) { - Node nextNode; + Operation nextNode; - for (Node node = block.Operations.First; node != null; node = nextNode) + for (Operation node = block.Operations.First; node != default; node = nextNode) { nextNode = node.ListNext; - if (node is not Operation operation) + if (node.Instruction == Instruction.Phi) { continue; } - HandleConstantRegCopy(block.Operations, node, operation); - HandleDestructiveRegCopy(block.Operations, node, operation); - HandleConstrainedRegCopy(block.Operations, node, operation); + HandleConstantRegCopy(block.Operations, node); + HandleDestructiveRegCopy(block.Operations, node); + HandleConstrainedRegCopy(block.Operations, node); - switch (operation.Instruction) + switch (node.Instruction) { case Instruction.Call: // Get the maximum number of arguments used on a call. // On windows, when a struct is returned from the call, // we also need to pass the pointer where the struct // should be written on the first argument. - int argsCount = operation.SourcesCount - 1; + int argsCount = node.SourcesCount - 1; - if (operation.Destination != null && operation.Destination.Type == OperandType.V128) + if (node.Destination != default && node.Destination.Type == OperandType.V128) { argsCount++; } @@ -60,72 +59,71 @@ namespace ARMeilleure.CodeGen.X86 // being called, as mandated by the ABI. if (callConv == CallConvName.Windows) { - HandleCallWindowsAbi(block.Operations, stackAlloc, node, operation); + HandleCallWindowsAbi(block.Operations, stackAlloc, node); } else /* if (callConv == CallConvName.SystemV) */ { - HandleCallSystemVAbi(block.Operations, node, operation); + HandleCallSystemVAbi(block.Operations, node); } break; case Instruction.ConvertToFPUI: - HandleConvertToFPUI(block.Operations, node, operation); + HandleConvertToFPUI(block.Operations, node); break; case Instruction.LoadArgument: if (callConv == CallConvName.Windows) { - nextNode = HandleLoadArgumentWindowsAbi(cctx, block.Operations, node, preservedArgs, operation); + nextNode = HandleLoadArgumentWindowsAbi(cctx, block.Operations, preservedArgs, node); } else /* if (callConv == CallConvName.SystemV) */ { - nextNode = HandleLoadArgumentSystemVAbi(cctx, block.Operations, node, preservedArgs, operation); + nextNode = HandleLoadArgumentSystemVAbi(cctx, block.Operations, preservedArgs, node); } break; case Instruction.Negate: - if (!operation.GetSource(0).Type.IsInteger()) + if (!node.GetSource(0).Type.IsInteger()) { - HandleNegate(block.Operations, node, operation); + HandleNegate(block.Operations, node); } break; case Instruction.Return: if (callConv == CallConvName.Windows) { - HandleReturnWindowsAbi(cctx, block.Operations, node, preservedArgs, operation); + HandleReturnWindowsAbi(cctx, block.Operations, preservedArgs, node); } else /* if (callConv == CallConvName.SystemV) */ { - HandleReturnSystemVAbi(block.Operations, node, operation); + HandleReturnSystemVAbi(block.Operations, node); } break; case Instruction.Tailcall: if (callConv == CallConvName.Windows) { - HandleTailcallWindowsAbi(block.Operations, stackAlloc, node, operation); + HandleTailcallWindowsAbi(block.Operations, stackAlloc, node); } else { - HandleTailcallSystemVAbi(block.Operations, stackAlloc, node, operation); + HandleTailcallSystemVAbi(block.Operations, stackAlloc, node); } break; case Instruction.VectorInsert8: if (!HardwareCapabilities.SupportsSse41) { - HandleVectorInsert8(block.Operations, node, operation); + HandleVectorInsert8(block.Operations, node); } break; case Instruction.Extended: - IntrinsicOperation intrinOp = (IntrinsicOperation)operation; - - if (intrinOp.Intrinsic == Intrinsic.X86Mxcsrmb || intrinOp.Intrinsic == Intrinsic.X86Mxcsrub) + if (node.Intrinsic == Intrinsic.X86Mxcsrmb || node.Intrinsic == Intrinsic.X86Mxcsrub) { int stackOffset = stackAlloc.Allocate(OperandType.I32); - operation.SetSources(new Operand[] { Const(stackOffset), operation.GetSource(0) }); + + node.SetSources(new Operand[] { Const(stackOffset), node.GetSource(0) }); } break; } @@ -133,16 +131,16 @@ namespace ARMeilleure.CodeGen.X86 } } - private static void HandleConstantRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation) + private static void HandleConstantRegCopy(IntrusiveList<Operation> nodes, Operation node) { - if (operation.SourcesCount == 0 || IsXmmIntrinsic(operation)) + if (node.SourcesCount == 0 || IsXmmIntrinsic(node)) { return; } - Instruction inst = operation.Instruction; + Instruction inst = node.Instruction; - Operand src1 = operation.GetSource(0); + Operand src1 = node.GetSource(0); Operand src2; if (src1.Kind == OperandKind.Constant) @@ -156,7 +154,7 @@ namespace ARMeilleure.CodeGen.X86 // - Replace the constant use with the XMM register. src1 = AddXmmCopy(nodes, node, src1); - operation.SetSource(0, src1); + node.SetSource(0, src1); } else if (!HasConstSrc1(inst)) { @@ -168,34 +166,34 @@ namespace ARMeilleure.CodeGen.X86 // -- Doing so may allow us to encode the constant as operand 2 and avoid a copy. // - If the constant is on operand 2, we check if the instruction supports it, // if not, we also add a copy. 64-bits constants are usually not supported. - if (IsCommutative(operation)) + if (IsCommutative(node)) { - src2 = operation.GetSource(1); + src2 = node.GetSource(1); Operand temp = src1; src1 = src2; src2 = temp; - operation.SetSource(0, src1); - operation.SetSource(1, src2); + node.SetSource(0, src1); + node.SetSource(1, src2); } if (src1.Kind == OperandKind.Constant) { src1 = AddCopy(nodes, node, src1); - operation.SetSource(0, src1); + node.SetSource(0, src1); } } } - if (operation.SourcesCount < 2) + if (node.SourcesCount < 2) { return; } - src2 = operation.GetSource(1); + src2 = node.GetSource(1); if (src2.Kind == OperandKind.Constant) { @@ -203,28 +201,28 @@ namespace ARMeilleure.CodeGen.X86 { src2 = AddXmmCopy(nodes, node, src2); - operation.SetSource(1, src2); + node.SetSource(1, src2); } else if (!HasConstSrc2(inst) || CodeGenCommon.IsLongConst(src2)) { src2 = AddCopy(nodes, node, src2); - operation.SetSource(1, src2); + node.SetSource(1, src2); } } } - private static void HandleConstrainedRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation) + private static void HandleConstrainedRegCopy(IntrusiveList<Operation> nodes, Operation node) { - Operand dest = operation.Destination; + Operand dest = node.Destination; - switch (operation.Instruction) + switch (node.Instruction) { case Instruction.CompareAndSwap: case Instruction.CompareAndSwap16: case Instruction.CompareAndSwap8: { - OperandType type = operation.GetSource(1).Type; + OperandType type = node.GetSource(1).Type; if (type == OperandType.V128) { @@ -243,14 +241,15 @@ namespace ARMeilleure.CodeGen.X86 Operand rcx = Gpr(X86Register.Rcx, OperandType.I64); Operand rdx = Gpr(X86Register.Rdx, OperandType.I64); - SplitOperand(operation.GetSource(1), rax, rdx); - SplitOperand(operation.GetSource(2), rbx, rcx); + SplitOperand(node.GetSource(1), rax, rdx); + SplitOperand(node.GetSource(2), rbx, rcx); + + Operation operation = node; node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax)); nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1))); operation.SetDestinations(new Operand[] { rdx, rax }); - operation.SetSources(new Operand[] { operation.GetSource(0), rdx, rax, rcx, rbx }); } else @@ -258,8 +257,8 @@ namespace ARMeilleure.CodeGen.X86 // Handle the many restrictions of the compare and exchange (32/64) instruction: // - The expected value should be in (E/R)AX. // - The value at the memory location is loaded to (E/R)AX. - Operand expected = operation.GetSource(1); - Operand newValue = operation.GetSource(2); + Operand expected = node.GetSource(1); + Operand newValue = node.GetSource(2); Operand rax = Gpr(X86Register.Rax, expected.Type); @@ -271,11 +270,11 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue)); - operation.SetSources(new Operand[] { operation.GetSource(0), rax, temp }); + node.SetSources(new Operand[] { node.GetSource(0), rax, temp }); nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); - operation.Destination = rax; + node.Destination = rax; } break; @@ -290,7 +289,7 @@ namespace ARMeilleure.CodeGen.X86 // - Additionally it also writes the remainder in RDX. if (dest.Type.IsInteger()) { - Operand src1 = operation.GetSource(0); + Operand src1 = node.GetSource(0); Operand rax = Gpr(X86Register.Rax, src1.Type); Operand rdx = Gpr(X86Register.Rdx, src1.Type); @@ -300,11 +299,8 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); - operation.SetDestinations(new Operand[] { rdx, rax }); - - operation.SetSources(new Operand[] { rdx, rax, operation.GetSource(1) }); - - operation.Destination = rax; + node.SetSources(new Operand[] { rdx, rax, node.GetSource(1) }); + node.Destination = rax; } break; @@ -312,19 +308,17 @@ namespace ARMeilleure.CodeGen.X86 case Instruction.Extended: { - IntrinsicOperation intrinOp = (IntrinsicOperation)operation; - // BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported. - if ((intrinOp.Intrinsic == Intrinsic.X86Blendvpd || - intrinOp.Intrinsic == Intrinsic.X86Blendvps || - intrinOp.Intrinsic == Intrinsic.X86Pblendvb) && + if ((node.Intrinsic == Intrinsic.X86Blendvpd || + node.Intrinsic == Intrinsic.X86Blendvps || + node.Intrinsic == Intrinsic.X86Pblendvb) && !HardwareCapabilities.SupportsVexEncoding) { Operand xmm0 = Xmm(X86Register.Xmm0, OperandType.V128); - nodes.AddBefore(node, Operation(Instruction.Copy, xmm0, operation.GetSource(2))); + nodes.AddBefore(node, Operation(Instruction.Copy, xmm0, node.GetSource(2))); - operation.SetSource(2, xmm0); + node.SetSource(2, xmm0); } break; @@ -337,18 +331,18 @@ namespace ARMeilleure.CodeGen.X86 // - The multiplicand is always in RAX. // - The lower 64-bits of the result is always in RAX. // - The higher 64-bits of the result is always in RDX. - Operand src1 = operation.GetSource(0); + Operand src1 = node.GetSource(0); Operand rax = Gpr(X86Register.Rax, src1.Type); Operand rdx = Gpr(X86Register.Rdx, src1.Type); nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1)); - operation.SetSource(0, rax); + node.SetSource(0, rax); nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx)); - operation.SetDestinations(new Operand[] { rdx, rax }); + node.SetDestinations(new Operand[] { rdx, rax }); break; } @@ -359,13 +353,13 @@ namespace ARMeilleure.CodeGen.X86 case Instruction.ShiftRightUI: { // The shift register is always implied to be CL (low 8-bits of RCX or ECX). - if (operation.GetSource(1).Kind == OperandKind.LocalVariable) + if (node.GetSource(1).Kind == OperandKind.LocalVariable) { Operand rcx = Gpr(X86Register.Rcx, OperandType.I32); - nodes.AddBefore(node, Operation(Instruction.Copy, rcx, operation.GetSource(1))); + nodes.AddBefore(node, Operation(Instruction.Copy, rcx, node.GetSource(1))); - operation.SetSource(1, rcx); + node.SetSource(1, rcx); } break; @@ -373,29 +367,29 @@ namespace ARMeilleure.CodeGen.X86 } } - private static void HandleDestructiveRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation) + private static void HandleDestructiveRegCopy(IntrusiveList<Operation> nodes, Operation node) { - if (operation.Destination == null || operation.SourcesCount == 0) + if (node.Destination == default || node.SourcesCount == 0) { return; } - Instruction inst = operation.Instruction; + Instruction inst = node.Instruction; - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); + Operand dest = node.Destination; + Operand src1 = node.GetSource(0); // The multiply instruction (that maps to IMUL) is somewhat special, it has // a three operand form where the second source is a immediate value. - bool threeOperandForm = inst == Instruction.Multiply && operation.GetSource(1).Kind == OperandKind.Constant; + bool threeOperandForm = inst == Instruction.Multiply && node.GetSource(1).Kind == OperandKind.Constant; - if (IsSameOperandDestSrc1(operation) && src1.Kind == OperandKind.LocalVariable && !threeOperandForm) + if (IsSameOperandDestSrc1(node) && src1.Kind == OperandKind.LocalVariable && !threeOperandForm) { bool useNewLocal = false; - for (int srcIndex = 1; srcIndex < operation.SourcesCount; srcIndex++) + for (int srcIndex = 1; srcIndex < node.SourcesCount; srcIndex++) { - if (operation.GetSource(srcIndex) == dest) + if (node.GetSource(srcIndex) == dest) { useNewLocal = true; @@ -412,23 +406,23 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddBefore(node, Operation(Instruction.Copy, temp, src1)); - operation.SetSource(0, temp); + node.SetSource(0, temp); nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp)); - operation.Destination = temp; + node.Destination = temp; } else { nodes.AddBefore(node, Operation(Instruction.Copy, dest, src1)); - operation.SetSource(0, dest); + node.SetSource(0, dest); } } else if (inst == Instruction.ConditionalSelect) { - Operand src2 = operation.GetSource(1); - Operand src3 = operation.GetSource(2); + Operand src2 = node.GetSource(1); + Operand src3 = node.GetSource(2); if (src1 == dest || src2 == dest) { @@ -436,32 +430,32 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddBefore(node, Operation(Instruction.Copy, temp, src3)); - operation.SetSource(2, temp); + node.SetSource(2, temp); nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp)); - operation.Destination = temp; + node.Destination = temp; } else { nodes.AddBefore(node, Operation(Instruction.Copy, dest, src3)); - operation.SetSource(2, dest); + node.SetSource(2, dest); } } } - private static void HandleConvertToFPUI(IntrusiveList<Node> nodes, Node node, Operation operation) + private static void HandleConvertToFPUI(IntrusiveList<Operation> nodes, Operation node) { // Unsigned integer to FP conversions are not supported on X86. // We need to turn them into signed integer to FP conversions, and // adjust the final result. - Operand dest = operation.Destination; - Operand source = operation.GetSource(0); + Operand dest = node.Destination; + Operand source = node.GetSource(0); Debug.Assert(source.Type.IsInteger(), $"Invalid source type \"{source.Type}\"."); - Node currentNode = node; + Operation currentNode = node; if (source.Type == OperandType.I32) { @@ -502,21 +496,21 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddAfter(node, Operation(Instruction.Add, dest, dest, lsbF)); } - Delete(nodes, currentNode, operation); + Delete(nodes, currentNode); } - private static void HandleNegate(IntrusiveList<Node> nodes, Node node, Operation operation) + private static void HandleNegate(IntrusiveList<Operation> nodes, Operation node) { // There's no SSE FP negate instruction, so we need to transform that into // a XOR of the value to be negated with a mask with the highest bit set. // This also produces -0 for a negation of the value 0. - Operand dest = operation.Destination; - Operand source = operation.GetSource(0); + Operand dest = node.Destination; + Operand source = node.GetSource(0); Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64, $"Invalid destination type \"{dest.Type}\"."); - Node currentNode = node; + Operation currentNode = node; Operand res = Local(dest.Type); @@ -524,27 +518,27 @@ namespace ARMeilleure.CodeGen.X86 if (dest.Type == OperandType.FP32) { - node = nodes.AddAfter(node, new IntrinsicOperation(Intrinsic.X86Pslld, res, res, Const(31))); + node = nodes.AddAfter(node, Operation(Intrinsic.X86Pslld, res, res, Const(31))); } else /* if (dest.Type == OperandType.FP64) */ { - node = nodes.AddAfter(node, new IntrinsicOperation(Intrinsic.X86Psllq, res, res, Const(63))); + node = nodes.AddAfter(node, Operation(Intrinsic.X86Psllq, res, res, Const(63))); } - node = nodes.AddAfter(node, new IntrinsicOperation(Intrinsic.X86Xorps, res, res, source)); + node = nodes.AddAfter(node, Operation(Intrinsic.X86Xorps, res, res, source)); nodes.AddAfter(node, Operation(Instruction.Copy, dest, res)); - Delete(nodes, currentNode, operation); + Delete(nodes, currentNode); } - private static void HandleVectorInsert8(IntrusiveList<Node> nodes, Node node, Operation operation) + private static void HandleVectorInsert8(IntrusiveList<Operation> nodes, Operation node) { // Handle vector insertion, when SSE 4.1 is not supported. - Operand dest = operation.Destination; - Operand src1 = operation.GetSource(0); // Vector - Operand src2 = operation.GetSource(1); // Value - Operand src3 = operation.GetSource(2); // Index + Operand dest = node.Destination; + Operand src1 = node.GetSource(0); // Vector + Operand src2 = node.GetSource(1); // Value + Operand src3 = node.GetSource(2); // Index Debug.Assert(src3.Kind == OperandKind.Constant); @@ -552,7 +546,7 @@ namespace ARMeilleure.CodeGen.X86 Debug.Assert(index < 16); - Node currentNode = node; + Operation currentNode = node; Operand temp1 = Local(OperandType.I32); Operand temp2 = Local(OperandType.I32); @@ -580,16 +574,15 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddAfter(node, vinsOp); - Delete(nodes, currentNode, operation); + Delete(nodes, currentNode); } - private static void HandleCallWindowsAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation) + private static void HandleCallWindowsAbi(IntrusiveList<Operation> nodes, StackAllocator stackAlloc, Operation node) { - Operand dest = operation.Destination; + Operand dest = node.Destination; // Handle struct arguments. int retArgs = 0; - int stackAllocOffset = 0; int AllocateOnStack(int size) @@ -610,9 +603,9 @@ namespace ARMeilleure.CodeGen.X86 return offset; } - Operand arg0Reg = null; + Operand arg0Reg = default; - if (dest != null && dest.Type == OperandType.V128) + if (dest != default && dest.Type == OperandType.V128) { int stackOffset = AllocateOnStack(dest.Type.GetSizeInBytes()); @@ -625,8 +618,7 @@ namespace ARMeilleure.CodeGen.X86 retArgs = 1; } - int argsCount = operation.SourcesCount - 1; - + int argsCount = node.SourcesCount - 1; int maxArgs = CallingConvention.GetArgumentsOnRegsCount() - retArgs; if (argsCount > maxArgs) @@ -636,16 +628,16 @@ namespace ARMeilleure.CodeGen.X86 Operand[] sources = new Operand[1 + retArgs + argsCount]; - sources[0] = operation.GetSource(0); + sources[0] = node.GetSource(0); - if (arg0Reg != null) + if (arg0Reg != default) { sources[1] = arg0Reg; } - for (int index = 1; index < operation.SourcesCount; index++) + for (int index = 1; index < node.SourcesCount; index++) { - Operand source = operation.GetSource(index); + Operand source = node.GetSource(index); if (source.Type == OperandType.V128) { @@ -655,19 +647,18 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddBefore(node, Operation(Instruction.StackAlloc, stackAddr, Const(stackOffset))); - Operation storeOp = Operation(Instruction.Store, null, stackAddr, source); + Operation storeOp = Operation(Instruction.Store, default, stackAddr, source); - HandleConstantRegCopy(nodes, nodes.AddBefore(node, storeOp), storeOp); + HandleConstantRegCopy(nodes, nodes.AddBefore(node, storeOp)); - operation.SetSource(index, stackAddr); + node.SetSource(index, stackAddr); } } // Handle arguments passed on registers. for (int index = 0; index < argsCount; index++) { - Operand source = operation.GetSource(index + 1); - + Operand source = node.GetSource(index + 1); Operand argReg; int argIndex = index + retArgs; @@ -683,25 +674,24 @@ namespace ARMeilleure.CodeGen.X86 Operation copyOp = Operation(Instruction.Copy, argReg, source); - HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); + HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp)); sources[1 + retArgs + index] = argReg; } // The remaining arguments (those that are not passed on registers) // should be passed on the stack, we write them to the stack with "SpillArg". - for (int index = argsCount; index < operation.SourcesCount - 1; index++) + for (int index = argsCount; index < node.SourcesCount - 1; index++) { - Operand source = operation.GetSource(index + 1); - + Operand source = node.GetSource(index + 1); Operand offset = Const((index + retArgs) * 8); - Operation spillOp = Operation(Instruction.SpillArg, null, offset, source); + Operation spillOp = Operation(Instruction.SpillArg, default, offset, source); - HandleConstantRegCopy(nodes, nodes.AddBefore(node, spillOp), spillOp); + HandleConstantRegCopy(nodes, nodes.AddBefore(node, spillOp)); } - if (dest != null) + if (dest != default) { if (dest.Type == OperandType.V128) { @@ -713,7 +703,7 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddAfter(node, loadOp); - operation.Destination = null; + node.Destination = default; } else { @@ -725,23 +715,23 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddAfter(node, copyOp); - operation.Destination = retReg; + node.Destination = retReg; } } - operation.SetSources(sources); + node.SetSources(sources); } - private static void HandleCallSystemVAbi(IntrusiveList<Node> nodes, Node node, Operation operation) + private static void HandleCallSystemVAbi(IntrusiveList<Operation> nodes, Operation node) { - Operand dest = operation.Destination; + Operand dest = node.Destination; List<Operand> sources = new List<Operand> { - operation.GetSource(0) + node.GetSource(0) }; - int argsCount = operation.SourcesCount - 1; + int argsCount = node.SourcesCount - 1; int intMax = CallingConvention.GetIntArgumentsOnRegsCount(); int vecMax = CallingConvention.GetVecArgumentsOnRegsCount(); @@ -753,7 +743,7 @@ namespace ARMeilleure.CodeGen.X86 for (int index = 0; index < argsCount; index++) { - Operand source = operation.GetSource(index + 1); + Operand source = node.GetSource(index + 1); bool passOnReg; @@ -790,7 +780,7 @@ namespace ARMeilleure.CodeGen.X86 Operation copyOp = Operation(Instruction.Copy, argReg, source); - HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); + HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp)); sources.Add(argReg); } @@ -798,25 +788,27 @@ namespace ARMeilleure.CodeGen.X86 { Operand offset = Const(stackOffset); - Operation spillOp = Operation(Instruction.SpillArg, null, offset, source); + Operation spillOp = Operation(Instruction.SpillArg, default, offset, source); - HandleConstantRegCopy(nodes, nodes.AddBefore(node, spillOp), spillOp); + HandleConstantRegCopy(nodes, nodes.AddBefore(node, spillOp)); stackOffset += source.Type.GetSizeInBytes(); } } - if (dest != null) + if (dest != default) { if (dest.Type == OperandType.V128) { Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); + Operation operation = node; + node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, retLReg)); nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, retHReg, Const(1))); - operation.Destination = null; + operation.Destination = default; } else { @@ -828,21 +820,21 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddAfter(node, copyOp); - operation.Destination = retReg; + node.Destination = retReg; } } - operation.SetSources(sources.ToArray()); + node.SetSources(sources.ToArray()); } - private static void HandleTailcallSystemVAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation) + private static void HandleTailcallSystemVAbi(IntrusiveList<Operation> nodes, StackAllocator stackAlloc, Operation node) { List<Operand> sources = new List<Operand> { - operation.GetSource(0) + node.GetSource(0) }; - int argsCount = operation.SourcesCount - 1; + int argsCount = node.SourcesCount - 1; int intMax = CallingConvention.GetIntArgumentsOnRegsCount(); int vecMax = CallingConvention.GetVecArgumentsOnRegsCount(); @@ -853,7 +845,7 @@ namespace ARMeilleure.CodeGen.X86 // Handle arguments passed on registers. for (int index = 0; index < argsCount; index++) { - Operand source = operation.GetSource(1 + index); + Operand source = node.GetSource(1 + index); bool passOnReg; @@ -886,7 +878,7 @@ namespace ARMeilleure.CodeGen.X86 Operation copyOp = Operation(Instruction.Copy, argReg, source); - HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); + HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp)); sources.Add(argReg); } @@ -901,19 +893,18 @@ namespace ARMeilleure.CodeGen.X86 // callee saved register (which would be trashed on the epilogue). Operand retReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); - Operation addrCopyOp = Operation(Instruction.Copy, retReg, operation.GetSource(0)); + Operation addrCopyOp = Operation(Instruction.Copy, retReg, node.GetSource(0)); nodes.AddBefore(node, addrCopyOp); sources[0] = retReg; - operation.SetSources(sources.ToArray()); + node.SetSources(sources.ToArray()); } - private static void HandleTailcallWindowsAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation) + private static void HandleTailcallWindowsAbi(IntrusiveList<Operation> nodes, StackAllocator stackAlloc, Operation node) { - int argsCount = operation.SourcesCount - 1; - + int argsCount = node.SourcesCount - 1; int maxArgs = CallingConvention.GetArgumentsOnRegsCount(); if (argsCount > maxArgs) @@ -926,15 +917,14 @@ namespace ARMeilleure.CodeGen.X86 // Handle arguments passed on registers. for (int index = 0; index < argsCount; index++) { - Operand source = operation.GetSource(1 + index); - + Operand source = node.GetSource(1 + index); Operand argReg = source.Type.IsInteger() ? Gpr(CallingConvention.GetIntArgumentRegister(index), source.Type) : Xmm(CallingConvention.GetVecArgumentRegister(index), source.Type); Operation copyOp = Operation(Instruction.Copy, argReg, source); - HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); + HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp)); sources[1 + index] = argReg; } @@ -944,23 +934,22 @@ namespace ARMeilleure.CodeGen.X86 // callee saved register (which would be trashed on the epilogue). Operand retReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); - Operation addrCopyOp = Operation(Instruction.Copy, retReg, operation.GetSource(0)); + Operation addrCopyOp = Operation(Instruction.Copy, retReg, node.GetSource(0)); nodes.AddBefore(node, addrCopyOp); sources[0] = retReg; - operation.SetSources(sources); + node.SetSources(sources); } - private static Node HandleLoadArgumentWindowsAbi( + private static Operation HandleLoadArgumentWindowsAbi( CompilerContext cctx, - IntrusiveList<Node> nodes, - Node node, + IntrusiveList<Operation> nodes, Operand[] preservedArgs, - Operation operation) + Operation node) { - Operand source = operation.GetSource(0); + Operand source = node.GetSource(0); Debug.Assert(source.Kind == OperandKind.Constant, "Non-constant LoadArgument source kind."); @@ -970,28 +959,25 @@ namespace ARMeilleure.CodeGen.X86 if (index < CallingConvention.GetArgumentsOnRegsCount()) { - Operand dest = operation.Destination; + Operand dest = node.Destination; - if (preservedArgs[index] == null) + if (preservedArgs[index] == default) { Operand argReg, pArg; if (dest.Type.IsInteger()) { argReg = Gpr(CallingConvention.GetIntArgumentRegister(index), dest.Type); - pArg = Local(dest.Type); } else if (dest.Type == OperandType.V128) { argReg = Gpr(CallingConvention.GetIntArgumentRegister(index), OperandType.I64); - pArg = Local(OperandType.I64); } else { argReg = Xmm(CallingConvention.GetVecArgumentRegister(index), dest.Type); - pArg = Local(dest.Type); } @@ -1006,9 +992,9 @@ namespace ARMeilleure.CodeGen.X86 ? Instruction.Load : Instruction.Copy, dest, preservedArgs[index]); - Node newNode = nodes.AddBefore(node, argCopyOp); + Operation newNode = nodes.AddBefore(node, argCopyOp); - Delete(nodes, node, operation); + Delete(nodes, node); return newNode; } @@ -1019,14 +1005,13 @@ namespace ARMeilleure.CodeGen.X86 } } - private static Node HandleLoadArgumentSystemVAbi( + private static Operation HandleLoadArgumentSystemVAbi( CompilerContext cctx, - IntrusiveList<Node> nodes, - Node node, + IntrusiveList<Operation> nodes, Operand[] preservedArgs, - Operation operation) + Operation node) { - Operand source = operation.GetSource(0); + Operand source = node.GetSource(0); Debug.Assert(source.Kind == OperandKind.Constant, "Non-constant LoadArgument source kind."); @@ -1070,9 +1055,9 @@ namespace ARMeilleure.CodeGen.X86 if (passOnReg) { - Operand dest = operation.Destination; + Operand dest = node.Destination; - if (preservedArgs[index] == null) + if (preservedArgs[index] == default) { if (dest.Type == OperandType.V128) { @@ -1108,9 +1093,9 @@ namespace ARMeilleure.CodeGen.X86 Operation argCopyOp = Operation(Instruction.Copy, dest, preservedArgs[index]); - Node newNode = nodes.AddBefore(node, argCopyOp); + Operation newNode = nodes.AddBefore(node, argCopyOp); - Delete(nodes, node, operation); + Delete(nodes, node); return newNode; } @@ -1123,18 +1108,16 @@ namespace ARMeilleure.CodeGen.X86 private static void HandleReturnWindowsAbi( CompilerContext cctx, - IntrusiveList<Node> nodes, - Node node, + IntrusiveList<Operation> nodes, Operand[] preservedArgs, - Operation operation) + Operation node) { - if (operation.SourcesCount == 0) + if (node.SourcesCount == 0) { return; } - Operand source = operation.GetSource(0); - + Operand source = node.GetSource(0); Operand retReg; if (source.Type.IsInteger()) @@ -1143,10 +1126,9 @@ namespace ARMeilleure.CodeGen.X86 } else if (source.Type == OperandType.V128) { - if (preservedArgs[0] == null) + if (preservedArgs[0] == default) { Operand preservedArg = Local(OperandType.I64); - Operand arg0 = Gpr(CallingConvention.GetIntArgumentRegister(0), OperandType.I64); Operation copyOp = Operation(Instruction.Copy, preservedArg, arg0); @@ -1165,7 +1147,7 @@ namespace ARMeilleure.CodeGen.X86 if (source.Type == OperandType.V128) { - Operation retStoreOp = Operation(Instruction.Store, null, retReg, source); + Operation retStoreOp = Operation(Instruction.Store, default, retReg, source); nodes.AddBefore(node, retStoreOp); } @@ -1176,17 +1158,17 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddBefore(node, retCopyOp); } - operation.SetSources(Array.Empty<Operand>()); + node.SetSources(Array.Empty<Operand>()); } - private static void HandleReturnSystemVAbi(IntrusiveList<Node> nodes, Node node, Operation operation) + private static void HandleReturnSystemVAbi(IntrusiveList<Operation> nodes, Operation node) { - if (operation.SourcesCount == 0) + if (node.SourcesCount == 0) { return; } - Operand source = operation.GetSource(0); + Operand source = node.GetSource(0); if (source.Type == OperandType.V128) { @@ -1208,10 +1190,9 @@ namespace ARMeilleure.CodeGen.X86 } } - private static Operand AddXmmCopy(IntrusiveList<Node> nodes, Node node, Operand source) + private static Operand AddXmmCopy(IntrusiveList<Operation> nodes, Operation node, Operand source) { Operand temp = Local(source.Type); - Operand intConst = AddCopy(nodes, node, GetIntConst(source)); Operation copyOp = Operation(Instruction.VectorCreateScalar, temp, intConst); @@ -1221,7 +1202,7 @@ namespace ARMeilleure.CodeGen.X86 return temp; } - private static Operand AddCopy(IntrusiveList<Node> nodes, Node node, Operand source) + private static Operand AddCopy(IntrusiveList<Operation> nodes, Operation node, Operand source) { Operand temp = Local(source.Type); @@ -1246,13 +1227,13 @@ namespace ARMeilleure.CodeGen.X86 return value; } - private static void Delete(IntrusiveList<Node> nodes, Node node, Operation operation) + private static void Delete(IntrusiveList<Operation> nodes, Operation node) { - operation.Destination = null; + node.Destination = default; - for (int index = 0; index < operation.SourcesCount; index++) + for (int index = 0; index < node.SourcesCount; index++) { - operation.SetSource(index, null); + node.SetSource(index, default); } nodes.Remove(node); @@ -1307,8 +1288,7 @@ namespace ARMeilleure.CodeGen.X86 private static bool IsIntrinsicSameOperandDestSrc1(Operation operation) { - IntrinsicOperation intrinOp = (IntrinsicOperation)operation; - IntrinsicInfo info = IntrinsicTable.GetInfo(intrinOp.Intrinsic); + IntrinsicInfo info = IntrinsicTable.GetInfo(operation.Intrinsic); return info.Type == IntrinsicType.Crc32 || info.Type == IntrinsicType.Fma || IsVexSameOperandDestSrc1(operation); } @@ -1319,7 +1299,7 @@ namespace ARMeilleure.CodeGen.X86 { bool isUnary = operation.SourcesCount < 2; - bool hasVecDest = operation.Destination != null && operation.Destination.Type == OperandType.V128; + bool hasVecDest = operation.Destination != default && operation.Destination.Type == OperandType.V128; return !HardwareCapabilities.SupportsVexEncoding && !isUnary && hasVecDest; } @@ -1408,8 +1388,7 @@ namespace ARMeilleure.CodeGen.X86 return false; } - IntrinsicOperation intrinOp = (IntrinsicOperation)operation; - IntrinsicInfo info = IntrinsicTable.GetInfo(intrinOp.Intrinsic); + IntrinsicInfo info = IntrinsicTable.GetInfo(operation.Intrinsic); return info.Type != IntrinsicType.Crc32; } |
