/// <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); }
/// <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); }
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); }
public RtlInstruction Branch(Expression cond, Address target, RtlClass rtlClass) { var br = new RtlBranch(cond, target, rtlClass); return(Emit(br)); }
/// <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); }
public RtlInstruction Branch(Expression cond, Address target, RtlClass rtlClass) { var br = new RtlBranch(cond, target, rtlClass); return Emit(br); }
/// <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); } }