/// <summary> /// Allows quick internal call replacements /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> /// <param name="internalMethod">The internal method to replace with.</param> /// <param name="internalClass">The internal class that has the internal method.</param> protected void Internal(Context context, BaseMethodCompiler methodCompiler, string internalMethod, string internalClass = "Internal") { if (context == null || methodCompiler == null || internalMethod == null || internalClass == null) throw new ArgumentNullException(); var type = methodCompiler.TypeSystem.GetTypeByName("Mosa.Runtime", internalClass); Debug.Assert(type != null, "Cannot find Mosa.Runtime." + internalClass); var method = type.FindMethodByName(internalMethod); Debug.Assert(method != null, "Cannot find " + internalMethod + " in " + type.Name); Operand callTargetOperand = Operand.CreateSymbolFromMethod(methodCompiler.TypeSystem, method); var operands = new Operand[context.OperandCount]; for (int i = 0; i < context.OperandCount; i++) operands[i] = context.GetOperand(i); Operand result = context.Result; context.SetInstruction(IRInstruction.Call, result, callTargetOperand); for (int i = 0; i < operands.Length; i++) { context.SetOperand(1 + i, operands[i]); } context.OperandCount = (byte)(1 + operands.Length); context.InvokeMethod = method; }
/// <summary> /// Validates the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); ctx.Result = ctx.Operand1; ctx.ResultCount = 2; }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, BaseMethodCompiler compiler) { base.Validate(ctx, compiler); var stackTypeForOperand1 = ctx.Operand1.StackType; var stackTypeForOperand2 = ctx.Operand2.StackType; if (ctx.Operand1.Type is ValueTypeSigType) { var op1Type = compiler.Method.Module.GetType((ctx.Operand1.Type as ValueTypeSigType).Token); if (op1Type.BaseType.FullName == "System.Enum") stackTypeForOperand1 = this.FromSigType(op1Type.Fields[0].SignatureType.Type); } if (ctx.Operand2.Type is ValueTypeSigType) { var op2Type = compiler.Method.Module.GetType((ctx.Operand2.Type as ValueTypeSigType).Token); if (op2Type.BaseType.FullName == "System.Enum") stackTypeForOperand2 = this.FromSigType(op2Type.Fields[0].SignatureType.Type); } var result = _opTable[(int)stackTypeForOperand1][(int)stackTypeForOperand2]; if (result == StackTypeCode.Unknown) throw new InvalidOperationException(@"Invalid stack result of instruction: " + result.ToString() + " (" + ctx.Operand1.ToString() + ")"); ctx.Result = compiler.CreateVirtualRegister(Operand.SigTypeFromStackType(result)); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var result = context.Result; var operand1 = context.Operand1; if (operand1.IsValueType) { InstructionNode def = operand1.Definitions[0]; var replacements = new List<Tuple<InstructionNode, int>>(); foreach (var use in operand1.Uses) for (int i = 0; i < use.OperandCount; i++) if (use.GetOperand(i) == operand1) replacements.Add(new Tuple<InstructionNode, int>(use, i)); foreach (var replace in replacements) replace.Item1.SetOperand(replace.Item2, def.Operand1); operand1 = def.Operand1; def.Empty(); if (operand1.IsMemoryAddress) { context.SetInstruction(IRInstruction.AddressOf, result, operand1); return; } } context.SetInstruction(IRInstruction.Move, result, operand1); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx"></param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); // Validate the typecode & determine the resulting stack type MosaType resultType; switch (opcode) { case OpCode.Conv_u: goto case OpCode.Conv_i; case OpCode.Conv_i: resultType = compiler.TypeSystem.BuiltIn.I; break; case OpCode.Conv_i1: resultType = compiler.TypeSystem.BuiltIn.I1; break; case OpCode.Conv_i2: resultType = compiler.TypeSystem.BuiltIn.I2; break; case OpCode.Conv_i4: resultType = compiler.TypeSystem.BuiltIn.I4; break; case OpCode.Conv_i8: resultType = compiler.TypeSystem.BuiltIn.I8; break; case OpCode.Conv_r4: resultType = compiler.TypeSystem.BuiltIn.R4; break; case OpCode.Conv_r8: resultType = compiler.TypeSystem.BuiltIn.R8; break; case OpCode.Conv_u1: resultType = compiler.TypeSystem.BuiltIn.U1; break; case OpCode.Conv_u2: resultType = compiler.TypeSystem.BuiltIn.U2; break; case OpCode.Conv_u4: resultType = compiler.TypeSystem.BuiltIn.U4; break; case OpCode.Conv_u8: resultType = compiler.TypeSystem.BuiltIn.U8; break; case OpCode.Conv_ovf_i: goto case OpCode.Conv_i; case OpCode.Conv_ovf_u: goto case OpCode.Conv_i; case OpCode.Conv_ovf_i_un: goto case OpCode.Conv_i; case OpCode.Conv_ovf_u_un: goto case OpCode.Conv_i; case OpCode.Conv_r_un: resultType = compiler.TypeSystem.BuiltIn.R8; break; default: throw new NotSupportedException(@"Overflow checking conversions not supported."); } ctx.Result = compiler.CreateVirtualRegister(resultType.GetStackType()); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); // Simple result is the same type as the unary argument ctx.Result = compiler.CreateVirtualRegister(ctx.Operand1.Type); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, BaseMethodCompiler compiler) { base.Validate(ctx, compiler); StackTypeCode result = StackTypeCode.Unknown; switch (opcode) { case OpCode.Add_ovf_un: result = _addovfunTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; case OpCode.Sub_ovf_un: result = _subovfunTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; default: result = _operandTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; } if (StackTypeCode.Unknown == result) throw new InvalidOperationException(@"Invalid operand types passed to " + opcode); ctx.Result = compiler.CreateVirtualRegister(Operand.SigTypeFromStackType(result)); }
private Operand GetRuntimeTypeHandle(Context context, BaseMethodCompiler methodCompiler) { var typeDef = Operand.CreateUnmanagedSymbolPointer(methodCompiler.TypeSystem, StringClassTypeDefinitionSymbolName); var runtimeTypeHandle = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.GetTypeByName("System", "RuntimeTypeHandle")); var before = context.InsertBefore(); before.SetInstruction(IRInstruction.Move, runtimeTypeHandle, typeDef); return runtimeTypeHandle; }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, BaseMethodCompiler compiler) { base.Validate(ctx, compiler); SZArraySigType arrayType = ctx.Operand1.Type as SZArraySigType; if (arrayType == null) throw new InvalidProgramException(@"Operand to ldlen is not a vector."); ctx.Result = compiler.CreateVirtualRegister(BuiltInSigType.IntPtr); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx"></param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, BaseMethodCompiler compiler) { base.Validate(ctx, compiler); // Validate the operand StackTypeCode result = _typeCodes[(int)ctx.Operand1.StackType]; if (StackTypeCode.Unknown == result) throw new InvalidOperationException(@"Invalid operand to Neg instruction [" + result + "]"); ctx.Result = compiler.CreateVirtualRegister(ctx.Operand1.Type); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); //FIXME: Intent? //SigType destType = ctx.Operand1.Type; //Debug.Assert(destType is PtrSigType || destType is RefSigType, @"Destination operand not a pointer or reference."); //if (!(destType is PtrSigType || destType is RefSigType)) // throw new InvalidOperationException(@"Invalid operand."); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); var result = operandTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; Debug.Assert(StackTypeCode.Unknown != result, @"Can't shift with the given virtualLocal operands."); if (StackTypeCode.Unknown == result) throw new InvalidOperationException(@"Invalid virtualLocal state for pairing (" + ctx.Operand1.Type.GetStackType() + ", " + ctx.Operand2.Type.GetStackType() + ")"); ctx.Result = compiler.CreateVirtualRegister(compiler.TypeSystem.GetStackTypeFromCode(result)); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, BaseMethodCompiler compiler) { base.Validate(ctx, compiler); StackTypeCode result = _operandTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; Debug.Assert(StackTypeCode.Unknown != result, @"Can't shift with the given stack operands."); if (StackTypeCode.Unknown == result) throw new InvalidOperationException(@"Invalid stack state for pairing (" + ctx.Operand1.StackType + ", " + ctx.Operand2.StackType + ")"); ctx.Result = compiler.CreateVirtualRegister(Operand.SigTypeFromStackType(result)); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx"></param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); // Validate the operand var result = opTable[(int)ctx.Operand1.Type.GetStackTypeCode()]; if (StackTypeCode.Unknown == result) throw new InvalidOperationException(@"Invalid operand to Not instruction."); ctx.Result = compiler.CreateVirtualRegister(ctx.Operand1.Type); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var result = context.Result; var operand1 = context.Operand1; if (operand1.IsValueType) { operand1 = context.Previous.Operand1; context.Previous.Empty(); context.SetInstruction(IRInstruction.AddressOf, result, operand1); return; } context.SetInstruction(IRInstruction.Move, result, operand1); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var method = methodCompiler.Compiler.PlatformInternalRuntimeType.FindMethodByName("AllocateString"); Operand callTargetOperand = Operand.CreateSymbolFromMethod(methodCompiler.TypeSystem, method); Operand typeDefinitionOperand = GetRuntimeTypeHandle(context, methodCompiler); Operand lengthOperand = context.Operand1; Operand result = context.Result; context.SetInstruction(IRInstruction.Call, result, callTargetOperand, typeDefinitionOperand, lengthOperand); context.InvokeMethod = method; }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); // If we're ldind.i8, fix an IL deficiency that the result may be U8 if (opcode == OpCode.Ldind_i8 && elementType.Value == MosaTypeCode.I8) { if (ctx.Operand1.Type.ElementType != null && ctx.Operand1.Type.ElementType.IsU8) { ctx.Result = compiler.CreateVirtualRegister(compiler.TypeSystem.BuiltIn.U8); } } }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); var stackTypeForOperand1 = ctx.Operand1.Type.GetStackTypeCode(); var stackTypeForOperand2 = ctx.Operand2.Type.GetStackTypeCode(); var result = opTable[(int)stackTypeForOperand1][(int)stackTypeForOperand2]; if (result == StackTypeCode.Unknown) { throw new InvalidOperationException(@"Invalid virtualLocal result of instruction: " + result.ToString() + " (" + ctx.Operand1.ToString() + ")"); } ctx.Result = compiler.CreateVirtualRegister(compiler.TypeSystem.GetStackTypeFromCode(result)); }
/// <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> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var size = InstructionSize.Size32; if (context.OperandCount == 1) { context.SetInstruction(IRInstruction.LoadInteger, size, context.Result, context.Operand1, Operand.CreateConstant(methodCompiler.TypeSystem, 0)); } else if (context.OperandCount == 2) { context.SetInstruction(IRInstruction.LoadInteger, size, context.Result, context.Operand1, context.Operand2); } else { throw new InvalidCompilerException(); } }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var size = methodCompiler.Architecture.NativePointerSize == 4 ? InstructionSize.Size32 : InstructionSize.Size64; if (context.OperandCount == 1) { context.SetInstruction(IRInstruction.Load, size, context.Result, context.Operand1, Operand.CreateConstantSignedInt(methodCompiler.TypeSystem, 0)); } else if (context.OperandCount == 2) { context.SetInstruction(IRInstruction.Load, size, context.Result, context.Operand1, context.Operand2); } else { throw new InvalidCompilerException(); } }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { string arch = "Mosa.Platform.Internal." + methodCompiler.Architecture.PlatformName; var type = methodCompiler.TypeSystem.GetTypeByName(arch, "Runtime"); Debug.Assert(type != null, "Cannot find " + arch + ".Runtime"); var method = type.FindMethodByName("InitializeArray"); Operand callTargetOperand = Operand.CreateSymbolFromMethod(methodCompiler.TypeSystem, method); Operand arrayOperand = context.Operand1; Operand fieldOperand = context.Operand2; context.SetInstruction(IRInstruction.Call, null, callTargetOperand, arrayOperand, fieldOperand); context.MosaMethod = method; }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, BaseMethodCompiler compiler) { base.Validate(ctx, compiler); // Make sure the base is a typed reference throw new NotImplementedException(); /* if (!Object.ReferenceEquals(_operands[0].Type, MetadataTypeReference.FromName(compiler.Assembly.Metadata, @"System", @"TypedReference"))) { Debug.Assert(false); throw new InvalidProgramException(@"Invalid stack object."); } // Push the loaded value _results[0] = CreateResultOperand(_typeRef); */ }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { string arch = "Mosa.Platform.Internal." + methodCompiler.Architecture.PlatformName; var type = methodCompiler.TypeSystem.GetTypeByName(arch, "Runtime"); Debug.Assert(type != null, "Cannot find " + arch + ".Runtime"); var method = type.FindMethodByName("AllocateString"); Operand callTargetOperand = Operand.CreateSymbolFromMethod(methodCompiler.TypeSystem, method); Operand methodTableOperand = Operand.CreateUnmanagedSymbolPointer(methodCompiler.TypeSystem, StringClassMethodTableSymbolName); Operand lengthOperand = context.Operand1; Operand result = context.Result; context.SetInstruction(IRInstruction.Call, result, callTargetOperand, methodTableOperand, lengthOperand); context.MosaMethod = method; }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); StackTypeCode result = StackTypeCode.Unknown; switch (opcode) { case OpCode.Add: result = addTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; break; case OpCode.Sub: result = subTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; break; default: result = operandTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; break; } if (result == StackTypeCode.Unknown) { throw new InvalidOperationException(@"Invalid operand types passed to " + opcode); } MosaType resultType = null; if (StackTypeCode.UnmanagedPointer != result) { resultType = compiler.TypeSystem.GetStackTypeFromCode(result); if (result == StackTypeCode.F && ctx.Operand1.Type.IsR4 && ctx.Operand2.Type.IsR4) resultType = compiler.TypeSystem.BuiltIn.R4; } else { if (ctx.Operand1.Type.IsPointer) { resultType = ctx.Operand1.Type; } else if (ctx.Operand2.Type.IsPointer) { resultType = ctx.Operand2.Type; } else throw new InvalidOperationException(@"Invalid operand types passed to " + opcode); } //Debug.Assert(resultType != null, ctx.ToString()); ctx.Result = compiler.CreateVirtualRegister(resultType); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); StackTypeCode result = StackTypeCode.Unknown; switch (opcode) { case OpCode.Add_ovf_un: result = addovfunTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; break; case OpCode.Sub_ovf_un: result = subovfunTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; break; default: result = operandTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; break; } if (StackTypeCode.Unknown == result) { throw new InvalidOperationException(@"Invalid operand types passed to " + opcode); } ctx.Result = compiler.CreateVirtualRegister(compiler.TypeSystem.GetStackTypeFromCode(result)); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Internal(context, methodCompiler, context.InvokeMethod.Name, "InternalsForObject"); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { context.SetInstruction(IRInstruction.AddressOf, context.Result, context.Operand1); }
/// <summary> /// Lays out all parameters of the method. /// </summary> /// <param name="compiler">The method compiler providing the parameters.</param> private void LayoutParameters(BaseMethodCompiler compiler) { List<Operand> paramOps = new List<Operand>(); int offset = 0; if (compiler.Method.Signature.HasThis || compiler.Method.Signature.HasExplicitThis) ++offset; for (int i = 0; i < compiler.Method.Parameters.Count + offset; ++i) paramOps.Add(compiler.GetParameterOperand(i)); LayoutVariables(paramOps, callingConvention, callingConvention.OffsetOfFirstParameter, -1); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="methodCompiler">The method compiler.</param> void IIntrinsicInternalMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var result = context.Result; var operand1 = context.Operand1; context.SetInstruction(IRInstruction.MoveInteger, result, operand1); }
/// <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; context.Result = compiler.CreateVirtualRegister(method.Signature.ReturnType.GetStackType()); } else { context.ResultCount = 0; } context.OperandCount = (byte)paramCount; }