private static TypeDescriptor[] ReduceTypes(TypeDescriptor[] types) { Contract.Requires<ArgumentException>(types != null); return types .Select(t => TypeLowering.Instance.GetHardwareType(t)) .ToArray(); }
public void RequireType(TypeDescriptor type, DesignDescriptor design) { if (!type.HasIntrinsicTypeOverride && !type.CILType.IsPrimitive) { design.TypeLib.AddType(type); CurComponent.AddDependency(_design.TypeLib.GetPackage(type.CILType)); } }
private bool IsFix(TypeDescriptor inType, out FixFormat format) { if (inType.CILType.Equals(typeof(SFix)) || inType.CILType.Equals(typeof(UFix))) { format = inType.GetFixFormat(); return true; } format = null; return false; }
private void ComputeDependentTypes() { if (!CILType.IsPrimitive) { var fields = CILType.GetFields( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { bool consider = (CILType.IsValueType && !HasIntrinsicTypeOverride) || field.HasCustomOrInjectedAttribute<DependentType>(); if (!consider) continue; object fieldVal = _sample == null ? null : field.GetValue(_sample); if (fieldVal == null) _memberTypes[field] = new TypeDescriptor(field.FieldType); else _memberTypes[field] = new TypeDescriptor(fieldVal); } var properties = CILType.GetProperties( BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo prop in properties) { bool consider = prop.HasCustomOrInjectedAttribute<DependentType>(); if (!consider) continue; object propVal = _sample == null ? null : prop.GetValue(_sample, new object[0]); if (propVal == null) _memberTypes[prop] = new TypeDescriptor(prop.PropertyType); else _memberTypes[prop] = new TypeDescriptor(propVal); } } }
/// <summary> /// Represents the described multi-dimensional array as array of arrays. Only applicable to array types. /// </summary> public TypeDescriptor[] MakeRank1Types() { if (Rank == 0) throw new InvalidOperationException("This operation is possible for types with Rank >= 1"); if (Rank == 1) return new TypeDescriptor[] { this }; if (!CILType.IsArray) throw new InvalidOperationException("This operation is possible for arrays"); TypeDescriptor[] result = new TypeDescriptor[Rank]; Type innerType = CILType.GetElementType(); TypeDescriptor tdElem = Element0Type; for (int i = result.Length - 1; i >= 0; i--) { innerType = innerType.MakeArrayType(); result[i] = new TypeDescriptor() { _sample = this._sample, CILType = innerType, HasIntrinsicTypeOverride = false, TypeParams = new object[] { TypeParams[i] }, Constraints = this.Constraints == null ? null : new Range[] { Constraints[i] }, IsArtificial = true, IsUnconstrained = false, Element0Type = tdElem }; tdElem = result[i]; } return result; }
internal TypeDescriptor Clone() { var copy = new TypeDescriptor(); copy.CILType = CILType; copy._sample = _sample; copy.InitTypeParams(); copy.ComputeDependentTypes(); copy.IsUnconstrained = IsUnconstrained; return copy; }
/// <summary> /// Constructs a new array element reference literal. /// </summary> /// <param name="arrayExpr">expression representing the referenced array</param> /// <param name="elemType">element type descriptor</param> /// <param name="indices">expressions representing the accessed array indices</param> public ArrayRef(Expression arrayExpr, TypeDescriptor elemType, params Expression[] indices) { if (arrayExpr == null || indices == null || elemType == null) throw new ArgumentException(); ArrayExpr = arrayExpr; Indices = indices; _type = elemType; }
/// <summary> /// Adjusts thee variable type. /// </summary> /// <param name="type">new variable type, which must be a refinement of its former type</param> public void UpgradeType(TypeDescriptor type) { _type = type; }
public ActualTypeAttribute(TypeDescriptor originalType) { ActualType = originalType; }
/// <summary> /// Constructs a new instance. /// </summary> /// <param name="sourceType">source type of the conversion</param> /// <param name="destType">destination type of the conversion</param> /// <param name="reinterpret"><c>true</c> if the conversion has re-interpret semantics</param> public CastParams(Type sourceType, TypeDescriptor destType, bool reinterpret) { SourceType = sourceType; DestType = destType; Reinterpret = reinterpret; }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { XilinxProject xproj = proj as XilinxProject; if (xproj == null) return null; Type otype = operandTypes[0].CILType; if (!operandTypes.All(t => t.CILType.Equals(otype))) return null; Type rtype = resultTypes[0].CILType; FloatingPointCore fpu = null; CoreConfiguration cfg = null; switch (instr.Name) { case InstructionCodes.Add: case InstructionCodes.Sub: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.AddSubtract, Precision = prec, ResultPrecision = prec, }; cfg = Config[prec, FloatingPointCore.EFunction.AddSubtract]; if (cfg.UseDedicatedAddSub) { if (instr.Name.Equals(InstructionCodes.Add)) fpu.AddSubSel = FloatingPointCore.EAddSub.Add; else fpu.AddSubSel = FloatingPointCore.EAddSub.Subtract; } else { fpu.AddSubSel = FloatingPointCore.EAddSub.Both; } } break; case InstructionCodes.IsEq: case InstructionCodes.IsGt: case InstructionCodes.IsGte: case InstructionCodes.IsLt: case InstructionCodes.IsLte: case InstructionCodes.IsNEq: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.Compare, Precision = prec }; cfg = Config[prec, FloatingPointCore.EFunction.Compare]; if (cfg.UseDedicatedCmp) { switch (instr.Name) { case InstructionCodes.IsEq: fpu.CompareSel = FloatingPointCore.ECompareOp.Equal; break; case InstructionCodes.IsGt: fpu.CompareSel = FloatingPointCore.ECompareOp.GreaterThan; break; case InstructionCodes.IsGte: fpu.CompareSel = FloatingPointCore.ECompareOp.GreaterThanOrEqual; break; case InstructionCodes.IsLt: fpu.CompareSel = FloatingPointCore.ECompareOp.LessThan; break; case InstructionCodes.IsLte: fpu.CompareSel = FloatingPointCore.ECompareOp.LessThanOrEqual; break; case InstructionCodes.IsNEq: fpu.CompareSel = FloatingPointCore.ECompareOp.NotEqual; break; default: throw new NotImplementedException(); } } else { fpu.CompareSel = FloatingPointCore.ECompareOp.Programmable; } fpu.ResultPrecision = FloatingPointCore.EPrecision.Custom; fpu.ResultExponentWidth = 1; fpu.ResultFractionWidth = 0; } break; case InstructionCodes.Mul: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.Multiply, Precision = prec, ResultPrecision = prec }; cfg = Config[prec, FloatingPointCore.EFunction.Multiply]; } break; case InstructionCodes.Div: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.Divide, Precision = prec, ResultPrecision = prec }; cfg = Config[prec, FloatingPointCore.EFunction.Divide]; } break; case InstructionCodes.Sqrt: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.SquareRoot, Precision = prec, ResultPrecision = prec }; cfg = Config[prec, FloatingPointCore.EFunction.SquareRoot]; } break; case InstructionCodes.Convert: { FloatingPointCore.EPrecision inprec = FloatingPointCore.EPrecision.Single; bool infloat = false; FixFormat infmt = null; if (otype.Equals(typeof(float))) { inprec = FloatingPointCore.EPrecision.Single; infloat = true; } else if (otype.Equals(typeof(double))) { inprec = FloatingPointCore.EPrecision.Double; infloat = true; } else if (otype.Equals(typeof(SFix)) || otype.Equals(typeof(Signed))) { inprec = FloatingPointCore.EPrecision.Custom; infloat = false; infmt = SFix.GetFormat(operandTypes[0]); } else { return null; } FloatingPointCore.EPrecision outprec = FloatingPointCore.EPrecision.Single; bool outfloat = false; FixFormat outfmt = null; if (rtype.Equals(typeof(float))) { outprec = FloatingPointCore.EPrecision.Single; outfloat = true; } else if (rtype.Equals(typeof(double))) { outprec = FloatingPointCore.EPrecision.Double; outfloat = true; } else if (rtype.Equals(typeof(SFix)) || rtype.Equals(typeof(Signed))) { outprec = FloatingPointCore.EPrecision.Custom; outfloat = false; outfmt = SFix.GetFormat(resultTypes[0]); } else { return null; } FloatingPointCore.EFunction func; if (!infloat && !outfloat) return null; else if (infloat && outfloat) func = FloatingPointCore.EFunction.FloatToFloat; else if (infloat) func = FloatingPointCore.EFunction.FloatToFixed; else func = FloatingPointCore.EFunction.FixedToFloat; fpu = new FloatingPointCore() { Function = func, Precision = inprec, ResultPrecision = outprec }; if (infmt != null) { fpu.ExponentWidth = infmt.IntWidth; fpu.FractionWidth = infmt.FracWidth; } if (outfmt != null) { fpu.ResultExponentWidth = outfmt.IntWidth; fpu.ResultFractionWidth = outfmt.FracWidth; } FloatingPointCore.EPrecision prec = infloat ? inprec : outprec; cfg = Config[prec, FloatingPointCore.EFunction.Multiply]; } break; default: return null; } fpu.TargetDeviceFamily = xproj.DeviceFamily; fpu.TargetISEVersion = xproj.ISEVersion; if (cfg.EnableDeviceCapabilityDependentDSPUsage) { switch (fpu.Function) { case FloatingPointCore.EFunction.Multiply: switch (xproj.DeviceFamily) { case EDeviceFamily.Spartan3: case EDeviceFamily.Spartan3A_3AN: case EDeviceFamily.Spartan3E: case EDeviceFamily.Automotive_Spartan3: case EDeviceFamily.Automotive_Spartan3A: case EDeviceFamily.Automotive_Spartan3E: if (cfg.DSPUsageRatio < 0.5f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage; else fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; break; default: if (cfg.DSPUsageRatio < 0.25f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; else if (cfg.DSPUsageRatio < 0.50f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.MediumUsage; else if (cfg.DSPUsageRatio < 0.75f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.MaxUsage; else fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage; break; } break; case FloatingPointCore.EFunction.AddSubtract: if (fpu.Precision == FloatingPointCore.EPrecision.Custom) { fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; } else { switch (xproj.DeviceFamily) { case EDeviceFamily.Virtex4: case EDeviceFamily.Virtex5: case EDeviceFamily.Virtex6: case EDeviceFamily.Virtex6_LowPower: if (cfg.DSPUsageRatio < 0.5f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; else fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage; break; default: fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; break; } } break; default: fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; break; } } else { fpu.DSP48EUsage = cfg.DSP48EUsage; } fpu.HasCE = cfg.HasCE; fpu.HasDivideByZero = cfg.HasDivideByZero; fpu.HasInvalidOp = cfg.HasInvalidOp; fpu.HasOperationND = cfg.HasOperationND; fpu.HasOperationRFD = cfg.HasOperationRFD; fpu.HasOverflow = cfg.HasOverflow; fpu.HasRdy = cfg.HasRdy; fpu.HasSCLR = cfg.HasSCLR; if (cfg.UseMaximumLatency) { fpu.UseMaximumLatency = true; } else if (cfg.SpecifyLatencyRatio) { fpu.UseMaximumLatency = false; fpu.Latency = (int)(cfg.LatencyRatio * fpu.MaximumLatency); } else { fpu.Latency = cfg.Latency; } IXILMapping result = TryMapOne(fpu.TASite, instr, operandTypes, resultTypes, false); Debug.Assert(result != null); return result; }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { IXILMapping alt0, alt1 = null; alt0 = TryMapOne(taSite, instr, operandTypes, resultTypes, false); switch (instr.Name) { case InstructionCodes.Add: case InstructionCodes.Mul: case InstructionCodes.IsEq: case InstructionCodes.IsNEq: alt1 = TryMapOne(taSite, instr, new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; case InstructionCodes.IsGt: alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsLt(), new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; case InstructionCodes.IsGte: alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsLte(), new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; case InstructionCodes.IsLt: alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsGt(), new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; case InstructionCodes.IsLte: alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsGte(), new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; } if (alt0 != null) yield return alt0; if (alt1 != null) yield return alt1; }
public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap) { var fu = taSite.Host; FloatingPointCore fpu = (FloatingPointCore)fu; if (fpu == null) return null; if (operandTypes.Length != fpu.Arity) return null; if (fpu.Function == FloatingPointCore.EFunction.AddSubtract || fpu.Function == FloatingPointCore.EFunction.Compare || fpu.Function == FloatingPointCore.EFunction.Divide || fpu.Function == FloatingPointCore.EFunction.FloatToFixed || fpu.Function == FloatingPointCore.EFunction.FloatToFloat || fpu.Function == FloatingPointCore.EFunction.Multiply || fpu.Function == FloatingPointCore.EFunction.SquareRoot) { Type itype = null; switch (fpu.Precision) { case FloatingPointCore.EPrecision.Single: itype = typeof(float); break; case FloatingPointCore.EPrecision.Double: itype = typeof(double); break; default: return null; } foreach (TypeDescriptor otype in operandTypes) if (!otype.CILType.Equals(itype)) return null; } Func<ISignalSource<StdLogicVector>[], ISignalSink<StdLogicVector>[], IEnumerable<TAVerb>> realize = null; ISignalSource<StdLogicVector> defOp = SignalSource.Create(StdLogicVector._0s(fpu.OperandWidth)); ISignalSink<StdLogicVector> defR = SignalSink.Nil<StdLogicVector>(); switch (fpu.Function) { case FloatingPointCore.EFunction.AddSubtract: if (instr.Name.Equals(InstructionCodes.Add) && (fpu.AddSubSel == FloatingPointCore.EAddSub.Add || fpu.AddSubSel == FloatingPointCore.EAddSub.Both)) { realize = (os, rs) => fpu.TASite.Add(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.Sub) && (fpu.AddSubSel == FloatingPointCore.EAddSub.Subtract || fpu.AddSubSel == FloatingPointCore.EAddSub.Both)) { realize = (os, rs) => fpu.TASite.Sub(os[0], os[1], rs[0]); } else return null; break; case FloatingPointCore.EFunction.Compare: if (instr.Name.Equals(InstructionCodes.IsLt)) { realize = (os, rs) => fpu.TASite.IsLt(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsLte)) { realize = (os, rs) => fpu.TASite.IsLte(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsEq)) { realize = (os, rs) => fpu.TASite.IsEq(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsNEq)) { realize = (os, rs) => fpu.TASite.IsNEq(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsGte)) { realize = (os, rs) => fpu.TASite.IsGte(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsGt)) { realize = (os, rs) => fpu.TASite.IsGt(os[0], os[1], rs[0]); } else { return null; } break; case FloatingPointCore.EFunction.Divide: if (instr.Name.Equals(InstructionCodes.Div)) { realize = (os, rs) => fpu.TASite.Div(os[0], os[1], rs[0]); } else return null; break; case FloatingPointCore.EFunction.FixedToFloat: if (instr.Name.Equals(InstructionCodes.Convert)) { if (!operandTypes[0].CILType.Equals(typeof(SFix)) && !operandTypes[0].CILType.Equals(typeof(Signed))) return null; FixFormat ffmt = SFix.GetFormat(operandTypes[0]); if (ffmt.IntWidth != fpu.ExponentWidth || ffmt.FracWidth != fpu.FractionWidth) return null; switch (fpu.ResultPrecision) { case FloatingPointCore.EPrecision.Single: if (!resultTypes[0].CILType.Equals(typeof(float))) return null; break; case FloatingPointCore.EPrecision.Double: if (!resultTypes[0].CILType.Equals(typeof(double))) return null; break; default: return null; } realize = (os, rs) => fpu.TASite.Fix2Float(os[0], rs[0]); } else return null; break; case FloatingPointCore.EFunction.FloatToFixed: if (instr.Name.Equals(InstructionCodes.Convert)) { if (!resultTypes[0].CILType.Equals(typeof(SFix)) && !resultTypes[0].CILType.Equals(typeof(Signed))) return null; FixFormat ffmt = SFix.GetFormat(resultTypes[0]); if (ffmt.IntWidth != fpu.ResultExponentWidth || ffmt.FracWidth != fpu.ResultFractionWidth) return null; switch (fpu.Precision) { case FloatingPointCore.EPrecision.Single: if (!operandTypes[0].CILType.Equals(typeof(float))) return null; break; case FloatingPointCore.EPrecision.Double: if (!operandTypes[0].CILType.Equals(typeof(double))) return null; break; default: return null; } realize = (os, rs) => fpu.TASite.Float2Fix(os[0], rs[0]); } else return null; break; case FloatingPointCore.EFunction.FloatToFloat: if (instr.Name.Equals(InstructionCodes.Convert)) { switch (fpu.Precision) { case FloatingPointCore.EPrecision.Single: if (!operandTypes[0].CILType.Equals(typeof(float))) return null; break; case FloatingPointCore.EPrecision.Double: if (!operandTypes[0].CILType.Equals(typeof(double))) return null; break; default: return null; } switch (fpu.ResultPrecision) { case FloatingPointCore.EPrecision.Single: if (!resultTypes[0].CILType.Equals(typeof(float))) return null; break; case FloatingPointCore.EPrecision.Double: if (!resultTypes[0].CILType.Equals(typeof(double))) return null; break; default: return null; } realize = (os, rs) => fpu.TASite.Float2Float(os[0], rs[0]); } else return null; break; case FloatingPointCore.EFunction.Multiply: if (instr.Name.Equals(InstructionCodes.Mul)) { realize = (os, rs) => fpu.TASite.Mul(os[0], os[1], rs[0]); } else return null; break; case FloatingPointCore.EFunction.SquareRoot: if (instr.Name.Equals(InstructionCodes.Sqrt)) { realize = (os, rs) => fpu.TASite.Sqrt(os[0], rs[0]); } else return null; break; default: throw new NotImplementedException(); } return new XILMapping(fpu.TASite, realize, swap); }
public object Deserialize(StdLogicVector slv, TypeDescriptor targetType) { var fmt = UFix.GetFormat(targetType); return UFix.FromUnsigned(slv.UnsignedValue, fmt.FracWidth); }
/// <summary> /// Extracts the fixed-point format description from the SysDOM type descriptor, given that it represents /// <c>UFix</c> or <c>Unsigned</c>. /// </summary> public static FixFormat GetFormat(TypeDescriptor td) { if (!td.CILType.Equals(typeof(UFix)) && !td.CILType.Equals(typeof(Unsigned))) throw new InvalidOperationException(); if (!td.IsComplete) throw new InvalidOperationException(); Range range = td.Constraints[0]; return new FixFormat(false, range.FirstBound + 1, -range.SecondBound); }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; var v = instr.Operand as FieldRef; if (v == null) yield break; var taLV = taSite as InlineFieldMapperTransactionSite; if (taLV == null) yield break; if (!taLV.Literal.Equals(v)) yield break; switch (instr.Name) { case InstructionCodes.LoadVar: yield return new ReadXILMapping(taLV); break; case InstructionCodes.StoreVar: yield return new WriteXILMapping(taLV); break; default: yield break; } }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject) { var v = instr.Operand as FieldRef; if (v == null) return null; var taSite = new InlineFieldMapperTransactionSite(this, host, v); switch (instr.Name) { case InstructionCodes.LoadVar: return new ReadXILMapping(taSite); case InstructionCodes.StoreVar: return new WriteXILMapping(taSite); default: return null; } }
private static FunctionSpec MakeFun(IntrinsicFunction ifun, TypeDescriptor returnType) { Contract.Requires<ArgumentNullException>(ifun != null); Contract.Requires<ArgumentNullException>(returnType != null); return new FunctionSpec(returnType) { IntrinsicRep = ifun }; }
/// <summary> /// Constructs a local variable. /// </summary> /// <param name="type">type of data stored in the variable</param> public Variable(TypeDescriptor type) { _type = type; LocalIndex = -1; LocalSubIndex = -1; }
/// <summary> /// Constructs a <c>FunctionCall</c> representation of a type conversion. /// </summary> /// <param name="expr">expression representing the value to be converted</param> /// <param name="srcType">source type of conversion</param> /// <param name="dstType">destination type of conversion</param> /// <param name="reinterpret">whether the conversion has re-interpret semantics</param> public static Expression Cast(Expression expr, Type srcType, TypeDescriptor dstType, bool reinterpret = false) { if (expr != null && expr.ResultType.Equals(dstType)) return expr; return new FunctionCall() { Callee = MakeFun( new IntrinsicFunction(IntrinsicFunction.EAction.Convert, new CastParams(srcType, dstType, reinterpret)), dstType), Arguments = new Expression[] { expr }, ResultType = dstType, SetResultTypeClass = EResultTypeClass.ObjectReference }; }
private void PopulateIndexList(List<Expression[]> result, IndexSpec indexSpec, TypeDescriptor elemType) { int count = indexSpec.Indices.Length; var curSeq = indexSpec.Indices.Reverse(); while (curSeq.Any()) { var seq = curSeq.Take(elemType.Rank).Reverse(); result.Add(seq .Select(ds => ds.Kind == DimSpec.EKind.Index ? LiteralReference.CreateConstant((int)ds) : LiteralReference.CreateConstant((Range)ds)) .ToArray()); if (seq.Any(ds => ds.Kind == DimSpec.EKind.Range)) break; curSeq = curSeq.Skip(elemType.Rank); elemType = elemType.Element0Type; } }
/// <summary> /// Constructs a <c>FunctionCall</c> representation of a type conversion with parameters. /// </summary> /// <param name="exprs">expressions representing the value to be converted and additional conversion parameters</param> /// <param name="srcType">source type of conversion</param> /// <param name="dstType">destination type of conversion</param> /// <param name="reinterpret">whether the conversion has re-interpret semantics</param> public static FunctionCall Cast(Expression[] exprs, Type srcType, TypeDescriptor dstType, bool reinterpret = false) { return new FunctionCall() { Callee = MakeFun( new IntrinsicFunction(IntrinsicFunction.EAction.Convert, new CastParams(srcType, dstType, reinterpret)), dstType), Arguments = exprs, ResultType = dstType, SetResultTypeClass = EResultTypeClass.ObjectReference }; }
/// <summary> /// Creates a matching for type cast expressions. /// </summary> /// <param name="srcType">source type</param> /// <param name="dstType">destination type</param> public Matching Cast(Type srcType, TypeDescriptor dstType) { var cast = IntrinsicFunctions.Cast((Expression)null, srcType, dstType); Matching newm = new Matching(); newm._func = e => e.NodeEquals(cast) && this.Match(e.Children.ElementAt(0)); newm._gen = () => newm._expr == null ? IntrinsicFunctions.Cast(_gen(), srcType, dstType) : newm._expr; return newm; }
/// <summary> /// Constructs a <c>FunctionCall</c> representation of an integral number resizing operation. /// </summary> /// <param name="expr">expression representing the value to be resized</param> /// <param name="newWidth">new integer width</param> /// <param name="resultType">result type descriptor</param> public static FunctionCall Resize(Expression expr, int newWidth, TypeDescriptor resultType) { return new FunctionCall() { Callee = MakeFun( new IntrinsicFunction(IntrinsicFunction.EAction.Resize, new ResizeParams(newWidth)), resultType), Arguments = new Expression[] { expr }, ResultType = resultType, SetResultTypeClass = EResultTypeClass.ObjectReference }; }
private void InitTypeParams() { var mtit = CILType.GetCustomOrInjectedAttribute<MapToIntrinsicType>(); if (mtit != null) { HasIntrinsicTypeOverride = true; IntrinsicTypeOverride = mtit.IntrinsicType; } else if (CILType.GetCustomOrInjectedAttribute<CompilerGeneratedAttribute>() != null) { HasIntrinsicTypeOverride = true; IntrinsicTypeOverride = EIntrinsicTypes.IllegalRuntimeType; } else { HasIntrinsicTypeOverride = false; } if (CILType.IsArray) { int rank = CILType.GetArrayRank(); TypeParams = new object[rank]; if (_sample != null) { Array array = (Array)_sample; for (int i = 0; i < rank; i++) TypeParams[i] = array.GetLength(i); } } else { List<object> typeParams = new List<object>(); foreach (PropertyInfo pi in CILType.GetProperties( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { object[] tparams = pi.GetCustomAndInjectedAttributes(typeof(TypeParameter)); if (tparams.Length > 0) { object arg = _sample == null ? null : pi.GetGetMethod().Invoke(_sample, new object[0]); typeParams.Add(arg); } } TypeParams = typeParams.ToArray(); } if (IsComplete) { if (CILType.IsArray) { Range[] result = new Range[Rank]; for (int i = 0; i < result.Length; i++) { result[i] = new Range(0, (int)TypeParams[i] - 1, EDimDirection.To); } Constraints = result; } else { List<Range> result = new List<Range>(); foreach (PropertyInfo pi in CILType.GetProperties( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { object[] tparams = pi.GetCustomAndInjectedAttributes(typeof(TypeParameter)); if (tparams.Length > 0) { TypeParameter tparam = (TypeParameter)tparams[0]; MethodInfo miconv = tparam.RangeConverter.GetMethod("ConvertToRange", BindingFlags.Static | BindingFlags.Public); object arg = pi.GetGetMethod().Invoke(_sample, new object[0]); Range carg = (Range)miconv.Invoke(null, new object[] { arg }); result.Add(carg); } } Constraints = result.ToArray(); } } Element0Type = GetElement0Type(); }
/// <summary> /// Constructs a <c>FunctionCall</c> representation of a bit vector indexed read operation. /// </summary> /// <param name="subj">expression representing the vector to be indexed</param> /// <param name="index">expression representing the accessed index</param> /// <param name="resultType">result type descriptor</param> public static FunctionCall Index(Expression subj, Expression index, TypeDescriptor resultType) { return new FunctionCall() { Callee = MakeFun( new IntrinsicFunction(IntrinsicFunction.EAction.Index), resultType), Arguments = new Expression[] { subj, index }, ResultType = resultType }; }
/// <summary> /// Clones this type and clears the constraints of the first dimension. Only applicable to constrained array types. /// </summary> public TypeDescriptor MakeUnconstrainedType() { if (Rank == 0) throw new InvalidOperationException("This operation is only possible for types with Rank > 0"); if (IsUnconstrained) throw new InvalidOperationException("This type is already unconstrained"); TypeDescriptor tdu; if (_sample != null) tdu = new TypeDescriptor(_sample); else tdu = new TypeDescriptor(CILType); tdu.IsUnconstrained = true; return tdu; }
/// <summary> /// Constructs a <c>FunctionCall</c> representation of executing a XIL instruction. /// </summary> /// <param name="xi">XIL instruction to execute</param> /// <param name="resultType">result type descriptor</param> /// <param name="args">expressions representing the instruction arguments</param> public static FunctionCall XILOpCode(XILInstr xi, TypeDescriptor resultType, params Expression[] args) { return new FunctionCall() { Callee = MakeFun( new IntrinsicFunction(IntrinsicFunction.EAction.XILOpCode, xi), resultType), Arguments = args, ResultType = resultType }; }
private string CheckStatic() { if (HasIntrinsicTypeOverride) return null; if (CILType.IsArray) { TypeDescriptor tdref = GetElement0Type(); string innerCheck = tdref.CheckStatic(); if (innerCheck != null) return innerCheck; if (_sample == null) return "No sample - not able to determine whether type descriptor is static"; Array array = (Array)_sample; int[] indices = new int[array.Rank]; do { object elem = array.GetValue(indices); if (elem == null) return "Null array element"; TypeDescriptor td = new TypeDescriptor(elem); if (!tdref.Equals(td)) return "Different element types in array"; int dim; for (dim = 0; dim < indices.Length; dim++) { ++indices[dim]; if (indices[dim] < array.GetLength(dim)) break; indices[dim] = 0; } if (dim == indices.Length) break; } while (true); return null; } else { if (!CILType.IsValueType && !CILType.IsPrimitive) return "Type is neither primitive nor a value type"; TypeDescriptor[] deps = GetDependentTypes(); foreach (TypeDescriptor dep in deps) { string innerCheck = dep.CheckStatic(); if (innerCheck != null) return innerCheck; } return null; } }
/// <summary> /// Constructs a <c>FunctionCall</c> representation of reading a tuple item. /// </summary> /// <param name="index">0-based index of accessed tuple element</param> /// <param name="resultType">result type descriptor</param> /// <param name="tup">expression representing the accessed tuple</param> public static FunctionCall TupleSelect(int index, TypeDescriptor resultType, Expression tup) { return new FunctionCall() { Callee = MakeFun( new IntrinsicFunction(IntrinsicFunction.EAction.TupleSelect, index), resultType), Arguments = new Expression[] { tup }, ResultType = resultType }; }