/// <summary>
        /// Cleanups the return value.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="context">The context.</param>
        /// <param name="result">The result.</param>
        private void CleanupReturnValue(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context, Operand result)
        {
            if (result == null)
            {
                return;
            }

            if (result.IsR)
            {
                Operand returnFP = Operand.CreateCPURegister(result.Type, returnFloatingPointRegister);
                context.AppendInstruction(IRInstruction.Gen, returnFP);
                architecture.InsertMoveInstruction(context, result, returnFP);
            }
            else if (result.Is64BitInteger)
            {
                Operand returnLow  = Operand.CreateCPURegister(result.Type, return32BitRegister);
                Operand returnHigh = Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.U4, return64BitRegister);
                context.AppendInstruction(IRInstruction.Gen, returnLow);
                context.AppendInstruction(IRInstruction.Gen, returnHigh);
                architecture.InsertMoveInstruction(context, result.Low, returnLow);
                architecture.InsertMoveInstruction(context, result.High, returnHigh);
            }
            else if (typeLayout.IsCompoundType(result.Type))
            {
                int     size            = typeLayout.GetTypeSize(result.Type);
                Operand stackPointerReg = Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.Pointer, architecture.StackPointerRegister);
                architecture.InsertCompoundMoveInstruction(compiler, context, result, Operand.CreateMemoryAddress(result.Type, stackPointerReg, 0), size);
            }
            else
            {
                Operand returnLow = Operand.CreateCPURegister(result.Type, return32BitRegister);
                context.AppendInstruction(IRInstruction.Gen, returnLow);
                architecture.InsertMoveInstruction(context, result, returnLow);
            }
        }
        private static int CalculateReturnSize(MosaTypeLayout typeLayout, MosaMethod method)
        {
            if (typeLayout.IsCompoundType(method.Signature.ReturnType))
            {
                return(typeLayout.GetTypeSize(method.Signature.ReturnType));
            }

            return(0);
        }
        private static int CalculateReturnSize(MosaTypeLayout typeLayout, Operand result)
        {
            if (result == null)
            {
                return(0);
            }

            if (typeLayout.IsCompoundType(result.Type))
            {
                return(typeLayout.GetTypeSize(result.Type));
            }

            return(0);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Expands method call instruction represented by the context to perform the method call.
        /// </summary>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="context">The context.</param>
        public override void MakeCall(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context)
        {
            /*
             * Calling convention is right-to-left, pushed on the stack. Return value in EAX for integral
             * types 4 bytes or less, XMM0 for floating point and EAX:EDX for 64-bit. If this is a method
             * of a type, the this argument is moved to ECX right before the call.
             * If return value is value type, a stack local is allocated as a hidden parameter in caller
             * stack, the callee will then store the return value in the allocated space
             * The return value is the first parameter (even before this)
             * The callee will place the address of the return value into EAX and the caller will then
             * either retrieve the return value using compound move or will let one of the callers higher
             * in the caller chain handle the retrieval of the return value using compound move.
             */

            Operand    target = context.Operand1;
            Operand    result = context.Result;
            MosaMethod method = context.InvokeMethod;

            Debug.Assert(method != null, context.ToString());

            Operand scratch = Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.Pointer, scratchRegister);

            List <Operand> operands = BuildOperands(context);

            int stackSize = CalculateStackSizeForParameters(typeLayout, architecture, operands, method);

            context.Empty();

            int returnSize = 0;

            if (typeLayout.IsCompoundType(method.Signature.ReturnType))
            {
                returnSize = typeLayout.GetTypeSize(method.Signature.ReturnType);
            }

            if (stackSize != 0 || returnSize != 0)
            {
                ReserveStackSizeForCall(typeLayout.TypeSystem, context, returnSize + stackSize, scratch);
                PushOperands(compiler, typeLayout, context, method, operands, returnSize + stackSize, scratch);
            }

            // the mov/call two-instructions combo is to help facilitate the register allocator
            architecture.InsertMoveInstruction(context, scratch, target);
            architecture.InsertCallInstruction(context, scratch);

            CleanupReturnValue(compiler, typeLayout, context, result);
            FreeStackAfterCall(typeLayout.TypeSystem, context, returnSize + stackSize);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Gets the type memory requirements.
 /// </summary>
 /// <param name="typeLayout">The type layouts.</param>
 /// <param name="type">The signature type.</param>
 /// <param name="size">Receives the memory size of the type.</param>
 /// <param name="alignment">Receives alignment requirements of the type.</param>
 public override void GetTypeRequirements(MosaTypeLayout typeLayout, MosaType type, out int size, out int alignment)
 {
     if (type.IsUI8 || type.IsR8 || !type.IsValueType || type.IsPointer)
     {
         size      = 8;
         alignment = 8;
     }
     else if (typeLayout.IsCompoundType(type))
     {
         size      = typeLayout.GetTypeSize(type);
         alignment = 8;
     }
     else
     {
         size      = 4;
         alignment = 4;
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets the type memory requirements.
        /// </summary>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="type">The type.</param>
        /// <param name="size">Receives the memory size of the type.</param>
        /// <param name="alignment">Receives alignment requirements of the type.</param>
        public override void GetTypeRequirements(MosaTypeLayout typeLayout, MosaType type, out int size, out int alignment)
        {
            alignment = 4;

            size = type.IsValueType ? typeLayout.GetTypeSize(type) : 4;
        }
Ejemplo n.º 7
0
        private TreeNode GetOrCreateNode(MosaType type)
        {
            if (map.TryGetValue(type, out TreeNode typeNode))
            {
                return(typeNode);
            }

            typeNode = new TreeNode(type.FullName)
            {
                Tag = type
            };

            map.Add(type, typeNode);

            var namespaceNode = GetOrCreateNode(type.Namespace, type.Module);

            AddToTree(typeNode, namespaceNode);

            if (type.BaseType != null)
            {
                var baseTypeNode = new TreeNode("Base Type: " + type.BaseType.FullName);
                typeNode.Nodes.Add(baseTypeNode);
            }

            if (type.DeclaringType != null)
            {
                var declaringTypeNode = new TreeNode("Declaring Type: " + type.DeclaringType.FullName);
                typeNode.Nodes.Add(declaringTypeNode);
            }

            if (type.ElementType != null)
            {
                var elementTypeNode = new TreeNode("Element Type: " + type.ElementType.FullName);
                typeNode.Nodes.Add(elementTypeNode);
            }

            if (type.Interfaces.Count != 0)
            {
                var interfacesNodes = new TreeNode("Interfaces");
                typeNode.Nodes.Add(interfacesNodes);

                foreach (var interfaceType in type.Interfaces)
                {
                    var interfaceNode = new TreeNode(interfaceType.FullName);
                    interfacesNodes.Nodes.Add(interfaceNode);
                }
            }

            if (type.Fields.Count != 0)
            {
                var fieldsNode = new TreeNode("Fields");
                if (ShowSizes)
                {
                    fieldsNode.Text = fieldsNode.Text + " (Count: " + type.Fields.Count.ToString() + " - Size: " + TypeLayout.GetTypeSize(type).ToString() + ")";
                }

                typeNode.Nodes.Add(fieldsNode);

                foreach (var field in type.Fields)
                {
                    var fieldNode = new TreeNode(field.ShortName);
                    fieldsNode.Nodes.Add(fieldNode);

                    if (field.IsStatic)
                    {
                        fieldNode.Text += " [Static]";
                    }

                    if (ShowSizes)
                    {
                        fieldNode.Text = fieldNode.Text + " (Size: " + TypeLayout.GetFieldSize(field).ToString();

                        if (!field.IsStatic)
                        {
                            fieldNode.Text = fieldNode.Text + " - Offset: " + TypeLayout.GetFieldOffset(field).ToString();
                        }

                        fieldNode.Text += ")";
                    }
                }
            }

            if (type.Properties.Count != 0)
            {
                var propertiesNode = new TreeNode("Properties");

                if (ShowSizes)
                {
                    propertiesNode.Text = propertiesNode.Text + " (Count: " + type.Properties.Count.ToString() + ")";
                }

                typeNode.Nodes.Add(propertiesNode);

                foreach (var property in type.Properties)
                {
                    if (Include == null || Include.Contains(property))
                    {
                        var propertyNode = new TreeNode(property.ShortName)
                        {
                            Tag = property
                        };
                        propertiesNode.Nodes.Add(propertyNode);

                        if (property.GetterMethod != null)
                        {
                            var getterNode = new TreeNode(property.GetterMethod.ShortName)
                            {
                                Tag = property.GetterMethod
                            };

                            propertyNode.Nodes.Add(getterNode);

                            if (property.GetterMethod.IsStatic)
                            {
                                getterNode.Text += " [Static]";
                            }

                            if (property.GetterMethod.IsAbstract)
                            {
                                getterNode.Text += " [Abstract]";
                            }

                            if (property.GetterMethod.IsNewSlot)
                            {
                                getterNode.Text += " [NewSlot]";
                            }

                            if (property.GetterMethod.IsVirtual)
                            {
                                getterNode.Text += " [Virtual]";
                            }

                            if (property.GetterMethod.IsFinal)
                            {
                                getterNode.Text += " [Final]";
                            }

                            if (property.GetterMethod.IsSpecialName)
                            {
                                getterNode.Text += " [SpecialName]";
                            }

                            if (property.GetterMethod.IsRTSpecialName)
                            {
                                getterNode.Text += " [RTSpecialName]";
                            }

                            if (property.GetterMethod.GenericArguments.Count != 0)
                            {
                                var genericParameterNodes = new TreeNode("Generic Arguments Types");
                                getterNode.Nodes.Add(genericParameterNodes);

                                foreach (var genericParameter in property.GetterMethod.GenericArguments)
                                {
                                    var GenericParameterNode = new TreeNode(genericParameter.Name);
                                    genericParameterNodes.Nodes.Add(GenericParameterNode);
                                }
                            }
                        }

                        if (property.SetterMethod != null)
                        {
                            var setterNode = new TreeNode(property.SetterMethod.ShortName)
                            {
                                Tag = property.SetterMethod
                            };
                            propertyNode.Nodes.Add(setterNode);

                            if (property.SetterMethod.IsStatic)
                            {
                                setterNode.Text += " [Static]";
                            }

                            if (property.SetterMethod.IsAbstract)
                            {
                                setterNode.Text += " [Abstract]";
                            }

                            if (property.SetterMethod.IsNewSlot)
                            {
                                setterNode.Text += " [NewSlot]";
                            }

                            if (property.SetterMethod.IsVirtual)
                            {
                                setterNode.Text += " [Virtual]";
                            }

                            if (property.SetterMethod.IsFinal)
                            {
                                setterNode.Text += " [Final]";
                            }

                            if (property.SetterMethod.IsSpecialName)
                            {
                                setterNode.Text += " [SpecialName]";
                            }

                            if (property.SetterMethod.IsRTSpecialName)
                            {
                                setterNode.Text += " [RTSpecialName]";
                            }

                            if (property.SetterMethod.GenericArguments.Count != 0)
                            {
                                var genericParameterNodes = new TreeNode("Generic Arguments Types");
                                setterNode.Nodes.Add(genericParameterNodes);

                                foreach (var genericParameter in property.SetterMethod.GenericArguments)
                                {
                                    var GenericParameterNode = new TreeNode(genericParameter.Name);
                                    genericParameterNodes.Nodes.Add(GenericParameterNode);
                                }
                            }
                        }
                    }
                }
            }

            if (type.Methods.Count != 0)
            {
                typeNode.Nodes.Add(new TreeNode("Methods"));

                var methodList = (new List <MosaMethod>(type.Methods)).OrderBy(o => o.ShortName).ToList();

                // Methods
                foreach (var method in type.Methods)
                {
                    if (Include == null || Include.Contains(method))
                    {
                        var methonode = GetOrCreateNode(method);
                    }
                }
            }

            //  Method Table
            if (TypeLayout.GetMethodTable(type) != null)
            {
                var methodTableNode = new TreeNode("Method Table");
                typeNode.Nodes.Add(methodTableNode);

                var methodList = (new List <MosaMethod>(TypeLayout.GetMethodTable(type))).OrderBy(o => o.ShortName).ToList();

                foreach (var method in methodList)
                {
                    if (Include == null || Include.Contains(method))
                    {
                        var methodNode = new TreeNode(method.ShortName)
                        {
                            Tag = method
                        };
                        methodTableNode.Nodes.Add(methodNode);
                    }
                }
            }

            return(typeNode);
        }
Ejemplo n.º 8
0
        public static void UpdateTree(TreeView treeView, TypeSystem typeSystem, MosaTypeLayout typeLayout, bool showSizes)
        {
            treeView.BeginUpdate();
            treeView.Nodes.Clear();

            foreach (var module in typeSystem.Modules)
            {
                List <TreeNode> namespaces = new List <TreeNode>();

                TreeNode moduleNode = new TreeNode(module.Name);
                treeView.Nodes.Add(moduleNode);

                List <MosaType> typeList = (new List <MosaType>(module.Types.Values)).OrderBy(o => o.FullName).ToList();

                foreach (MosaType type in typeList)
                {
                    TreeNode namespaceNode = null;
                    string   @namespace    = (string.IsNullOrWhiteSpace(type.Namespace)) ? "[No Namespace]" : type.Namespace;
                    foreach (TreeNode node in namespaces)
                    {
                        if (node.Text.Equals(@namespace))
                        {
                            namespaceNode = node;
                            break;
                        }
                    }

                    if (namespaceNode == null)
                    {
                        namespaceNode = new TreeNode(@namespace);
                        moduleNode.Nodes.Add(namespaceNode);
                        namespaces.Add(namespaceNode);
                    }

                    TreeNode typeNode = new TreeNode(type.FullName);
                    namespaceNode.Nodes.Add(typeNode);

                    if (type.BaseType != null)
                    {
                        TreeNode baseTypeNode = new TreeNode("Base Type: " + type.BaseType.FullName);
                        typeNode.Nodes.Add(baseTypeNode);
                    }

                    if (type.DeclaringType != null)
                    {
                        TreeNode declaringTypeNode = new TreeNode("Declaring Type: " + type.DeclaringType.FullName);
                        typeNode.Nodes.Add(declaringTypeNode);
                    }

                    if (type.ElementType != null)
                    {
                        TreeNode elementTypeNode = new TreeNode("Element Type: " + type.ElementType.FullName);
                        typeNode.Nodes.Add(elementTypeNode);
                    }

                    if (type.Interfaces.Count != 0)
                    {
                        TreeNode interfacesNodes = new TreeNode("Interfaces");
                        typeNode.Nodes.Add(interfacesNodes);

                        foreach (MosaType interfaceType in type.Interfaces)
                        {
                            TreeNode interfaceNode = new TreeNode(interfaceType.FullName);
                            interfacesNodes.Nodes.Add(interfaceNode);
                        }
                    }

                    if (type.Fields.Count != 0)
                    {
                        TreeNode fieldsNode = new TreeNode("Fields");
                        if (showSizes)
                        {
                            fieldsNode.Text = fieldsNode.Text + " (Count: " + type.Fields.Count.ToString() + " - Size: " + typeLayout.GetTypeSize(type).ToString() + ")";
                        }

                        typeNode.Nodes.Add(fieldsNode);

                        foreach (MosaField field in type.Fields)
                        {
                            TreeNode fieldNode = new TreeNode(field.ShortName);
                            fieldsNode.Nodes.Add(fieldNode);

                            if (field.IsStatic)
                            {
                                fieldNode.Text = fieldNode.Text + " [Static]";
                            }

                            if (showSizes)
                            {
                                fieldNode.Text = fieldNode.Text + " (Size: " + typeLayout.GetFieldSize(field).ToString();

                                if (!field.IsStatic)
                                {
                                    fieldNode.Text = fieldNode.Text + " - Offset: " + typeLayout.GetFieldOffset(field).ToString();
                                }

                                fieldNode.Text = fieldNode.Text + ")";
                            }
                        }
                    }

                    if (type.Properties.Count != 0)
                    {
                        TreeNode propertiesNode = new TreeNode("Properties");
                        if (showSizes)
                        {
                            propertiesNode.Text = propertiesNode.Text + " (Count: " + type.Properties.Count.ToString() + ")";
                        }

                        typeNode.Nodes.Add(propertiesNode);

                        foreach (MosaProperty property in type.Properties)
                        {
                            TreeNode propertyNode = new ViewNode <MosaProperty>(property, property.ShortName);
                            propertiesNode.Nodes.Add(propertyNode);

                            if (property.GetterMethod != null)
                            {
                                TreeNode getterNode = new ViewNode <MosaMethod>(property.GetterMethod, property.GetterMethod.ShortName);
                                propertyNode.Nodes.Add(getterNode);

                                if (property.GetterMethod.IsStatic)
                                {
                                    getterNode.Text = getterNode.Text + " [Static]";
                                }

                                if (property.GetterMethod.IsAbstract)
                                {
                                    getterNode.Text = getterNode.Text + " [Abstract]";
                                }

                                if (property.GetterMethod.IsNewSlot)
                                {
                                    getterNode.Text = getterNode.Text + " [NewSlot]";
                                }

                                if (property.GetterMethod.IsVirtual)
                                {
                                    getterNode.Text = getterNode.Text + " [Virtual]";
                                }

                                if (property.GetterMethod.IsFinal)
                                {
                                    getterNode.Text = getterNode.Text + " [Final]";
                                }

                                if (property.GetterMethod.IsSpecialName)
                                {
                                    getterNode.Text = getterNode.Text + " [SpecialName]";
                                }

                                if (property.GetterMethod.IsRTSpecialName)
                                {
                                    getterNode.Text = getterNode.Text + " [RTSpecialName]";
                                }

                                if (property.GetterMethod.GenericArguments.Count != 0)
                                {
                                    TreeNode genericParameterNodes = new TreeNode("Generic Arguments Types");
                                    getterNode.Nodes.Add(genericParameterNodes);

                                    foreach (var genericParameter in property.GetterMethod.GenericArguments)
                                    {
                                        TreeNode GenericParameterNode = new TreeNode(genericParameter.Name);
                                        genericParameterNodes.Nodes.Add(GenericParameterNode);
                                    }
                                }
                            }

                            if (property.SetterMethod != null)
                            {
                                TreeNode setterNode = new ViewNode <MosaMethod>(property.SetterMethod, property.SetterMethod.ShortName);
                                propertyNode.Nodes.Add(setterNode);

                                if (property.SetterMethod.IsStatic)
                                {
                                    setterNode.Text = setterNode.Text + " [Static]";
                                }

                                if (property.SetterMethod.IsAbstract)
                                {
                                    setterNode.Text = setterNode.Text + " [Abstract]";
                                }

                                if (property.SetterMethod.IsNewSlot)
                                {
                                    setterNode.Text = setterNode.Text + " [NewSlot]";
                                }

                                if (property.SetterMethod.IsVirtual)
                                {
                                    setterNode.Text = setterNode.Text + " [Virtual]";
                                }

                                if (property.SetterMethod.IsFinal)
                                {
                                    setterNode.Text = setterNode.Text + " [Final]";
                                }

                                if (property.SetterMethod.IsSpecialName)
                                {
                                    setterNode.Text = setterNode.Text + " [SpecialName]";
                                }

                                if (property.SetterMethod.IsRTSpecialName)
                                {
                                    setterNode.Text = setterNode.Text + " [RTSpecialName]";
                                }

                                if (property.SetterMethod.GenericArguments.Count != 0)
                                {
                                    TreeNode genericParameterNodes = new TreeNode("Generic Arguments Types");
                                    setterNode.Nodes.Add(genericParameterNodes);

                                    foreach (var genericParameter in property.SetterMethod.GenericArguments)
                                    {
                                        TreeNode GenericParameterNode = new TreeNode(genericParameter.Name);
                                        genericParameterNodes.Nodes.Add(GenericParameterNode);
                                    }
                                }
                            }
                        }
                    }

                    if (type.Methods.Count != 0)
                    {
                        TreeNode methodsNode = new TreeNode("Methods");
                        typeNode.Nodes.Add(methodsNode);

                        foreach (MosaMethod method in type.Methods)
                        {
                            if (method.ShortName.StartsWith("set_") || method.ShortName.StartsWith("get_"))
                            {
                                continue;
                            }

                            TreeNode methodNode = new ViewNode <MosaMethod>(method, method.ShortName);
                            methodsNode.Nodes.Add(methodNode);

                            if (method.IsStatic)
                            {
                                methodNode.Text = methodNode.Text + " [Static]";
                            }

                            if (method.IsAbstract)
                            {
                                methodNode.Text = methodNode.Text + " [Abstract]";
                            }

                            if (method.IsNewSlot)
                            {
                                methodNode.Text = methodNode.Text + " [NewSlot]";
                            }

                            if (method.IsVirtual)
                            {
                                methodNode.Text = methodNode.Text + " [Virtual]";
                            }

                            if (method.IsFinal)
                            {
                                methodNode.Text = methodNode.Text + " [Final]";
                            }

                            if (method.IsSpecialName)
                            {
                                methodNode.Text = methodNode.Text + " [SpecialName]";
                            }

                            if (method.IsRTSpecialName)
                            {
                                methodNode.Text = methodNode.Text + " [RTSpecialName]";
                            }

                            if (method.GenericArguments.Count != 0)
                            {
                                TreeNode genericParameterNodes = new TreeNode("Generic Arguments Types");
                                methodNode.Nodes.Add(genericParameterNodes);

                                foreach (var genericParameter in method.GenericArguments)
                                {
                                    TreeNode GenericParameterNode = new TreeNode(genericParameter.Name);
                                    genericParameterNodes.Nodes.Add(GenericParameterNode);
                                }
                            }
                        }
                    }

                    if (typeLayout.GetMethodTable(type) != null)
                    {
                        TreeNode methodTableNode = new TreeNode("Method Table");
                        typeNode.Nodes.Add(methodTableNode);

                        foreach (MosaMethod method in typeLayout.GetMethodTable(type))
                        {
                            TreeNode methodNode = new ViewNode <MosaMethod>(method, method.ShortName);
                            methodTableNode.Nodes.Add(methodNode);
                        }
                    }
                }
            }

            treeView.EndUpdate();
        }
        /// <summary>
        /// Expands method call instruction represented by the context to perform the method call.
        /// </summary>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="context">The context.</param>
        public override void MakeCall(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context)
        {
            /*
             * Calling convention is right-to-left, pushed on the stack. Return value in EAX for integral
             * types 4 bytes or less, XMM0 for floating point and EAX:EDX for 64-bit. If this is a method
             * of a type, the this argument is moved to ECX right before the call.
             * If return value is value type, a stack local is allocated as a hidden parameter in caller
             * stack, the callee will then store the return value in the allocated space
             * The return value is the first parameter (even before this)
             * The callee will place the address of the return value into EAX and the caller will then
             * either retrieve the return value using compound move or will let one of the callers higher
             * in the caller chain handle the retrieval of the return value using compound move.
             */

            Operand target = context.Operand1;
            Operand result = context.Result;
            MosaMethod method = context.InvokeMethod;

            Debug.Assert(method != null, context.ToString());

            Operand scratch = Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.Pointer, scratchRegister);

            List<Operand> operands = BuildOperands(context);

            int stackSize = CalculateStackSizeForParameters(typeLayout, architecture, operands, method);

            context.Empty();

            int returnSize = 0;
            if (typeLayout.IsCompoundType(method.Signature.ReturnType))
            {
                returnSize = typeLayout.GetTypeSize(method.Signature.ReturnType);
            }

            if (stackSize != 0 || returnSize != 0)
            {
                ReserveStackSizeForCall(typeLayout.TypeSystem, context, returnSize + stackSize, scratch);
                PushOperands(compiler, typeLayout, context, method, operands, returnSize + stackSize, scratch);
            }

            // the mov/call two-instructions combo is to help facilitate the register allocator
            architecture.InsertMoveInstruction(context, scratch, target);
            architecture.InsertCallInstruction(context, scratch);

            CleanupReturnValue(compiler, typeLayout, context, result);
            FreeStackAfterCall(typeLayout.TypeSystem, context, returnSize + stackSize);
        }
 /// <summary>
 /// Pushes the specified instructions.
 /// </summary>
 /// <param name="compiler">The compiler.</param>
 /// <param name="typeLayout">The type layout.</param>
 /// <param name="context">The context.</param>
 /// <param name="op">The op.</param>
 /// <param name="stackSize">Size of the stack.</param>
 /// <param name="parameterSize">Size of the parameter.</param>
 /// <param name="scratch">The scratch.</param>
 private void Push(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context, Operand op, int stackSize, int parameterSize, Operand scratch)
 {
     if (op.Is64BitInteger)
     {
         architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(typeLayout.TypeSystem.BuiltIn.I4, scratch, stackSize), op.Low);
         architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(typeLayout.TypeSystem.BuiltIn.I4, scratch, stackSize + 4), op.High);
     }
     else if (op.IsR)
     {
         if (op.IsR8 && parameterSize == 4)
         {
             Operand op2 = Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.R4, returnFloatingPointRegister);
             architecture.InsertMoveInstruction(context, op2, op);
             architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(scratch.Type, scratch, stackSize), op2);
         }
         else
         {
             architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(scratch.Type, scratch, stackSize), op);
         }
     }
     else if (typeLayout.IsCompoundType(op.Type))
     {
         architecture.InsertCompoundMoveInstruction(compiler, context, Operand.CreateMemoryAddress(op.Type, scratch, stackSize), op, typeLayout.GetTypeSize(op.Type));
     }
     else
     {
         architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(op.Type, scratch, stackSize), op);
     }
 }
        /// <summary>
        /// Cleanups the return value.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="typeLayout">The type layouts.</param>
        /// <param name="context">The context.</param>
        /// <param name="result">The result.</param>
        private void CleanupReturnValue(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context, Operand result)
        {
            if (result == null)
                return;

            if (result.IsR)
            {
                Operand returnFP = Operand.CreateCPURegister(result.Type, returnFloatingPointRegister);
                context.AppendInstruction(IRInstruction.Gen, returnFP);
                architecture.InsertMoveInstruction(context, result, returnFP);
            }
            else if (result.Is64BitInteger)
            {
                Operand returnLow = Operand.CreateCPURegister(result.Type, return32BitRegister);
                Operand returnHigh = Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.U4, return64BitRegister);
                context.AppendInstruction(IRInstruction.Gen, returnLow);
                context.AppendInstruction(IRInstruction.Gen, returnHigh);
                architecture.InsertMoveInstruction(context, result.Low, returnLow);
                architecture.InsertMoveInstruction(context, result.High, returnHigh);
            }
            else if (typeLayout.IsCompoundType(result.Type))
            {
                int size = typeLayout.GetTypeSize(result.Type);
                Operand returnLow = Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.Pointer, return32BitRegister);
                context.AppendInstruction(IRInstruction.Gen, returnLow);
                architecture.InsertCompoundMoveInstruction(compiler, context, result, Operand.CreateMemoryAddress(result.Type, returnLow, 0), size);
            }
            else
            {
                Operand returnLow = Operand.CreateCPURegister(result.Type, return32BitRegister);
                context.AppendInstruction(IRInstruction.Gen, returnLow);
                architecture.InsertMoveInstruction(context, result, returnLow);
            }
        }
 /// <summary>
 /// Pushes the specified instructions.
 /// </summary>
 /// <param name="compiler">The compiler.</param>
 /// <param name="typeLayout">The type layout.</param>
 /// <param name="context">The context.</param>
 /// <param name="op">The op.</param>
 /// <param name="stackSize">Size of the stack.</param>
 /// <param name="parameterSize">Size of the parameter.</param>
 /// <param name="scratch">The scratch.</param>
 private void Push(BaseMethodCompiler compiler, MosaTypeLayout typeLayout, Context context, Operand op, int stackSize, int parameterSize, Operand scratch)
 {
     if (op.Is64BitInteger)
     {
         architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(typeLayout.TypeSystem.BuiltIn.I4, scratch, stackSize), op.Low);
         architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(typeLayout.TypeSystem.BuiltIn.I4, scratch, stackSize + 4), op.High);
     }
     else if (op.IsR)
     {
         if (op.IsR8 && parameterSize == 4)
         {
             Operand op2 = Operand.CreateCPURegister(typeLayout.TypeSystem.BuiltIn.R4, returnFloatingPointRegister);
             architecture.InsertMoveInstruction(context, op2, op);
             architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(scratch.Type, scratch, stackSize), op2);
         }
         else
         {
             architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(scratch.Type, scratch, stackSize), op);
         }
     }
     else if (typeLayout.IsCompoundType(op.Type))
     {
         architecture.InsertCompoundMoveInstruction(compiler, context, Operand.CreateMemoryAddress(op.Type, scratch, stackSize), op, typeLayout.GetTypeSize(op.Type));
     }
     else
     {
         architecture.InsertMoveInstruction(context, Operand.CreateMemoryAddress(op.Type, scratch, stackSize), op);
     }
 }
        private static int CalculateReturnSize(MosaTypeLayout typeLayout, Operand result)
        {
            if (result == null)
                return 0;

            if (typeLayout.IsCompoundType(result.Type))
            {
                return typeLayout.GetTypeSize(result.Type);
            }

            return 0;
        }
        private static int CalculateReturnSize(MosaTypeLayout typeLayout, MosaMethod method)
        {
            if (typeLayout.IsCompoundType(method.Signature.ReturnType))
            {
                return typeLayout.GetTypeSize(method.Signature.ReturnType);
            }

            return 0;
        }