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