diff --git a/ARMeilleure/CodeGen/RegisterAllocators/LinearScan.cs b/ARMeilleure/CodeGen/RegisterAllocators/LinearScan.cs index 8e91f2389f..31cdb237eb 100644 --- a/ARMeilleure/CodeGen/RegisterAllocators/LinearScan.cs +++ b/ARMeilleure/CodeGen/RegisterAllocators/LinearScan.cs @@ -695,19 +695,24 @@ namespace ARMeilleure.CodeGen.RegisterAllocators { Node operation = GetOperationNode(usePosition).Value; - for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++) + for (int index = 0; index < operation.SourcesCount; index++) { - Operand source = operation.GetSource(srcIndex); + Operand source = operation.GetSource(index); if (source == current.Local) { - operation.SetSource(srcIndex, register); + operation.SetSource(index, register); } } - if (operation.Dest == current.Local) + for (int index = 0; index < operation.DestinationsCount; index++) { - operation.Dest = register; + Operand dest = operation.GetDestination(index); + + if (dest == current.Local) + { + operation.SetDestination(index, register); + } } } } @@ -753,13 +758,14 @@ namespace ARMeilleure.CodeGen.RegisterAllocators Node operation = node.Value; - Operand dest = operation.Dest; - - if (dest != null && dest.Kind == OperandKind.LocalVariable && visited.Add(dest)) + foreach (Operand dest in Destinations(operation)) { - dest.NumberLocal(_intervals.Count); + if (dest.Kind == OperandKind.LocalVariable && visited.Add(dest)) + { + dest.NumberLocal(_intervals.Count); - _intervals.Add(new LiveInterval(dest)); + _intervals.Add(new LiveInterval(dest)); + } } } @@ -794,7 +800,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators foreach (Node node in block.Operations) { - foreach (Operand source in Operands(node)) + foreach (Operand source in Sources(node)) { int id = GetOperandId(source); @@ -804,9 +810,9 @@ namespace ARMeilleure.CodeGen.RegisterAllocators } } - if (node.Dest != null && IsLocalOrRegister(node.Dest.Kind)) + foreach (Operand dest in Destinations(node)) { - liveKill.Set(GetOperandId(node.Dest)); + liveKill.Set(GetOperandId(dest)); } } @@ -894,9 +900,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators { operationPos -= InstructionGap; - Operand dest = node.Dest; - - if (dest != null && IsLocalOrRegister(dest.Kind)) + foreach (Operand dest in Destinations(node)) { LiveInterval interval = _intervals[GetOperandId(dest)]; @@ -904,7 +908,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators interval.AddUsePosition(operationPos + 1); } - foreach (Operand source in Operands(node)) + foreach (Operand source in Sources(node)) { LiveInterval interval = _intervals[GetOperandId(source)]; @@ -983,7 +987,15 @@ namespace ARMeilleure.CodeGen.RegisterAllocators } } - private static IEnumerable Operands(Node node) + private static IEnumerable Destinations(Node node) + { + for (int index = 0; index < node.DestinationsCount; index++) + { + yield return node.GetDestination(index); + } + } + + private static IEnumerable Sources(Node node) { for (int index = 0; index < node.SourcesCount; index++) { diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs index 866576a7da..c738ad8b3f 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -700,6 +700,10 @@ namespace ARMeilleure.CodeGen.X86 if (dest.Type.IsInteger()) { + divisor = operation.GetSource(2); + + EnsureSameType(dest, divisor); + if (divisor.Type == OperandType.I32) { context.Assembler.Cdq(); @@ -723,7 +727,7 @@ namespace ARMeilleure.CodeGen.X86 private static void GenerateDivideUI(CodeGenContext context, Operation operation) { - Operand divisor = operation.GetSource(1); + Operand divisor = operation.GetSource(2); Operand rdx = Register(X86Register.Rdx); diff --git a/ARMeilleure/CodeGen/X86/PreAllocator.cs b/ARMeilleure/CodeGen/X86/PreAllocator.cs index 2f83e3ed60..e14b7fcf78 100644 --- a/ARMeilleure/CodeGen/X86/PreAllocator.cs +++ b/ARMeilleure/CodeGen/X86/PreAllocator.cs @@ -79,7 +79,7 @@ namespace ARMeilleure.CodeGen.X86 { HandleLoadArgumentWindowsAbi(cctx, node, preservedArgs, operation); } - else + else /* if (callConv == CallConvName.SystemV) */ { HandleLoadArgumentSystemVAbi(cctx, node, preservedArgs, operation); } @@ -209,28 +209,26 @@ namespace ARMeilleure.CodeGen.X86 // - The expected value should be in RDX:RAX. // - The new value to be written should be in RCX:RBX. // - The value at the memory location is loaded to RDX:RAX. - void SplitOperand(Operand source, X86Register lowReg, X86Register highReg) + void SplitOperand(Operand source, Operand lr, Operand hr) { - Operand lr = Gpr(lowReg, OperandType.I64); - Operand hr = Gpr(highReg, OperandType.I64); - nodes.AddBefore(node, new Operation(Instruction.VectorExtract, lr, source, Const(0))); nodes.AddBefore(node, new Operation(Instruction.VectorExtract, hr, source, Const(1))); } - SplitOperand(operation.GetSource(1), X86Register.Rax, X86Register.Rdx); - SplitOperand(operation.GetSource(2), X86Register.Rbx, X86Register.Rcx); - Operand rax = Gpr(X86Register.Rax, OperandType.I64); + Operand rbx = Gpr(X86Register.Rbx, OperandType.I64); + 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); + node = nodes.AddAfter(node, new Operation(Instruction.VectorCreateScalar, dest, rax)); node = nodes.AddAfter(node, new Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1))); - operation.SetSource(1, Undef()); - operation.SetSource(2, Undef()); + operation.SetDestinations(new Operand[] { rdx, rax }); - operation.Dest = null; + operation.SetSources(new Operand[] { operation.GetSource(0), rdx, rax, rcx, rbx }); break; } @@ -245,25 +243,24 @@ namespace ARMeilleure.CodeGen.X86 Operand eax = Gpr(X86Register.Rax, OperandType.I32); Operand ebx = Gpr(X86Register.Rbx, OperandType.I32); - Operand rcx = Gpr(X86Register.Rcx, OperandType.I64); + Operand ecx = Gpr(X86Register.Rcx, OperandType.I32); Operand edx = Gpr(X86Register.Rdx, OperandType.I32); // Value 0x01 = Version, family and feature information. nodes.AddBefore(node, new Operation(Instruction.Copy, eax, Const(1))); - // We don't care about those two, but their values are overwritten, - // so we need to take that into account. - node = nodes.AddAfter(node, new Operation(Instruction.Clobber, eax)); - node = nodes.AddAfter(node, new Operation(Instruction.Clobber, ebx)); - // Copy results to the destination register. // The values are split into 2 32-bits registers, we merge them // into a single 64-bits register. + Operand rcx = Gpr(X86Register.Rcx, OperandType.I64); + node = nodes.AddAfter(node, new Operation(Instruction.ZeroExtend32, dest, edx)); node = nodes.AddAfter(node, new Operation(Instruction.ShiftLeft, dest, dest, Const(32))); node = nodes.AddAfter(node, new Operation(Instruction.BitwiseOr, dest, dest, rcx)); - operation.Dest = null; + operation.SetDestinations(new Operand[] { eax, ebx, ecx, edx }); + + operation.SetSources(new Operand[] { eax }); break; } @@ -280,14 +277,15 @@ namespace ARMeilleure.CodeGen.X86 Operand rax = Gpr(X86Register.Rax, src1.Type); Operand rdx = Gpr(X86Register.Rdx, src1.Type); - nodes.AddBefore(node, new Operation(Instruction.Copy, rax, src1)); - - operation.SetSource(0, rax); - + nodes.AddBefore(node, new Operation(Instruction.Copy, rax, src1)); nodes.AddBefore(node, new Operation(Instruction.Clobber, rdx)); node = nodes.AddAfter(node, new Operation(Instruction.Copy, dest, rax)); + operation.SetDestinations(new Operand[] { rdx, rax }); + + operation.SetSources(new Operand[] { rdx, rax, operation.GetSource(1) }); + operation.Dest = rax; break; @@ -328,7 +326,7 @@ namespace ARMeilleure.CodeGen.X86 node = nodes.AddAfter(node, new Operation(Instruction.Copy, dest, rdx)); - operation.Dest = rdx; + operation.SetDestinations(new Operand[] { rdx, rax }); break; } @@ -571,11 +569,13 @@ namespace ARMeilleure.CodeGen.X86 return offset; } + Operand arg0Reg = null; + if (dest != null && dest.Type == OperandType.V128) { int stackOffset = AllocateOnStack(dest.Type.GetSizeInBytes()); - Operand arg0Reg = Gpr(CallingConvention.GetIntArgumentRegister(0), OperandType.I64); + arg0Reg = Gpr(CallingConvention.GetIntArgumentRegister(0), OperandType.I64); Operation allocOp = new Operation(Instruction.StackAlloc, arg0Reg, Const(stackOffset)); @@ -584,6 +584,24 @@ namespace ARMeilleure.CodeGen.X86 retArgs = 1; } + int argsCount = operation.SourcesCount - 1; + + int maxArgs = CallingConvention.GetArgumentsOnRegsCount() - retArgs; + + if (argsCount > maxArgs) + { + argsCount = maxArgs; + } + + Operand[] sources = new Operand[1 + retArgs + argsCount]; + + sources[0] = operation.GetSource(0); + + if (arg0Reg != null) + { + sources[1] = arg0Reg; + } + for (int index = 1; index < operation.SourcesCount; index++) { Operand source = operation.GetSource(index); @@ -602,35 +620,29 @@ namespace ARMeilleure.CodeGen.X86 HandleConstantCopy(nodes.AddBefore(node, storeOp), storeOp); - operation.SetSource(index, stackAddr); + sources[retArgs + index] = stackAddr; } } // Handle arguments passed on registers. - int argsCount = operation.SourcesCount - 1; - - int maxArgs = CallingConvention.GetArgumentsOnRegsCount() - retArgs; - - if (argsCount > maxArgs) - { - argsCount = maxArgs; - } - for (int index = 0; index < argsCount; index++) { Operand source = operation.GetSource(index + 1); - RegisterType regType = source.Type.ToRegisterType(); + if (source.Type == OperandType.V128) + { + source = sources[1 + retArgs + index]; + } Operand argReg; int argIndex = index + retArgs; - if (regType == RegisterType.Integer) + if (source.Type.IsInteger()) { argReg = Gpr(CallingConvention.GetIntArgumentRegister(argIndex), source.Type); } - else /* if (regType == RegisterType.Vector) */ + else { argReg = Xmm(CallingConvention.GetVecArgumentRegister(argIndex), source.Type); } @@ -639,7 +651,7 @@ namespace ARMeilleure.CodeGen.X86 HandleConstantCopy(nodes.AddBefore(node, copyOp), copyOp); - operation.SetSource(index + 1, argReg); + sources[1 + retArgs + index] = argReg; } // The remaining arguments (those that are not passed on registers) @@ -653,8 +665,6 @@ namespace ARMeilleure.CodeGen.X86 Operation spillOp = new Operation(Instruction.SpillArg, null, offset, source); HandleConstantCopy(nodes.AddBefore(node, spillOp), spillOp); - - operation.SetSource(index + 1, new Operand(OperandKind.Undefined)); } if (dest != null) @@ -663,8 +673,6 @@ namespace ARMeilleure.CodeGen.X86 { Operand retValueAddr = Local(OperandType.I64); - Operand arg0Reg = Gpr(CallingConvention.GetIntArgumentRegister(0), OperandType.I64); - Operation copyOp = new Operation(Instruction.Copy, retValueAddr, arg0Reg); nodes.AddBefore(node, copyOp); @@ -677,9 +685,7 @@ namespace ARMeilleure.CodeGen.X86 } else { - RegisterType regType = dest.Type.ToRegisterType(); - - Operand retReg = regType == RegisterType.Integer + Operand retReg = dest.Type.IsInteger() ? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type) : Xmm(CallingConvention.GetVecReturnRegister(), dest.Type); @@ -691,6 +697,8 @@ namespace ARMeilleure.CodeGen.X86 } } + operation.SetSources(sources); + return node; } @@ -700,7 +708,10 @@ namespace ARMeilleure.CodeGen.X86 LinkedList nodes = node.List; - // Handle arguments passed on registers. + List sources = new List(); + + sources.Add(operation.GetSource(0)); + int argsCount = operation.SourcesCount - 1; int intMax = CallingConvention.GetIntArgumentsOnRegsCount(); @@ -739,8 +750,6 @@ namespace ARMeilleure.CodeGen.X86 nodes.AddBefore(node, new Operation(Instruction.VectorExtract, argReg, source, Const(0))); nodes.AddBefore(node, new Operation(Instruction.VectorExtract, argReg2, source, Const(1))); - operation.SetSource(index + 1, Undef()); - continue; } @@ -754,7 +763,7 @@ namespace ARMeilleure.CodeGen.X86 HandleConstantCopy(nodes.AddBefore(node, copyOp), copyOp); - operation.SetSource(index + 1, argReg); + sources.Add(argReg); } else { @@ -765,8 +774,6 @@ namespace ARMeilleure.CodeGen.X86 HandleConstantCopy(nodes.AddBefore(node, spillOp), spillOp); stackOffset += source.Type.GetSizeInBytes(); - - operation.SetSource(index + 1, Undef()); } } @@ -784,9 +791,7 @@ namespace ARMeilleure.CodeGen.X86 } else { - RegisterType regType = dest.Type.ToRegisterType(); - - Operand retReg = regType == RegisterType.Integer + Operand retReg = dest.Type.IsInteger() ? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type) : Xmm(CallingConvention.GetVecReturnRegister(), dest.Type); @@ -798,6 +803,8 @@ namespace ARMeilleure.CodeGen.X86 } } + operation.SetSources(sources.ToArray()); + return node; } diff --git a/ARMeilleure/IntermediateRepresentation/Instruction.cs b/ARMeilleure/IntermediateRepresentation/Instruction.cs index 863f385849..4c4ecb8f2d 100644 --- a/ARMeilleure/IntermediateRepresentation/Instruction.cs +++ b/ARMeilleure/IntermediateRepresentation/Instruction.cs @@ -76,21 +76,4 @@ namespace ARMeilleure.IntermediateRepresentation SpillArg, StoreToContext } - - static class InstructionExtensions - { - public static bool IsShift(this Instruction inst) - { - switch (inst) - { - case Instruction.RotateRight: - case Instruction.ShiftLeft: - case Instruction.ShiftRightSI: - case Instruction.ShiftRightUI: - return true; - } - - return false; - } - } } \ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/Node.cs b/ARMeilleure/IntermediateRepresentation/Node.cs index 2808f5487b..15848f9e8c 100644 --- a/ARMeilleure/IntermediateRepresentation/Node.cs +++ b/ARMeilleure/IntermediateRepresentation/Node.cs @@ -4,63 +4,129 @@ namespace ARMeilleure.IntermediateRepresentation { class Node { - private Operand _dest; - - private LinkedListNode _asgUseNode; - public Operand Dest { get { - return _dest; + return _destinations.Length != 0 ? GetDestination(0) : null; } set { - if (_dest != null && _dest.Kind == OperandKind.LocalVariable) + if (value != null) { - _dest.Assignments.Remove(_asgUseNode); + SetDestinations(new Operand[] { value }); } - - if (value != null && value.Kind == OperandKind.LocalVariable) + else { - _asgUseNode = value.Assignments.AddLast(this); + SetDestinations(new Operand[0]); } - - _dest = value; } } - protected Operand[] Sources; + private Operand[] _destinations; + private Operand[] _sources; - public int SourcesCount => Sources.Length; + private LinkedListNode[] _asgUseNodes; + private LinkedListNode[] _srcUseNodes; - protected LinkedListNode[] SrcUseNodes; + public int DestinationsCount => _destinations.Length; + public int SourcesCount => _sources.Length; - public Node(int sourcesCount) + public Node(Operand destination, int sourcesCount) { - SrcUseNodes = new LinkedListNode[sourcesCount]; + Dest = destination; + + _sources = new Operand[sourcesCount]; + + _srcUseNodes = new LinkedListNode[sourcesCount]; + } + + public Node(Operand[] destinations, int sourcesCount) + { + SetDestinations(destinations); + + _sources = new Operand[sourcesCount]; + + _srcUseNodes = new LinkedListNode[sourcesCount]; + } + + public Operand GetDestination(int index) + { + return _destinations[index]; } public Operand GetSource(int index) { - return Sources[index]; + return _sources[index]; + } + + public void SetDestination(int index, Operand destination) + { + Set(_destinations, _asgUseNodes, index, destination); } public void SetSource(int index, Operand source) { - Operand oldSrc = Sources[index]; + Set(_sources, _srcUseNodes, index, source); + } - if (oldSrc != null && oldSrc.Kind == OperandKind.LocalVariable) + private void Set(Operand[] ops, LinkedListNode[] uses, int index, Operand newOp) + { + Operand oldOp = ops[index]; + + if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) { - oldSrc.Uses.Remove(SrcUseNodes[index]); + oldOp.Uses.Remove(uses[index]); } - if (source != null && source.Kind == OperandKind.LocalVariable) + if (newOp != null && newOp.Kind == OperandKind.LocalVariable) { - SrcUseNodes[index] = source.Uses.AddLast(this); + uses[index] = newOp.Uses.AddLast(this); } - Sources[index] = source; + ops[index] = newOp; + } + + public void SetDestinations(Operand[] destinations) + { + Set(ref _destinations, ref _asgUseNodes, destinations); + } + + 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 < ops.Length; index++) + { + Operand oldOp = ops[index]; + + if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) + { + oldOp.Uses.Remove(uses[index]); + } + } + } + + ops = new Operand[newOps.Length]; + + uses = new LinkedListNode[newOps.Length]; + + for (int index = 0; index < newOps.Length; index++) + { + Operand newOp = newOps[index]; + + ops[index] = newOp; + + if (newOp.Kind == OperandKind.LocalVariable) + { + uses[index] = newOp.Uses.AddLast(this); + } + } } } } \ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/Operation.cs b/ARMeilleure/IntermediateRepresentation/Operation.cs index a8586e0274..be59887878 100644 --- a/ARMeilleure/IntermediateRepresentation/Operation.cs +++ b/ARMeilleure/IntermediateRepresentation/Operation.cs @@ -6,22 +6,29 @@ namespace ARMeilleure.IntermediateRepresentation { public Instruction Inst { get; private set; } - public Operation(Instruction inst, Operand dest, params Operand[] sources) : base(sources.Length) + public Operation( + Instruction inst, + Operand destination, + params Operand[] sources) : base(destination, sources.Length) { Inst = inst; - Dest = dest; - //The array may be modified externally, so we store a copy. - Sources = (Operand[])sources.Clone(); - - for (int index = 0; index < Sources.Length; index++) + for (int index = 0; index < sources.Length; index++) { - Operand source = Sources[index]; + SetSource(index, sources[index]); + } + } - if (source.Kind == OperandKind.LocalVariable) - { - SrcUseNodes[index] = source.Uses.AddLast(this); - } + public Operation( + Instruction inst, + Operand[] destinations, + Operand[] sources) : base(destinations, sources.Length) + { + Inst = inst; + + for (int index = 0; index < sources.Length; index++) + { + SetSource(index, sources[index]); } } @@ -29,24 +36,7 @@ namespace ARMeilleure.IntermediateRepresentation { Inst = Instruction.Copy; - for (int index = 0; index < Sources.Length; index++) - { - if (Sources[index].Kind != OperandKind.LocalVariable) - { - continue; - } - - Sources[index].Uses.Remove(SrcUseNodes[index]); - } - - Sources = new Operand[] { source }; - - SrcUseNodes = new LinkedListNode[1]; - - if (source.Kind == OperandKind.LocalVariable) - { - SrcUseNodes[0] = source.Uses.AddLast(this); - } + SetSources(new Operand[] { source }); } } } \ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/PhiNode.cs b/ARMeilleure/IntermediateRepresentation/PhiNode.cs index 803230e58e..30fc4d384c 100644 --- a/ARMeilleure/IntermediateRepresentation/PhiNode.cs +++ b/ARMeilleure/IntermediateRepresentation/PhiNode.cs @@ -4,13 +4,9 @@ namespace ARMeilleure.IntermediateRepresentation { private BasicBlock[] _blocks; - public PhiNode(Operand dest, int predecessorsCount) : base(predecessorsCount) + public PhiNode(Operand destination, int predecessorsCount) : base(destination, predecessorsCount) { - Sources = new Operand[predecessorsCount]; - _blocks = new BasicBlock[predecessorsCount]; - - Dest = dest; } public BasicBlock GetBlock(int index) diff --git a/ARMeilleure/Translation/ArmEmitterContext.cs b/ARMeilleure/Translation/ArmEmitterContext.cs index da9e95367f..d35e985e6c 100644 --- a/ARMeilleure/Translation/ArmEmitterContext.cs +++ b/ARMeilleure/Translation/ArmEmitterContext.cs @@ -3,6 +3,7 @@ using ARMeilleure.Instructions; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Memory; using ARMeilleure.State; +using System.Collections.Generic; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -10,6 +11,8 @@ namespace ARMeilleure.Translation { class ArmEmitterContext : EmitterContext { + private Dictionary _labels; + private OpCode _optOpLastCompare; private OpCode _optOpLastFlagSet; @@ -42,6 +45,20 @@ namespace ARMeilleure.Translation { Memory = memory; Mode = mode; + + _labels = new Dictionary(); + } + + public Operand GetLabel(ulong address) + { + if (!_labels.TryGetValue(address, out Operand label)) + { + label = Label(); + + _labels.Add(address, label); + } + + return label; } public void MarkComparison(Operand n, Operand m) diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs index a1cdf71092..727833d1be 100644 --- a/ARMeilleure/Translation/EmitterContext.cs +++ b/ARMeilleure/Translation/EmitterContext.cs @@ -10,8 +10,6 @@ namespace ARMeilleure.Translation { class EmitterContext { - private Dictionary _labels; - private Dictionary _irLabels; private LinkedList _irBlocks; @@ -22,8 +20,6 @@ namespace ARMeilleure.Translation public EmitterContext() { - _labels = new Dictionary(); - _irLabels = new Dictionary(); _irBlocks = new LinkedList(); @@ -94,37 +90,34 @@ namespace ARMeilleure.Translation return Call(Const(ptr.ToInt64()), returnType, callArgs); } + private static Dictionary _typeCodeToOperandTypeMap = + new Dictionary() + { + { TypeCode.Boolean, OperandType.I32 }, + { TypeCode.Byte, OperandType.I32 }, + { TypeCode.Char, OperandType.I32 }, + { TypeCode.Double, OperandType.FP64 }, + { TypeCode.Int16, OperandType.I32 }, + { TypeCode.Int32, OperandType.I32 }, + { TypeCode.Int64, OperandType.I64 }, + { TypeCode.SByte, OperandType.I32 }, + { TypeCode.Single, OperandType.FP32 }, + { TypeCode.UInt16, OperandType.I32 }, + { TypeCode.UInt32, OperandType.I32 }, + { TypeCode.UInt64, OperandType.I64 } + }; + private static OperandType GetOperandType(Type type) { - switch (Type.GetTypeCode(type)) + if (_typeCodeToOperandTypeMap.TryGetValue(Type.GetTypeCode(type), out OperandType ot)) { - case TypeCode.Boolean: - case TypeCode.Char: - case TypeCode.Byte: - case TypeCode.SByte: - case TypeCode.UInt16: - case TypeCode.Int16: - case TypeCode.UInt32: - case TypeCode.Int32: - return OperandType.I32; - - case TypeCode.UInt64: - case TypeCode.Int64: - return OperandType.I64; - - case TypeCode.Single: - return OperandType.FP32; - - case TypeCode.Double: - return OperandType.FP64; + return ot; } - - if (type == typeof(V128)) + else if (type == typeof(V128)) { return OperandType.V128; } - - if (type == typeof(void)) + else if (type == typeof(void)) { return OperandType.None; } @@ -527,18 +520,6 @@ namespace ARMeilleure.Translation } } - public Operand GetLabel(ulong address) - { - if (!_labels.TryGetValue(address, out Operand label)) - { - label = Label(); - - _labels.Add(address, label); - } - - return label; - } - private void NewNextBlock() { BasicBlock block = new BasicBlock(_irBlocks.Count);