Beispiel #1
0
 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;
 }
Beispiel #7
0
        /// <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;
        }
Beispiel #8
0
 /// <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);
        }
Beispiel #14
0
 public object Deserialize(StdLogicVector slv, TypeDescriptor targetType)
 {
     var fmt = UFix.GetFormat(targetType);
     return UFix.FromUnsigned(slv.UnsignedValue, fmt.FracWidth);
 }
Beispiel #15
0
 /// <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
     };
 }
Beispiel #19
0
 /// <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
            };
        }
Beispiel #21
0
 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
     };
 }