public void ReplaceLastNonBranchWithBranch(int numInstrs, Block target) { if (LastInstr.IsBr()) { numInstrs++; } ReplaceLastInstrsWithBranch(numInstrs, target); }
public bool CanAppend(Block other) { if (other == null || other == this || GetOnlyTarget() != other) { return(false); } // If it's eg. a leave, then don't merge them since it clears the stack. return(LastInstr.IsBr() || Instr.IsFallThrough(LastInstr.OpCode)); }
public void FlipConditionalBranch() { if (fallThrough == null || targets == null || targets.Count != 1) { throw new ApplicationException("Invalid bcc block state"); } LastInstr.FlipConditonalBranch(); var oldFallThrough = fallThrough; fallThrough = targets[0]; targets[0] = oldFallThrough; }
public void Remove(int index, int num) { if (index + num > instructions.Count) { throw new ApplicationException("Overflow"); } if (num > 0 && index + num == instructions.Count && LastInstr.IsConditionalBranch()) { DisconnectFromFallThroughAndTargets(); } instructions.RemoveRange(index, num); }
// If last instr is a br/br.s, removes it and replaces it with a fall through public void RemoveLastBr() { if (!LastInstr.IsBr()) { return; } if (fallThrough != null || (LastInstr.Operand != null && (targets == null || targets.Count != 1))) { throw new ApplicationException("Invalid block state when last instr is a br/br.s"); } fallThrough = LastInstr.Operand != null ? targets[0] : null; targets = null; instructions.RemoveAt(instructions.Count - 1); }
// Returns true if it's a conditional branch public bool IsConditionalBranch() { return(LastInstr.IsConditionalBranch()); }
public bool CanFlipConditionalBranch() { return(LastInstr.CanFlipConditionalBranch()); }