public Instruction CreateLongInstruction(AddSubCandidate loCandidate, AddSubCandidate hiCandidate) { var totalSize = PrimitiveType.Create( Domain.SignedInt | Domain.UnsignedInt, loCandidate.Dst.DataType.BitSize + loCandidate.Dst.DataType.BitSize); var left = CreateCandidate(loCandidate.Left, hiCandidate.Left, totalSize); var right = CreateCandidate(loCandidate.Right, hiCandidate.Right, totalSize); this.dst = CreateCandidate(loCandidate.Dst, hiCandidate.Dst, totalSize); if (left == null || right == null || dst == null) { return(null); } var expSum = new BinaryExpression(loCandidate.Op, left.DataType, left, right); if (dst is Identifier idDst) { return(new Assignment(idDst, expSum)); } else { return(new Store(dst, expSum)); } }
/// <summary> /// Determines if the carry flag reaches a using instruction. /// </summary> /// <param name="instrs"></param> /// <param name="i"></param> /// <param name="next"></param> /// <returns></returns> public AddSubCandidate FindUsingInstruction(StatementList stms, int i, AddSubCandidate loInstr) { for (++i; i < stms.Count; ++i) { var asc = MatchAdcSbc(stms[i].Instruction); if (asc != null) { //Debug.Print("Left sides: [{0}] [{1}]", asc.Left, loInstr.Left); if (asc.Left.GetType() != loInstr.Left.GetType()) { return(null); } asc.StatementIndex = i; return(asc); } if (!(stms[i].Instruction is Assignment ass)) { continue; } if (IsCarryFlag(ass.Dst)) { return(null); } } return(null); }
/// <summary> /// Determines if the carry flag reaches a using instruction. /// </summary> /// <param name="instrs"></param> /// <param name="i"></param> /// <param name="next"></param> /// <returns></returns> public AddSubCandidate?FindUsingInstruction(Identifier cy, AddSubCandidate loInstr) { var queue = new Queue <Statement>(ssa.Identifiers[cy].Uses); while (queue.Count > 0) { var use = queue.Dequeue(); var asc = MatchAdcSbc(use); if (asc != null) { //Debug.Print("Left sides: [{0}] [{1}]", asc.Left, loInstr.Left); if (asc.Left.GetType() != loInstr.Left.GetType()) { return(null); } asc.Statement = use; return(asc); } if (!(use.Instruction is Assignment ass)) { continue; } if (ass.Src is Slice) { queue.EnqueueRange(ssa.Identifiers[ass.Dst].Uses); continue; } if (IsCarryFlag(ass.Dst)) { return(null); } } return(null); }
/// <summary> /// Find a statement index appropriate for insert the new /// long addition statements. /// </summary> /// <returns></returns> private int FindInsertPosition(AddSubCandidate loCandidate, AddSubCandidate hiCandidate, StatementList stmts) { int iStm = stmts.IndexOf(hiCandidate.Statement!); if (loCandidate.Dst is Identifier idLow) { int iFirstLowUsage = ssa.Identifiers[idLow].Uses .Select(u => stmts.IndexOf(u)) .Where(i => i >= 0) .Min(); iStm = Math.Min(iStm, iFirstLowUsage); } return iStm; }
/// <summary> /// Determines if the carry flag reaches a using instruction. /// </summary> /// <param name="instrs"></param> /// <param name="i"></param> /// <param name="next"></param> /// <returns></returns> public AddSubCandidate FindUsingInstruction(StatementList stms, int i, AddSubCandidate loInstr) { for (++i; i < stms.Count; ++i) { var asc = MatchAdcSbc(stms[i].Instruction); if (asc != null) { Debug.Print("Left sides: [{0}] [{1}]", asc.Left, loInstr.Left); if (asc.Left.GetType() != loInstr.Left.GetType()) return null; asc.StatementIndex = i; return asc; } var ass = stms[i].Instruction as Assignment; if (ass == null) continue; var bin = ass.Src as BinaryExpression; if (bin == null) continue; if (IsCarryFlag(ass.Dst)) return null; } return null; }
public Instruction CreateLongInstruction(AddSubCandidate loCandidate, AddSubCandidate hiCandidate) { var totalSize = PrimitiveType.Create( Domain.SignedInt | Domain.UnsignedInt, loCandidate.Dst.DataType.Size + loCandidate.Dst.DataType.Size); var left = CreateCandidate(loCandidate.Left, hiCandidate.Left, totalSize); var right = CreateCandidate(loCandidate.Right, hiCandidate.Right, totalSize); this.dst = CreateCandidate(loCandidate.Dst, hiCandidate.Dst, totalSize); if (left == null || right == null || dst == null) return null; var expSum = new BinaryExpression(loCandidate.Op, left.DataType, left, right); var idDst = dst as Identifier; if (idDst != null) { return new Assignment(idDst, expSum); } else { return new Store(dst, expSum); } }
public void CreateLongInstruction(AddSubCandidate loCandidate, AddSubCandidate hiCandidate) { var totalSize = PrimitiveType.Create( Domain.SignedInt | Domain.UnsignedInt, loCandidate.Dst !.DataType.BitSize + hiCandidate.Dst !.DataType.BitSize); var left = CreateCandidate(loCandidate.Left, hiCandidate.Left, totalSize); var right = CreateCandidate(loCandidate.Right, hiCandidate.Right, totalSize); this.dst = CreateCandidate(loCandidate.Dst, hiCandidate.Dst, totalSize); var stmts = hiCandidate.Statement !.Block.Statements; var linAddr = hiCandidate.Statement.LinearAddress; var iStm = FindInsertPosition(loCandidate, hiCandidate, stmts); Statement?stmMkLeft = null; if (left is Identifier) { stmMkLeft = stmts.Insert( iStm++, linAddr, CreateMkSeq(left, hiCandidate.Left, loCandidate.Left)); left = ReplaceDstWithSsaIdentifier(left, null !, stmMkLeft); } Statement?stmMkRight = null; if (right is Identifier) { stmMkRight = stmts.Insert( iStm++, linAddr, CreateMkSeq(right, hiCandidate.Right, loCandidate.Right)); right = ReplaceDstWithSsaIdentifier(right, null !, stmMkRight); } var expSum = new BinaryExpression(loCandidate.Op, left.DataType, left, right); Instruction instr = Assign(dst, expSum); var stmLong = stmts.Insert(iStm++, linAddr, instr); this.dst = ReplaceDstWithSsaIdentifier(this.dst, expSum, stmLong); var sidDst = GetSsaIdentifierOf(dst); var sidLeft = GetSsaIdentifierOf(left); var sidRight = GetSsaIdentifierOf(right); if (stmMkLeft != null && sidLeft != null) { GetSsaIdentifierOf(loCandidate.Left)?.Uses.Add(stmMkLeft); GetSsaIdentifierOf(hiCandidate.Left)?.Uses.Add(stmMkLeft); } if (stmMkRight != null && sidRight != null) { GetSsaIdentifierOf(loCandidate.Right)?.Uses.Add(stmMkRight); GetSsaIdentifierOf(hiCandidate.Right)?.Uses.Add(stmMkRight); } if (sidDst != null) { if (sidLeft != null) { sidLeft.Uses.Add(stmLong); } if (sidRight != null) { sidRight.Uses.Add(stmLong); } } var sidDstLo = GetSsaIdentifierOf(loCandidate.Dst); if (sidDstLo != null) { var cast = new Slice(loCandidate.Dst.DataType, dst, 0); var stmCastLo = stmts.Insert(iStm++, linAddr, new AliasAssignment( sidDstLo.Identifier, cast)); var stmDeadLo = sidDstLo.DefStatement; sidDstLo.DefExpression = cast; sidDstLo.DefStatement = stmCastLo; var sidDstHi = GetSsaIdentifierOf(hiCandidate.Dst); var slice = new Slice(hiCandidate.Dst.DataType, dst, loCandidate.Dst.DataType.BitSize); var stmSliceHi = stmts.Insert(iStm++, linAddr, new AliasAssignment( sidDstHi !.Identifier, slice)); var stmDeadHi = sidDstHi.DefStatement; sidDstHi.DefExpression = slice; sidDstHi.DefStatement = stmSliceHi; if (sidDstLo != null) { sidDst !.Uses.Add(stmCastLo); } if (sidDstHi != null) { sidDst !.Uses.Add(stmSliceHi); } ssa.DeleteStatement(stmDeadLo !); ssa.DeleteStatement(stmDeadHi !); } }