public virtual Expression VisitCast(Cast cast) { var exp = cast.Expression.Accept(this); if (exp != Constant.Invalid) { var ptCast = cast.DataType.ResolveAs <PrimitiveType>(); Constant c = exp as Constant; if (c != null && ptCast != null) { PrimitiveType ptSrc = c.DataType as PrimitiveType; if (ptSrc != null) { if (ptCast.Domain == Domain.Real) { if (ptSrc.Domain == Domain.Real && ptCast.Size < ptSrc.Size) { Changed = true; return(ConstantReal.Create(ptCast, c.ToReal64())); } } else if ((ptSrc.Domain & Domain.Integer) != 0) { Changed = true; return(Constant.Create(ptCast, c.ToUInt64())); } } } Identifier id; DepositBits dpb; if (exp.As(out id) && ctx.GetDefiningExpression(id).As(out dpb) && dpb.BitPosition == 0) { // If we are casting the result of a DPB, and the deposited part is >= // the size of the cast, then use deposited part directly. int sizeDiff = dpb.InsertedBits.DataType.Size - cast.DataType.Size; if (sizeDiff >= 0) { ctx.RemoveIdentifierUse(id); ctx.UseExpression(dpb.InsertedBits); Changed = true; if (sizeDiff > 0) { return(new Cast(cast.DataType, dpb.InsertedBits)); } else { return(dpb.InsertedBits); } } } cast = new Cast(cast.DataType, exp); } if (castCastRule.Match(cast)) { Changed = true; return(castCastRule.Transform()); } return(cast); }
protected Constant BuildConstant(DataType t1, DataType t2, double val) { PrimitiveType p1 = (PrimitiveType)t1; PrimitiveType p2 = (PrimitiveType)t2; int size = Math.Max(p1.Size, p2.Size); return(ConstantReal.Create(PrimitiveType.Create(p1.Domain & p2.Domain, size), val)); }
protected Constant BuildConstant(DataType t1, DataType t2, double val) { PrimitiveType p1 = t1.ResolveAs <PrimitiveType>() !; PrimitiveType p2 = t2.ResolveAs <PrimitiveType>() !; int bitSize = Math.Max(p1.BitSize, p2.BitSize); return(ConstantReal.Create(PrimitiveType.Create(p1.Domain & p2.Domain, bitSize), val)); }
public override Constant ReinterpretAsFloat(Constant rawBits) { if (rawBits.DataType.BitSize == 32) { var n = ConstantReal.Create(rawBits.DataType, Real32ToIEEE(rawBits.ToUInt32())); return(n); } else if (rawBits.DataType.BitSize == 48) { var n = ConstantReal.Create(rawBits.DataType, Real48ToIEEE(rawBits.ToUInt64())); return(n); } throw new NotSupportedException($"Floating point bit size {rawBits.DataType.BitSize} is not supported."); }
/// <summary> /// Take a bitvector of type wordXXX and reinterpret it as a floating-point /// constant. /// </summary> /// <param name="ptCast">Floating-point type to which the raw bits are being cast.</param> /// <param name="rawBits">The raw bits being cast.</param> /// <returns>A floating-point constant, possibly with a <see cref="Cast"/> wrapped around it /// if the constant is not 32- or 64-bit. /// </returns> private Expression CastRawBitsToReal(PrimitiveType ptCast, Constant rawBits) { var bitSize = Math.Min(rawBits.DataType.BitSize, 64); var dtImm = PrimitiveType.Create(Domain.Real, bitSize); var cImm = Constant.RealFromBitpattern(dtImm, rawBits.ToInt64()); cImm = ConstantReal.Create(dtImm, cImm.ToReal64()); if (cImm.DataType.BitSize == ptCast.BitSize) { return(cImm); } else { return(new Conversion(cImm, cImm.DataType, ptCast)); } }
public virtual Expression VisitCast(Cast cast) { var exp = cast.Expression.Accept(this); if (exp != Constant.Invalid) { var ptCast = cast.DataType.ResolveAs <PrimitiveType>(); if (exp is Constant c && ptCast != null) { if (c.DataType is PrimitiveType ptSrc) { if (ptCast.Domain == Domain.Real) { if (ptSrc.Domain == Domain.Real && ptCast.Size < ptSrc.Size) { Changed = true; return(ConstantReal.Create(ptCast, c.ToReal64())); } } else if ((ptSrc.Domain & Domain.Integer) != 0) { Changed = true; return(Constant.Create(ptCast, c.ToUInt64())); } } } if (exp is Identifier id && ctx.GetDefiningExpression(id) is DepositBits dpb && dpb.BitPosition == 0) { // If we are casting the result of a DPB, and the deposited part is >= // the size of the cast, then use deposited part directly. int sizeDiff = dpb.InsertedBits.DataType.Size - cast.DataType.Size; if (sizeDiff >= 0) { ctx.RemoveIdentifierUse(id); ctx.UseExpression(dpb.InsertedBits); Changed = true; if (sizeDiff > 0) { return(new Cast(cast.DataType, dpb.InsertedBits)); } else { return(dpb.InsertedBits); } } } if (exp is ProcedureConstant pc && cast.DataType.BitSize == pc.DataType.BitSize) { // (wordnn) procedure_const => procedure_const return(pc); } if (exp.DataType.BitSize == cast.DataType.BitSize) { // Redundant word-casts can be stripped. var wordType = PrimitiveType.CreateWord(exp.DataType.BitSize); if (wordType == cast.DataType) { return(exp); } } cast = new Cast(cast.DataType, exp); } if (castCastRule.Match(cast)) { Changed = true; return(castCastRule.Transform()); } return(cast); }
public virtual Expression VisitConversion(Conversion conversion) { var exp = conversion.Expression.Accept(this); if (!(exp is InvalidConstant)) { var ptCvt = conversion.DataType.ResolveAs <PrimitiveType>(); var ptSrc = conversion.SourceDataType.ResolveAs <PrimitiveType>(); if (exp is Constant c && ptCvt != null) { if (ptSrc != null) { if (ptCvt.Domain == Domain.Real) { if (ptSrc.Domain == Domain.Real) { if (ptCvt.Size < ptSrc.Size) { // Real-to-real conversion. Changed = true; return(ConstantReal.Create(ptCvt, c.ToReal64())); } } else if (ptSrc.IsWord) { // Raw bit pattern reinterpretation. Changed = true; return(CastRawBitsToReal(ptCvt, c)); } else { // integer to real conversion Changed = true; return(ConstantReal.Create(ptCvt, c.ToInt64())); } } else if ((ptSrc.Domain & Domain.Integer) != 0) { if (ptSrc != null) { if (ptSrc.Domain == Domain.SignedInt) { Changed = true; return(Constant.Create(ptCvt, c.ToInt64())); } else if (ptSrc.Domain.HasFlag(Domain.SignedInt)) { Changed = true; return(Constant.Create(ptCvt, c.ToUInt64())); } } } } } if (exp is Identifier id && ctx.GetDefiningExpression(id) is MkSequence seq) { // If we are casting a SEQ, and the corresponding element is >= // the size of the cast, then use deposited part directly. var lsbElem = seq.Expressions[seq.Expressions.Length - 1]; int sizeDiff = lsbElem.DataType.Size - conversion.DataType.Size; if (sizeDiff >= 0) { foreach (var elem in seq.Expressions) { ctx.RemoveExpressionUse(elem); } ctx.UseExpression(lsbElem); Changed = true; if (sizeDiff > 0) { return(new Conversion(lsbElem, lsbElem.DataType, conversion.DataType)); } else { return(lsbElem); } } } if (exp is ProcedureConstant pc && conversion.DataType.BitSize == pc.DataType.BitSize) { // (wordnn) procedure_const => procedure_const return(pc); } if (exp.DataType.BitSize == conversion.DataType.BitSize) { // Redundant word-casts can be stripped. if (conversion.DataType.IsWord) { return(exp); } } conversion = new Conversion(exp, exp.DataType, conversion.DataType); } if (convertConvertRule.Match(conversion)) { Changed = true; return(convertConvertRule.Transform()); } return(conversion); }
private Expression FCmp0(Expression val) { return(m.FSub(val, ConstantReal.Create(val.DataType, 0.0))); }
public virtual Expression VisitCast(Cast cast) { var exp = cast.Expression.Accept(this); if (exp != Constant.Invalid) { var ptCast = cast.DataType.ResolveAs <PrimitiveType>(); if (exp is Constant c && ptCast != null) { if (c.DataType is PrimitiveType ptSrc) { if (ptCast.Domain == Domain.Real) { if (ptSrc.Domain == Domain.Real && ptCast.Size < ptSrc.Size) { Changed = true; return(ConstantReal.Create(ptCast, c.ToReal64())); } } else if ((ptSrc.Domain & Domain.Integer) != 0) { Changed = true; return(Constant.Create(ptCast, c.ToUInt64())); } } } if (exp is Identifier id && ctx.GetDefiningExpression(id) is MkSequence seq) { // If we are casting a SEQ, and the corresponding element is >= // the size of the cast, then use deposited part directly. var lsbElem = seq.Expressions[seq.Expressions.Length - 1]; int sizeDiff = lsbElem.DataType.Size - cast.DataType.Size; if (sizeDiff >= 0) { foreach (var elem in seq.Expressions) { ctx.RemoveExpressionUse(elem); } ctx.UseExpression(lsbElem); Changed = true; if (sizeDiff > 0) { return(new Cast(cast.DataType, lsbElem)); } else { return(lsbElem); } } } if (exp is ProcedureConstant pc && cast.DataType.BitSize == pc.DataType.BitSize) { // (wordnn) procedure_const => procedure_const return(pc); } if (exp.DataType.BitSize == cast.DataType.BitSize) { // Redundant word-casts can be stripped. if (cast.DataType.IsWord()) { return(exp); } } cast = new Cast(cast.DataType, exp); } if (castCastRule.Match(cast)) { Changed = true; return(castCastRule.Transform()); } return(cast); }