Example #1
0
        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));
            }
        }
Example #2
0
 /// <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);
 }
Example #3
0
        /// <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);
        }
Example #4
0
 /// <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;
 }
Example #5
0
 /// <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;
 }
Example #6
0
        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);
            }
        }
Example #7
0
        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 !);
            }
        }