/// <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); }
/// <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> /// 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; } }
/// <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; }
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); }
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; }