/// <summary> /// Determine whether <paramref name="instr"/> is a match for /// the pattern that is a constant division /// </summary> /// <remarks> /// The pattern is: /// <code> /// hi:lo = r * const /// hi = slice(hi:lo) (alias) /// hi = hi >> shift (optional) /// </code> /// This transformation must be carried out before value propagation /// pushes the shift inside other operations. /// </remarks> /// <param name="instr"></param> /// <returns></returns> public bool Match(Instruction instr) { Assignment ass; SequenceStorage dst; BinaryExpression bin; Constant cRight; // Look for hi:lo = a * C if (!instr.As(out ass) || !ass.Dst.Storage.As(out dst) || !ass.Src.As(out bin) || !(bin.Operator is IMulOperator) || !bin.Right.As(out cRight) || ass.Dst.DataType.Size <= bin.Left.DataType.Size) { return(false); } this.idOrig = ass.Dst; this.idDst = FindAlias(ass.Dst, dst.Head); if (idDst == null) { return(false); } var best = FindBestRational(cRight.ToUInt32()); // There may be a subsequent SAR / SHR to increase // the divisor. var idSlice = idDst; Constant rShift = null; if (idSlice != null) { rShift = FindShiftUse(idSlice); if (rShift != null) { best = best / (1 << rShift.ToInt32()); } } this.bestRational = best; this.dividend = bin.Left; return(true); }
/// <summary> /// Determine whether <paramref name="instr"/> is a match for /// the pattern that is a constant division /// </summary> /// <remarks> /// The pattern is: /// <code> /// hi:lo = r * const /// hi = slice(hi:lo) (alias) /// hi = hi >> shift (optional) /// </code> /// This transformation must be carried out before value propagation /// pushes the shift inside other operations. /// </remarks> /// <param name="instr"></param> /// <returns></returns> public bool Match(Instruction instr) { Assignment ass; SequenceStorage dst; BinaryExpression bin; Constant cRight; // Look for hi:lo = a * C if (!instr.As(out ass) || !ass.Dst.Storage.As(out dst) || !ass.Src.As(out bin) || !(bin.Operator is IMulOperator) || !bin.Right.As(out cRight) || ass.Dst.DataType.Size <= bin.Left.DataType.Size) { return false; } this.idOrig = ass.Dst; this.idDst = FindAlias(ass.Dst, dst.Head); if (idDst == null) return false; var best = FindBestRational(cRight.ToUInt32()); // There may be a subsequent SAR / SHR to increase // the divisor. var idSlice = idDst; Constant rShift = null; if (idSlice != null) { rShift = FindShiftUse(idSlice); if (rShift != null) { best = best / (1 << rShift.ToInt32()); } } this.bestRational = best; this.dividend = bin.Left; return true; }