/// <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, IMethodCompiler compiler) { base.Validate(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, IMethodCompiler 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, IMethodCompiler 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 Validate(Context ctx, IMethodCompiler 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> /// Sets the invoke target. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> /// <param name="method">The method.</param> private static void SetInvokeTarget(Context ctx, IMethodCompiler compiler, RuntimeMethod method) { if (method == null) throw new ArgumentNullException(@"method"); // Signature of the call target // Number of parameters required for the call ctx.InvokeTarget = method; // Retrieve the target signature MethodSignature signature = ctx.InvokeTarget.Signature; // Fix the parameter list byte paramCount = (byte)signature.Parameters.Length; if (signature.HasThis && !signature.HasExplicitThis) paramCount++; // Setup operands for parameters and the return value if (signature.ReturnType.Type != CilElementType.Void) { ctx.ResultCount = 1; ctx.Result = compiler.CreateVirtualRegister(signature.ReturnType); } else ctx.ResultCount = 0; ctx.OperandCount = paramCount; }
/// <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, IMethodCompiler 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)); }
/// <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, IMethodCompiler compiler) { base.Validate(ctx, compiler); StackTypeCode result = StackTypeCode.Unknown; switch (opcode) { case OpCode.Add: result = addTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; case OpCode.Sub: result = subTable[(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); SigType resultType; if (result != StackTypeCode.Ptr) { resultType = Operand.SigTypeFromStackType(result); } else { // Copy the pointer element type PtrSigType op0 = ctx.Operand1.Type as PtrSigType; PtrSigType op1 = ctx.Operand2.Type as PtrSigType; if (op0 != null) resultType = new PtrSigType(op0.CustomMods, op0.ElementType); else if (op1 != null) resultType = new PtrSigType(op1.CustomMods, op1.ElementType); else throw new InvalidOperationException(); } ctx.Result = compiler.CreateVirtualRegister(resultType); }
/// <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, IMethodCompiler compiler) { base.Validate(ctx, compiler); // Validate the typecode & determine the resulting stack type SigType resultType; switch (opcode) { case OpCode.Conv_u: goto case OpCode.Conv_i; case OpCode.Conv_i: resultType = compiler.Architecture.NativeType; break; case OpCode.Conv_i1: resultType = BuiltInSigType.SByte; break; case OpCode.Conv_i2: resultType = BuiltInSigType.Int16; break; case OpCode.Conv_i4: resultType = BuiltInSigType.Int32; break; case OpCode.Conv_i8: resultType = BuiltInSigType.Int64; break; case OpCode.Conv_r4: resultType = BuiltInSigType.Single; break; case OpCode.Conv_r8: resultType = BuiltInSigType.Double; break; case OpCode.Conv_u1: resultType = BuiltInSigType.Byte; break; case OpCode.Conv_u2: resultType = BuiltInSigType.UInt16; break; case OpCode.Conv_u4: resultType = BuiltInSigType.UInt32; break; case OpCode.Conv_u8: resultType = BuiltInSigType.UInt64; 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; default: throw new NotSupportedException(@"Overflow checking conversions not supported."); } 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 Validate(Context ctx, IMethodCompiler compiler) { base.Validate(ctx, compiler); // If we're ldind.i8, fix an IL deficiency that the result may be U8 if (opcode == OpCode.Ldind_i8 && typeRef.Type == CilElementType.I8) { SigType opType = ctx.Operand1.Type; RefSigType rst = opType as RefSigType; PtrSigType ptr = opType as PtrSigType; if (rst != null && rst.ElementType.Type == CilElementType.U8 || ptr != null && ptr.ElementType.Type == CilElementType.U8) { ctx.Result = compiler.CreateVirtualRegister(BuiltInSigType.UInt64); } } }
/// <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, IMethodCompiler 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)); }