/// <summary> /// Sets the invoke target. /// </summary> /// <param name="context">The context.</param> /// <param name="compiler">The compiler.</param> /// <param name="method">The method.</param> private static void SetInvokeTarget(InstructionNode context, BaseMethodCompiler compiler, MosaMethod method) { context.InvokeMethod = method; // Fix the parameter list int paramCount = method.Signature.Parameters.Count; if (method.HasThis && !method.HasExplicitThis) { paramCount++; } // Setup operands for parameters and the return value if (!method.Signature.ReturnType.IsVoid) { context.ResultCount = 1; if (compiler.StoreOnStack(method.Signature.ReturnType)) { context.Result = AllocateVirtualRegisterOrStackSlot(compiler, method.Signature.ReturnType); } else { context.Result = compiler.CreateVirtualRegister(method.Signature.ReturnType.GetStackType()); } } else { context.ResultCount = 0; } context.OperandCount = (byte)paramCount; }
/// <summary> /// Requests the calling convention to create an appropriate move instruction to populate the return /// value of a method. /// </summary> /// <param name="compiler">The compiler.</param> /// <param name="context">The context.</param> /// <param name="operand">The operand, that's holding the return value.</param> public override void SetReturnValue(BaseMethodCompiler compiler, Context context, Operand operand) { int size, alignment; architecture.GetTypeRequirements(compiler.TypeLayout, operand.Type, out size, out alignment); size = Alignment.AlignUp(size, alignment); if (operand.IsR4) { architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, returnFloatingPointRegister), operand); } else if (operand.IsR8) { architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, returnFloatingPointRegister), operand); } else if (operand.IsLong) { MosaType highType = (operand.IsI8) ? compiler.TypeSystem.BuiltIn.I4 : compiler.TypeSystem.BuiltIn.U4; architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(compiler.TypeSystem.BuiltIn.U4, return32BitRegister), operand.Low); architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(highType, return64BitRegister), operand.High); } else if (compiler.StoreOnStack(operand.Type)) { int size2 = compiler.TypeLayout.GetTypeSize(operand.Type); var OffsetOfFirstParameterOperand = Operand.CreateConstant(compiler.TypeSystem, OffsetOfFirstParameter); architecture.InsertCompoundCopy(compiler, context, compiler.StackFrame, OffsetOfFirstParameterOperand, compiler.StackFrame, operand, size2); } else { architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, return32BitRegister), operand); } }
/// <summary> /// Pushes the specified instructions. /// </summary> /// <param name="compiler">The compiler.</param> /// <param name="context">The context.</param> /// <param name="operand">The op.</param> /// <param name="offset">Size of the stack.</param> /// <param name="size">Size of the parameter.</param> /// <param name="scratch">The scratch.</param> private void Push(BaseMethodCompiler compiler, Context context, Operand operand, int offset, int size, Operand scratch) { var offsetOperand = Operand.CreateConstant(compiler.TypeSystem, offset); if (operand.Is64BitInteger) { var offset4Operand = Operand.CreateConstant(compiler.TypeSystem, offset + 4); architecture.InsertStoreInstruction(context, scratch, offsetOperand, operand.Low); architecture.InsertStoreInstruction(context, scratch, offset4Operand, operand.High); } else if (operand.IsR) { if (operand.IsR8 && size == 4) { Operand op2 = Operand.CreateCPURegister(compiler.TypeSystem.BuiltIn.R4, returnFloatingPointRegister); architecture.InsertMoveInstruction(context, op2, operand); architecture.InsertStoreInstruction(context, scratch, offsetOperand, op2); } else { architecture.InsertStoreInstruction(context, scratch, offsetOperand, operand); } } else if (compiler.StoreOnStack(operand.Type)) { var offset2 = Operand.CreateConstant(compiler.TypeSystem, offset); architecture.InsertCompoundCopy(compiler, context, scratch, offset2, compiler.StackFrame, operand, compiler.TypeLayout.GetTypeSize(operand.Type)); } else { architecture.InsertStoreInstruction(context, scratch, offsetOperand, operand); } }
private static int CalculateReturnSize(BaseMethodCompiler compiler, MosaMethod method) { if (compiler.StoreOnStack(method.Signature.ReturnType)) { return(compiler.TypeLayout.GetTypeSize(method.Signature.ReturnType)); } return(0); }
private static int CalculateReturnSize(BaseMethodCompiler compiler, Operand result) { if (result == null) { return(0); } if (compiler.StoreOnStack(result.Type)) { return(compiler.TypeLayout.GetTypeSize(result.Type)); } return(0); }
/// <summary> /// Cleanups the return value. /// </summary> /// <param name="compiler">The compiler.</param> /// <param name="context">The context.</param> /// <param name="result">The result.</param> private void CleanupReturnValue(BaseMethodCompiler compiler, 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(compiler.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 (compiler.StoreOnStack(result.Type)) { Debug.Assert(result.IsStackLocal); int size = compiler.TypeLayout.GetTypeSize(result.Type); var stackPointerRegister = Operand.CreateCPURegister(compiler.TypeSystem.BuiltIn.Pointer, architecture.StackPointerRegister); architecture.InsertCompoundCopy(compiler, context, compiler.StackFrame, result, stackPointerRegister, compiler.ConstantZero, 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="operand">The op.</param> /// <param name="offset">Size of the stack.</param> /// <param name="size">Size of the parameter.</param> /// <param name="scratch">The scratch.</param> private void Push(BaseMethodCompiler compiler, Context context, Operand operand, int offset, int size, Operand scratch) { var offsetOperand = Operand.CreateConstant(compiler.TypeSystem, offset); if (operand.Is64BitInteger) { var offset4Operand = Operand.CreateConstant(compiler.TypeSystem, offset + 4); architecture.InsertStoreInstruction(context, scratch, offsetOperand, operand.Low); architecture.InsertStoreInstruction(context, scratch, offset4Operand, operand.High); } else if (operand.IsR) { if (operand.IsR8 && size == 4) { Operand op2 = Operand.CreateCPURegister(compiler.TypeSystem.BuiltIn.R4, returnFloatingPointRegister); architecture.InsertMoveInstruction(context, op2, operand); architecture.InsertStoreInstruction(context, scratch, offsetOperand, op2); } else { architecture.InsertStoreInstruction(context, scratch, offsetOperand, operand); } } else if (compiler.StoreOnStack(operand.Type)) { var offset2 = Operand.CreateConstant(compiler.TypeSystem, offset); architecture.InsertCompoundMoveInstruction(compiler, context, scratch, offset2, compiler.StackFrame, operand, compiler.TypeLayout.GetTypeSize(operand.Type)); } else { architecture.InsertStoreInstruction(context, scratch, offsetOperand, operand); } }
/// <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, 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(compiler.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 (compiler.StoreOnStack(result.Type)) { Debug.Assert(result.IsStackLocal); int size = compiler.TypeLayout.GetTypeSize(result.Type); var stackPointerRegister = Operand.CreateCPURegister(compiler.TypeSystem.BuiltIn.Pointer, architecture.StackPointerRegister); architecture.InsertCompoundMoveInstruction(compiler, context, result, result, stackPointerRegister, compiler.ConstantZero, size); } else { Operand returnLow = Operand.CreateCPURegister(result.Type, return32BitRegister); context.AppendInstruction(IRInstruction.Gen, returnLow); architecture.InsertMoveInstruction(context, result, returnLow); } }
private static int CalculateReturnSize(BaseMethodCompiler compiler, Operand result) { if (result == null) return 0; if (compiler.StoreOnStack(result.Type)) { return compiler.TypeLayout.GetTypeSize(result.Type); } return 0; }
private static int CalculateReturnSize(BaseMethodCompiler compiler, MosaMethod method) { if (compiler.StoreOnStack(method.Signature.ReturnType)) { return compiler.TypeLayout.GetTypeSize(method.Signature.ReturnType); } return 0; }
/// <summary> /// Requests the calling convention to create an appropriate move instruction to populate the return /// value of a method. /// </summary> /// <param name="compiler">The compiler.</param> /// <param name="typeLayout">The type layouts.</param> /// <param name="context">The context.</param> /// <param name="operand">The operand, that's holding the return value.</param> public override void SetReturnValue(BaseMethodCompiler compiler, Context context, Operand operand) { int size, alignment; architecture.GetTypeRequirements(compiler.TypeLayout, operand.Type, out size, out alignment); size = Alignment.AlignUp(size, alignment); if (operand.IsR4) { architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, returnFloatingPointRegister), operand); } else if (operand.IsR8) { architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, returnFloatingPointRegister), operand); } else if (operand.IsLong) { MosaType highType = (operand.IsI8) ? compiler.TypeSystem.BuiltIn.I4 : compiler.TypeSystem.BuiltIn.U4; architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(compiler.TypeSystem.BuiltIn.U4, return32BitRegister), operand.Low); architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(highType, return64BitRegister), operand.High); } else if (size == 4 || size == 2 || size == 1) { architecture.InsertMoveInstruction(context, Operand.CreateCPURegister(operand.Type, return32BitRegister), operand); } else if (compiler.StoreOnStack(operand.Type)) { int size2 = compiler.TypeLayout.GetTypeSize(operand.Type); var OffsetOfFirstParameterOperand = Operand.CreateConstant(compiler.TypeSystem, OffsetOfFirstParameter); architecture.InsertCompoundMoveInstruction(compiler, context, compiler.StackFrame, OffsetOfFirstParameterOperand, compiler.StackFrame, operand, size2); } }
/// <summary> /// Sets the invoke target. /// </summary> /// <param name="context">The context.</param> /// <param name="compiler">The compiler.</param> /// <param name="method">The method.</param> private static void SetInvokeTarget(InstructionNode context, BaseMethodCompiler compiler, MosaMethod method) { context.InvokeMethod = method; // Fix the parameter list int paramCount = method.Signature.Parameters.Count; if (method.HasThis && !method.HasExplicitThis) paramCount++; // Setup operands for parameters and the return value if (!method.Signature.ReturnType.IsVoid) { context.ResultCount = 1; if (compiler.StoreOnStack(method.Signature.ReturnType)) { context.Result = AllocateVirtualRegisterOrStackSlot(compiler, method.Signature.ReturnType); } else { context.Result = compiler.CreateVirtualRegister(method.Signature.ReturnType.GetStackType()); } } else { context.ResultCount = 0; } context.OperandCount = (byte)paramCount; }