private Expression?ShiftRightShiftLeft(BinaryExpression bin) { if (bin.Operator != Operator.Shl || !(bin.Right is Constant cRight)) { return(null); } if (bin.Left is Identifier idLeft) { var innerExp = ctx.GetDefiningExpression(idLeft); if (innerExp is null) { return(null); } if (innerExp is BinaryExpression binInner && (binInner.Operator == Operator.Shr || binInner.Operator == Operator.Sar) && cmp.Equals(cRight, binInner.Right)) { ctx.RemoveExpressionUse(idLeft); ctx.UseExpression(binInner.Left); var sig = FunctionType.Func( new Identifier("", bin.DataType, null !), new Identifier("x", binInner.Left.DataType, null !), new Identifier("y", PrimitiveType.Int32, null !)); var align = new IntrinsicProcedure(IntrinsicProcedure.Align, true, sig); return(m.Fn(align, binInner.Left, Constant.Int32(1 << cRight.ToInt32()))); } } return(null); }
public bool Match(MkSequence seq) { if (seq.Expressions.Length != 2) { return(false); //$TODO: handle sequences of any length? } this.idHi = seq.Expressions[0] as Identifier; this.idLo = seq.Expressions[1] as Identifier; if (idHi == null || idLo == null) { return(false); } var defHi = ctx.GetDefiningExpression(idHi) as Slice; var defLo = ctx.GetDefiningExpression(idLo) as Slice; if (defHi == null || defLo == null) { return(false); } if (defHi.Expression != defLo.Expression) { return(false); } this.idOrig = defHi.Expression as Identifier; return(idOrig != null); }
public bool Match(DepositBits dpb) { this.dpbUse = dpb; if (!dpb.Source.As(out idDef)) { return(false); } var expDef = ctx.GetDefiningExpression(idDef); if (expDef == null) { return(false); } if (!expDef.As(out dpbDef)) { return(false); } if (!dpbDef.Source.As(out idSrc)) { return(false); } return (dpbDef.BitCount == dpbUse.BitCount && dpbDef.BitPosition == dpbUse.BitPosition); }
public bool Match(DepositBits dpb) { this.dpbUse = dpb; if (!(dpb.Source is Identifier idDef)) { return(false); } var expDef = ctx.GetDefiningExpression(idDef); if (expDef == null) { return(false); } if (!(expDef is DepositBits dpbDef)) { return(false); } if (!(dpbDef.Source is Identifier idSrc)) { return(false); } this.idDef = idDef; this.dpbDef = dpbDef; this.idSrc = idSrc; return(dpbDef.BitPosition == dpbUse.BitPosition); }
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); }
/// <summary> /// Try to find an original 32-bit segmented pointer that may have /// been SLICE'd to a segment and offset register. /// </summary> /// <param name="seg"></param> /// <param name="off"></param> /// <returns></returns> private Identifier?SlicedSegPointer(Identifier seg, Identifier off) { var defSeg = ctx.GetDefiningExpression(seg) as Slice; var defOff = ctx.GetDefiningExpression(off) as Slice; if (defSeg == null || defOff == null) { return(null); } if (defSeg.Expression == defOff.Expression) { return(defSeg.Expression as Identifier); } else { return(null); } }
public bool Match(Expression ea) { //$REFACTOR: this is mutable shared state. Rewrite this to // use the (Expression newExpr, bool changed) pattern used // elsewhere in ExpressionSimplifier. this.binEaLeft = null; this.binEaRight = null; this.idEa = null; if (ea is BinaryExpression bin) { if (bin.Operator == Operator.IAdd || bin.Operator == Operator.ISub) { if (bin.Left is Identifier idLeft) { this.defIndex = ctx.GetDefiningExpression(idLeft); if (IsScaled(defIndex)) { this.binEaLeft = bin; return(true); } } if (bin.Right is Identifier idRight) { this.defIndex = ctx.GetDefiningExpression(idRight); if (IsScaled(defIndex)) { this.binEaRight = bin; return(true); } } } } else if (ea is Identifier id) { this.defIndex = ctx.GetDefiningExpression(id); if (IsScaled(defIndex)) { idEa = id; return(true); } } return(false); }
private bool IsSequence(Expression e, out MkSequence sequence) { if (e is Identifier id) { sequence = ctx.GetDefiningExpression(id) as MkSequence; } else { sequence = e as MkSequence; } return(sequence != null); }
public bool Match(Expression ea) { if (ea is BinaryExpression bin) { if (bin.Operator == Operator.IAdd || bin.Operator == Operator.ISub) { if (bin.Left is Identifier idLeft) { this.defIndex = ctx.GetDefiningExpression(idLeft); if (IsScaled(defIndex)) { this.binEaLeft = bin; return(true); } } if (bin.Right is Identifier idRight) { this.defIndex = ctx.GetDefiningExpression(idRight); if (IsScaled(defIndex)) { this.binEaRight = bin; return(true); } } } } else if (ea is Identifier id) { this.defIndex = ctx.GetDefiningExpression(id); if (IsScaled(defIndex)) { idEa = id; return(true); } } return(false); }
private bool IsSequence(Expression e, out MkSequence sequence) { MkSequence?s; if (e is Identifier id) { s = ctx.GetDefiningExpression(id) as MkSequence; } else { s = e as MkSequence; } sequence = s !; return(s != null); }
public virtual Expression VisitCast(Cast cast) { var exp = cast.Expression.Accept(this); if (exp == Constant.Invalid) { return(exp); } Constant c = exp as Constant; if (c != null) { PrimitiveType p = c.DataType as PrimitiveType; if (p != null && (p.Domain & Domain.Integer) != 0) { //$REVIEW: this is fixed to 32 bits; need a general solution to it. Changed = true; return(Constant.Create(cast.DataType, 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); } } } return(new Cast(cast.DataType, exp)); }
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 != Constant.Invalid) { 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); }
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); }