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());
            }
        }
示例#3
0
        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);
            }
        }