private InstructionDependency[] Convert(InstructionDependency[] preds, TypeDescriptor from, TypeDescriptor to) { if (from.Equals(to)) { // nothing to do return preds; } else if (IsSFix(from) && IsUFix(to)) { var fromFmt = SFix.GetFormat(from); var toFmt = UFix.GetFormat(to); int interIW = toFmt.IntWidth + 1; int interFW = toFmt.FracWidth; if (interIW != fromFmt.IntWidth || interFW != fromFmt.FracWidth) { var interType = SFix.MakeType(interIW, interFW); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType)); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, interType, to)); } else { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); } return new InstructionDependency[0]; } else if (IsUFix(from) && IsSFix(to)) { var fromFmt = UFix.GetFormat(from); var toFmt = SFix.GetFormat(to); int interIW = toFmt.IntWidth - 1; int interFW = toFmt.FracWidth; if (interIW != fromFmt.IntWidth || interFW != fromFmt.FracWidth) { var interType = UFix.MakeType(interIW, interFW); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType)); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, interType, to)); } else { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); } return new InstructionDependency[0]; } else if (IsSLV(from)) { int wfrom = TypeLowering.Instance.GetWireWidth(from); int wto = TypeLowering.Instance.GetWireWidth(to); if (wfrom == wto) { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); } else { var interType = StdLogicVector.MakeType(wto); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType)); Convert(interType, to); } return new InstructionDependency[0]; } else if (IsSLV(to)) { int wfrom = TypeLowering.Instance.GetWireWidth(from); int wto = TypeLowering.Instance.GetWireWidth(to); if (wfrom == wto) { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); } else { var interType = StdLogicVector.MakeType(wfrom); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, interType)); Convert(interType, to); } return new InstructionDependency[0]; } else { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, 1, from, to)); return new InstructionDependency[0]; } }
/// <summary> /// Returns a type which is able to represent either of two given types without loss of precision /// </summary> /// <param name="td1">first given type</param> /// <param name="td2">second given type</param> /// <returns></returns> private static TypeDescriptor GetCommonType(TypeDescriptor td1, TypeDescriptor td2) { if (td1.Equals(td2)) return td1; if (IsSFix(td1) && IsUFix(td2)) { var fmt1 = SFix.GetFormat(td1); var fmt2 = UFix.GetFormat(td2); return SFix.MakeType( Math.Max(fmt1.IntWidth, fmt2.IntWidth + 1), Math.Max(fmt1.FracWidth, fmt2.FracWidth)); } else if (IsUFix(td1) && IsSFix(td2)) { return GetCommonType(td2, td1); } else if (IsSFix(td1) && IsSFix(td2)) { var fmt1 = SFix.GetFormat(td1); var fmt2 = SFix.GetFormat(td2); return SFix.MakeType( Math.Max(fmt1.IntWidth, fmt2.IntWidth), Math.Max(fmt1.FracWidth, fmt2.FracWidth)); } else if (IsUFix(td1) && IsUFix(td2)) { var fmt1 = UFix.GetFormat(td1); var fmt2 = UFix.GetFormat(td2); return UFix.MakeType( Math.Max(fmt1.IntWidth, fmt2.IntWidth), Math.Max(fmt1.FracWidth, fmt2.FracWidth)); } else if (IsSigned(td1)) { var fmt = SFix.GetFormat(td1); var td1x = SFix.MakeType(fmt.IntWidth, fmt.FracWidth); return GetCommonType(td1x, td2); } else if (IsSigned(td2)) { return GetCommonType(td2, td1); } else if (IsUnsigned(td1)) { var fmt = UFix.GetFormat(td1); var td1x = UFix.MakeType(fmt.IntWidth, fmt.FracWidth); return GetCommonType(td1x, td2); } else if (IsUnsigned(td2)) { return GetCommonType(td2, td1); } else { throw new NotSupportedException( "Cannot determine common type between " + td1.ToString() + " and " + td2.ToString()); } }
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); } }