예제 #1
0
        /// <summary>
        /// Branches need to terminate the current basic block and make links
        /// to the 'true' and 'false' destinations.
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public bool VisitBranch(RtlBranch b)
        {
            // We don't know the 'then' block yet, as the following statements may chop up the block
            // we're presently in. Back-patch in when the block target is obtained.
            var branch = new Branch(b.Condition, new Block(blockCur.Procedure, "TMP!"));

            Emit(branch);

            // The following statements may chop up the blockCur, so hang on to the essentials.
            var proc            = blockCur.Procedure;
            var fallthruAddress = ric.Address + ric.Length;

            var blockThen = BlockFromAddress(ric.Address, b.Target, proc, state.Clone());

            var blockElse      = FallthroughBlock(ric.Address, proc, fallthruAddress);
            var branchingBlock = scanner.FindContainingBlock(ric.Address);

            branch.Target = blockThen;      // The back-patch referred to above.
            EnsureEdge(proc, branchingBlock, blockElse);
            EnsureEdge(proc, branchingBlock, blockThen);

            // Now, switch to the fallthru block and keep rewriting.
            blockCur = blockElse;
            return(true);
        }
예제 #2
0
        /// <summary>
        /// Branches need to terminate the current basic block and make links
        /// to the 'true' and 'false' destinations.
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public bool VisitBranch(RtlBranch b)
        {
            // We don't know the 'then' block yet, as the following statements may chop up the block
            // we're presently in. Back-patch in when the block target is obtained.
            var branch = new Branch(b.Condition, new Block(blockCur.Procedure, "TMP!"));

            Emit(branch);

            // The following statements may chop up the blockCur, so hang on to the essentials.
            var proc = blockCur.Procedure;
            RtlInstructionCluster ricDelayed = null;

            if ((b.Class & RtlClass.Delay) != 0)
            {
                rtlStream.MoveNext();
                ricDelayed = rtlStream.Current;
                ric        = ricDelayed;
            }
            var fallthruAddress = ric.Address + ric.Length;

            var blockThen = BlockFromAddress(ric.Address, b.Target, proc, state.Clone());

            var blockElse      = FallthroughBlock(ric.Address, proc, fallthruAddress);
            var branchingBlock = scanner.FindContainingBlock(ric.Address);

            if ((b.Class & RtlClass.Delay) != 0 &&
                ricDelayed.Instructions.Count > 0)
            {
                // Introduce stubs for the delay slot, but only
                // if the delay slot isn't empty.
                var blockDsF = proc.AddBlock(branchingBlock.Name + "_ds_f");
                var blockDsT = proc.AddBlock(branchingBlock.Name + "_ds_t");
                blockDsF.IsSynthesized = true;
                blockDsT.IsSynthesized = true;
                blockCur = blockDsF;
                ProcessRtlCluster(ricDelayed);
                blockCur = blockDsT;
                ProcessRtlCluster(ricDelayed);
                EnsureEdge(proc, blockDsF, blockElse);
                EnsureEdge(proc, blockDsT, blockThen);
                branch.Target = blockDsT;
                EnsureEdge(proc, branchingBlock, blockDsF);
                EnsureEdge(proc, branchingBlock, blockDsT);
            }
            else
            {
                branch.Target = blockThen;      // The back-patch referred to above.
                EnsureEdge(proc, branchingBlock, blockElse);
                EnsureEdge(proc, branchingBlock, blockThen);
            }

            // Now, switch to the fallthru block and keep rewriting.
            blockCur = blockElse;
            return(true);
        }
예제 #3
0
        public SlicerResult VisitBranch(RtlBranch branch)
        {
            var se         = branch.Condition.Accept(this, BackwardSlicerContext.Cond(new BitRange(0, 0)));
            var addrTarget = branch.Target as Address;

            if (addrTarget == null)
            {
                throw new NotImplementedException();    //$REVIEW: do we ever see this?
            }
            if (this.addrSucc != addrTarget)
            {
                this.invertCondition = true;
            }
            return(se);
        }
예제 #4
0
        public RtlInstruction Branch(Expression cond, Address target, RtlClass rtlClass)
        {
            var br = new RtlBranch(cond, target, rtlClass);

            return(Emit(br));
        }
예제 #5
0
파일: RtlEmitter.cs 프로젝트: relaxar/reko
 /// <summary>
 /// Called when we need to generate an RtlBranch in the middle of an operation.
 /// Normally, branches are at the end of the Rtl's of a translated instruction,
 /// but in some cases, they are not.
 /// </summary>
 /// <param name="condition"></param>
 /// <param name="target"></param>
 /// <param name="?"></param>
 public void BranchInMiddleOfInstruction(Expression condition, Address target, RtlClass rtlClass)
 {
     var branch = new RtlBranch(condition, target, rtlClass);
     branch.NextStatementRequiresLabel = true;
     instrs.Add(branch);
 }
예제 #6
0
 public RtlInstruction Branch(Expression cond, Address target, RtlClass rtlClass)
 {
     var br = new RtlBranch(cond, target, rtlClass);
     return Emit(br);
 }
예제 #7
0
        /// <summary>
        /// Branches need to terminate the current basic block and make links
        /// to the 'true' and 'false' destinations.
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public bool VisitBranch(RtlBranch b)
        {
            // We don't know the 'then' block yet, as the following statements may chop up the block
            // we're presently in. Back-patch in when the block target is obtained.
            var branch = new Branch(b.Condition, new Block(blockCur.Procedure, "TMP!"));

            Emit(branch, blockCur);

            // The following statements may chop up the blockCur, so hang on to the essentials.
            var proc = blockCur.Procedure;
            RtlInstructionCluster ricDelayed = null;

            if ((b.Class & RtlClass.Delay) != 0)
            {
                rtlStream.MoveNext();
                ricDelayed = rtlStream.Current;
                ric        = ricDelayed;
            }
            var fallthruAddress = ric.Address + ric.Length;

            Block blockThen;

            if (!program.SegmentMap.IsValidAddress((Address)b.Target))
            {
                blockThen = proc.AddBlock(this.ric.Address.GenerateName("l", "_then"));
                var jmpSite = state.OnBeforeCall(stackReg, arch.PointerType.Size);
                GenerateCallToOutsideProcedure(jmpSite, (Address)b.Target);
                Emit(new ReturnInstruction());
                blockCur.Procedure.ControlGraph.AddEdge(blockCur, blockCur.Procedure.ExitBlock);
            }
            else
            {
                blockThen = BlockFromAddress(ric.Address, (Address)b.Target, proc, state.Clone());
            }

            var blockElse      = FallthroughBlock(ric.Address, proc, fallthruAddress);
            var branchingBlock = blockCur.IsSynthesized
                ? blockCur
                : scanner.FindContainingBlock(ric.Address);

            if ((b.Class & RtlClass.Delay) != 0 &&
                ricDelayed.Instructions.Length > 0)
            {
                // Introduce stubs for the delay slot, but only
                // if the delay slot isn't empty.

                if ((b.Class & RtlClass.Annul) != 0)
                {
                    EnsureEdge(proc, branchingBlock, blockElse);
                }
                else
                {
                    Block blockDsF = null;
                    blockDsF = proc.AddBlock(branchingBlock.Name + "_ds_f");
                    blockDsF.IsSynthesized = true;
                    blockCur = blockDsF;
                    ProcessRtlCluster(ricDelayed);
                    EnsureEdge(proc, blockDsF, blockElse);
                    EnsureEdge(proc, branchingBlock, blockDsF);
                }

                Block blockDsT = proc.AddBlock(branchingBlock.Name + "_ds_t");
                blockDsT.IsSynthesized = true;
                blockCur = blockDsT;
                ProcessRtlCluster(ricDelayed);
                EnsureEdge(proc, blockDsT, blockThen);
                branch.Target = blockDsT;
                EnsureEdge(proc, branchingBlock, blockDsT);
            }
            else
            {
                branch.Target = blockThen;      // The back-patch referred to above.
                EnsureEdge(proc, branchingBlock, blockElse);
                if (blockElse != blockThen)
                {
                    EnsureEdge(proc, branchingBlock, blockThen);
                }
                else
                {
                    proc.ControlGraph.AddEdge(branchingBlock, blockThen);
                }
            }
            if (BlockHasBeenScanned(blockElse))
            {
                return(false);
            }
            else
            {
                blockCur = blockElse;
                return(true);
            }
        }