コード例 #1
0
ファイル: ValueSet.cs プロジェクト: zan00789/reko
        /// <summary>
        /// Returns a valueset whose values are the truncation of this valueset's
        /// values.
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public override ValueSet Truncate(DataType dt)
        {
            if (SI.Stride < 0)
            {
                return(this);
            }

            var             mask = (1 << dt.BitSize) - 1;
            StridedInterval siNew;

            if (SI.Low == SI.High)
            {
                siNew = StridedInterval.Constant(
                    Constant.Create(dt, SI.Low & mask));
            }
            else
            {
                siNew = StridedInterval.Create(
                    SI.Stride, 0, Math.Min(mask, SI.High));
            }
            return(new IntervalValueSet(dt, siNew));
        }
コード例 #2
0
        public ValueSet VisitBinaryExpression(BinaryExpression binExp)
        {
            var cLeft  = binExp.Left as Constant;
            var cRight = binExp.Right as Constant;

            //$TODO: it would be great if Address were simply a Constant.
            // but we have segmented addresses which need special treatment
            // everywhere.
            if (binExp.Left is Address aLeft)
            {
                cLeft = aLeft.ToConstant();
            }
            if (binExp.Right is Address aRight)
            {
                cRight = aRight.ToConstant();
            }

            if (cLeft != null && cRight != null)
            {
                return(new IntervalValueSet(
                           cLeft.DataType,
                           StridedInterval.Constant(
                               binExp.Operator.ApplyConstants(cLeft, cRight))));
            }

            if (cLeft == null && cRight != null)
            {
                var left = binExp.Left.Accept(this);
                if (binExp.Operator == Operator.IAdd)
                {
                    return(left.Add(cRight));
                }
                else if (binExp.Operator == Operator.And)
                {
                    return(left.And(cRight));
                }
                else if (binExp.Operator == Operator.Shl)
                {
                    return(left.Shl(cRight));
                }
                else if (binExp.Operator == Operator.IMul)
                {
                    return(left.IMul(cRight));
                }
                else if (binExp.Operator == Operator.ISub)
                {
                    return(left.Sub(cRight));
                }
            }
            if (cRight == null && cLeft != null)
            {
                var right = binExp.Right.Accept(this);
                if (binExp.Operator == Operator.IAdd)
                {
                    return(right.Add(cLeft));
                }
                else if (binExp.Operator == Operator.And)
                {
                    return(right.And(cLeft));
                }
            }
            if (binExp.Operator == Operator.IAdd)
            {
                if (cmp.Equals(binExp.Left, binExp.Right))
                {
                    var left = binExp.Left.Accept(this);
                    return(left.Shl(Constant.Int32(1)));
                }
            }
            return(IntervalValueSet.Any);
        }