/// <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)); }
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); }