Simulation

Rasmus Pedersen <[email protected]> Thu, 20 Apr 2006 14:26:46 +0200
Newsgroups gmane.comp.jakarta.bcel.user
Message-ID <[email protected]>
Hi,

I have written a class (attached) that uses a controlflowgraph. It only 
walks the code using the instructions themselves.

I would like to use the values of the variables in a method to figure 
out how many times a basic block is executed. So the question is: How 
(not if) can I find out how often a loop is executed using BCEL? Would 
it help to use final variables or something that could be read in BCEL 
at compile time???

Best,
Rasmus

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
WCETAnalyser.java (text/plain, 68.3 KB)
package com.jopdesign.wcet;

import java.util.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import org.apache.bcel.classfile.*;
import org.apache.bcel.classfile.Visitor;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.*;
import org.apache.bcel.verifier.exc.*;
import org.apache.bcel.verifier.structurals.*;

import com.jopdesign.build.TransitiveHull;

/**
 * The class is a STARTING POINT for wcet analysis. It is pretty
 * straight-forward to add classes that hook into the
 * <code>controlFlowGraph</code> and is used as a departure for further
 * analysis. The <code>WCETMethodBlock</code> is an example of how the basic
 * blocks can be created.
 * 
 * The control flow graph is used as a basis for creating the basic blocks. It
 * builds up an array of basic blocks in the WCETMethodBlock.
 * 
 * The basic hierarchy is that WCETAnalyzer creates one WCETMethodBlock for each
 * method. The WCETMethodBlock assists WCETAnalyzer in creating the
 * WCETBasicBlock objects for each basic block. Then WCETBasicBlock can be used
 * together with WCETInstruction to calculate the WCET value for that particular
 * basic block.
 * 
 * @author rup, ms
 * @see Section 7.4 and Appendix D in MS thesis
 */

// History:
// 2006-04-01 rup: Initial version aimed at directed graph of basic blocks
// 2006-04-07 rup: Moved to become a non-Jopizer dependent piece of code
// 2006-04-20 rup: Show both cachehit and cachemiss entries

// TODOs:
// TODO: WCET/BCET analysis. Now it is "just" cycle counting
// TODO: How to analyze those bytecodes implemented in Java? (MS: Use the WCA on the functions)
// TODO: How to handle the {209-221} opcodes for JOP?

/**
 * The thing that controls the WCETClassBlock etc.
 */
public class WCETAnalyser {
  public final static String nativeClass = "com.jopdesign.sys.Native";

  PrintWriter out;

  /**
   * Loaded classes, type is JavaClass
   */
  List clazzes = new LinkedList();

  org.apache.bcel.util.ClassPath classpath; // = ClassPath.SYSTEM_CLASS_PATH;

  /**
   * The class that contains the main method.
   */
  static String mainClass;

  public WCETAnalyser() {
    // TODO: Debugging from Eclipse creates a different classpath?
    // classpath = new org.apache.bcel.util.ClassPath(".");
  }

  public static void main(String[] args) {
    String outFile = "/tmp/wcet.txt";
    WCETAnalyser wca = new WCETAnalyser();
    HashSet clsArgs = new HashSet();

    try {
      if (args.length == 0) {
        System.err
            .println("WCETAnalyser arguments: [-cp classpath] [-o file] class [class]*");
      } else {
        for (int i = 0; i < args.length; i++) {
          if (args[i].equals("-cp")) {
            i++;
            wca.classpath = new org.apache.bcel.util.ClassPath(args[i]);
            continue;
          }
          if (args[i].equals("-o")) {
            i++;
            outFile = args[i];
            continue;
          }

          clsArgs.add(args[i]);
          mainClass = args[i].replace('/', '.');
        }

        System.out.println("CLASSPATH=" + wca.classpath + "\tmain class="
            + mainClass);

        wca.out = new PrintWriter(new FileOutputStream(outFile));

        wca.load(clsArgs);

        wca.iterate(new SetWCETAnalysis(wca));
        wca.out.println("************************************************");
        wca.out.println("\nTable of WCETInstruction cycles");
        wca.out.println("\nassuming n=0");
        wca.out.println("================================");
        wca.out.println("Instruction               Cycles");
        wca.out.println("--------------------------------");
        wca.out.println(WCETInstruction.toWCAString()
            + "================================");
        wca.out.println("Note: Remember to keep WCETAnalyzer updated");
        wca.out.println("each time a bytecode implementation is changed.");
        wca.out.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Load all classes and the super classes from the argument list.
   * 
   * @throws IOException
   */
  private void load(Set clsArgs) throws IOException {
    JavaClass[] jcl = new JavaClass[clsArgs.size()];
    Iterator i = clsArgs.iterator();
    for (int nr = 0; i.hasNext(); ++nr) {
      String clname = (String) i.next();
      InputStream is = classpath.getInputStream(clname);
      jcl[nr] = new ClassParser(is, clname).parse();
      System.out.println(jcl[nr].getClassName());
    }
    TransitiveHull hull = new TransitiveHull(classpath, jcl);
    hull.start();
    System.out.println(Arrays.asList(hull.getClassNames()));
    JavaClass[] jc = hull.getClasses();
    // clazzes contains now the closure of the application
    for (int j = 0; j < jc.length; ++j) {
      // The class Native is NOT used in a JOP application
      if (!jc[j].getClassName().equals(nativeClass)) {
        // ClassInfo cli = new ClassInfo(jc[j]);
        clazzes.add(jc[j]);
        // clazz2cli.put(jc[j], cli);
      }
    }
  }

  private void iterate(Visitor v) {

    Iterator it = clazzes.iterator();
    // System.err.println("------------------");
    while (it.hasNext()) {
      JavaClass clz = (JavaClass) it.next();
      new DescendingVisitor(clz, v).visit();
    }
  }
  
}

/**
 * It has a HashMap of WCETBasicBlocks. The class have methods that are called
 * from the WCETAnalyzers controlFlowGraph method. It creates the the directed
 * graph of wcbbs.
 */
// TODO: Perhaps add a WCETJavaClass later
class WCETMethodBlock {
  // Basic Blocks
  TreeMap bbs;

  JavaClass jc;

  Method method;

  MethodGen mg;

  ControlFlowGraph cfg;

  String tostr;

  String signature;

  String name;

  String cname;

  // directed graph of the basic blocks
  int dg[][];
  
  // method size in 32 bit words
  int n = -1;

  // create a bb covering the whole method
  // from here on we split it when necessary
  public void init(InstructionHandle stih, InstructionHandle endih) {
    WCETBasicBlock wcbb = new WCETBasicBlock(stih, endih, this);
    // wcbb.setEnd(endih.getPosition()); //we will do it lastly
    bbs.put(new Integer(wcbb.getStart()), wcbb);
  }

  /**
   * Instanciated from from <code>SetClassInfo</code>.
   */
  public WCETMethodBlock(Method method, JavaClass jc) {
    String methodId = method.getName() + method.getSignature();

    String classId = jc.getClassName();
    bbs = new TreeMap();
    this.method = method;
    this.jc = jc;

    // TODO: ms needs to check if the "3" needs to be added like
    // in MethodInfo?
    // set method length in 32 bit words

    if (!method.isAbstract()) {
      n = (method.getCode().getCode().length + 3) / 4;
    } else {
      n = -1;
    }
  }

  /**
   * Control flow analysis for one nonabstract-method.
   */
  public void controlFlowGraph() {
    ConstantPoolGen cpg = new ConstantPoolGen(jc.getConstantPool());

    // Some methods overridden (see bottom of this file)
    InstConstraintVisitor icv = new AnInstConstraintVisitor();

    icv.setConstantPoolGen(cpg);

    ExecutionVisitor ev = new ExecutionVisitor();
    ev.setConstantPoolGen(cpg);

    MethodGen mg = new MethodGen(method, jc.getClassName(), cpg);
    // To later get the PC positions of the instructions
    mg.getInstructionList().setPositions(true);
    // String tostr = mg.toString();
    String signature = mg.getSignature();
    // debug hint: set conditionl breakpoint here like name=="sort"
    String name = mg.getName();
    // System.out.println(name);
    String cname = mg.getClassName();

    icv.setMethodGen(mg);

    if (!(mg.isAbstract() || mg.isNative())) { // IF mg HAS CODE

      // pass 0: Create basic blocks
      InstructionHandle ih = mg.getInstructionList().getStart();
      // wcet startup: create the first full covering bb
      InstructionHandle ihend = mg.getInstructionList().getEnd();
      init(ih, ihend);
      // System.out.println(mg);
      // System.out.println(method.getCode());

      do {
        // create new bb (a)for branch target and (b) for sucessor
        // TODO: What about return?
        Instruction ins = ih.getInstruction();
        // System.out.println(ins);
        if (ih.getInstruction() instanceof BranchInstruction) {
          InstructionHandle ihtar = ((BranchInstruction) ih.getInstruction())
              .getTarget();
          // System.out.println(ihtar);
          InstructionHandle ihnext = ih.getNext();
          createBasicBlock(ihtar);
          if (ihnext != null) {
            // TODO: Check that last instruction works and that a basic block
            // can be of length one
            createBasicBlock(ihnext);
          }
        }
      } while ((ih = ih.getNext()) != null);

      // Pass 1: Set the id of each block
      int id = 0;
      // it is sorted on the (final) start pos of each block
      for (Iterator iter = getBbs().keySet().iterator(); iter.hasNext();) {
        WCETBasicBlock wbb = (WCETBasicBlock) getBbs().get(
            (Integer) iter.next());
        wbb.calculateWcet();
        wbb.setId(id);
        id++;

        // Can the linking be done here?
        ih = wbb.getEndih();
        WCETBasicBlock wbbthis = getCoveringBB(ih);

        if (ih.getInstruction() instanceof BranchInstruction) {
          // target
          InstructionHandle ihtar = ((BranchInstruction) ih.getInstruction())
              .getTarget();
          WCETBasicBlock wbbtar = getCoveringBB(ihtar);
          // target wbb
          wbbthis.setTarbb(wbbtar);
          // targeter in target
          wbbtar.addTargeter(wbbthis);

          // next when the instruction is an if
          // TODO: What about TABLESWITCH and LOOKUPSWITCH
          if (ih.getInstruction() instanceof IfInstruction) {

            InstructionHandle ihnext = ih.getNext();

            if (ihnext != null) {
              WCETBasicBlock wbbnxt = getCoveringBB(ihnext);
              // nextwbb
              wbbthis.setSucbb(wbbnxt);
            }
          }
        } else { // just set successor
          InstructionHandle ihnext = ih.getNext();

          if (ihnext != null) {
            WCETBasicBlock wbbnxt = getCoveringBB(ihnext);
            // nextwbb
            wbbthis.setSucbb(wbbnxt);
          }

        }

      }

      // Pass 2: linking the blocks
      // ih = mg.getInstructionList().getStart();
      //
      // do {
      // if (ih.getInstruction() instanceof BranchInstruction) {
      // // target
      // InstructionHandle ihtar = ((BranchInstruction) ih.getInstruction())
      // .getTarget();
      // WCETBasicBlock wbbthis = getCoveringBB(ih);
      // WCETBasicBlock wbbtar = getCoveringBB(ihtar);
      // // target wbb
      // wbbthis.setTarbb(wbbtar);
      // // targeter in target
      // wbbtar.addTargeter(wbbthis);
      //
      // // next when the instruction is an if
      // //TODO: What about TABLESWITCH and LOOKUPSWITCH
      // if (ih.getInstruction() instanceof IfInstruction) {
      //            
      // InstructionHandle ihnext = ih.getNext();
      //
      // if (ihnext != null) {
      // WCETBasicBlock wbbnxt = getCoveringBB(ihnext);
      // // nextwbb
      // wbbthis.setSucbb(wbbnxt);
      // }
      // }
      // }
      // } while ((ih = ih.getNext()) != null);

    }

  }

  public ControlFlowGraph getControlFlowGraph() {
    return cfg;
  }

  public MethodGen getMethodGen() {
    return mg;
  }

  /**
   * Get the bb that currently covers the bytecode at the position. The design
   * is such that some bb will always cover a bytecode. It may the the same bb
   * that is returned if the branch points back (direct loop).
   * 
   * @param pos
   * @return covering bb
   */
  public WCETBasicBlock getCoveringBB(InstructionHandle ih) {
    // if cov bb starts on pos then done otherwise run throug all keys
    WCETBasicBlock covbb = (WCETBasicBlock) bbs.get(new Integer(ih
        .getPosition()));
    if (covbb == null) {
      Iterator it = bbs.keySet().iterator();
      // find the cov. bb
      int bbpos = 0;
      while (it.hasNext()) {
        int apos = ((Integer) it.next()).intValue();
        if (apos < ih.getPosition() && apos > bbpos) {
          bbpos = apos;
        }
      }
      covbb = (WCETBasicBlock) bbs.get(new Integer(bbpos));
    }
    return covbb;
  }

  /**
   * Create a new wcbb if none of the existing wcbbs are starting on that
   * position. Call this method twice when you encounter a branch type byte
   * code.
   * 
   * @param start
   *          the position to check for
   * @return true if a wcbb was created
   */
  public boolean createBasicBlock(InstructionHandle stih) {
    boolean res;
    // get the covering bb
    WCETBasicBlock covwcbb = getCoveringBB(stih);
    if (covwcbb.getStart() == stih.getPosition()) {
      // already a bb on start pos
      res = false;
    } else // create one by splitting the covering bb
    {
      WCETBasicBlock wcbb = covwcbb.split(stih);
      // save the new bb in the hash map
      if (bbs.put(new Integer(stih.getPosition()), wcbb) != null) {
        System.err.println("The starting pos should be unique.");
        System.exit(-1);
      }
      res = true;
    }
    return res;
  }

  /**
   * It sorts the basic blocks and creates the directed graph.
   */
  public void directedGraph() {
    // now create the directed graph
    dg = new int[bbs.size()][bbs.size()];
    for (Iterator iter = bbs.keySet().iterator(); iter.hasNext();) {
      Integer keyInt = (Integer) iter.next();
      // HERE
      WCETBasicBlock wcbb = (WCETBasicBlock) bbs.get(keyInt);
      WCETBasicBlock tarwcbb = wcbb.getTarbb();
      // TODO: Check for bugs
      int id = wcbb.getId();
      if (tarwcbb != null) {
        int tarbbid = tarwcbb.getId();
        dg[id][tarbbid]++;
      }
      WCETBasicBlock sucbb = wcbb.getSucbb();
      if (sucbb != null) {
        int sucid = sucbb.getId();
        dg[id][sucid]++;
      }
    }

  }

  /**
   * Converts the WCETMethodBasicBlock to a String.
   * 
   * @return string representation of the MehtodBasicBlock
   */
  public String toString() {
    StringBuffer sb = new StringBuffer();
    sb.append("************************************************\n");
    sb.append("\"WCET\" DUMP OF " + jc.getClassName() + "." + method.getName()
        + method.getSignature() + "\nlen="+n+" words\n");

    // sb.append("Number of basic blocks= "+ bbs.size()+"\n");

    // sb.append("Method cycle sum="+methodWcet+" (just the sum of the basic
    // blocks)\n");
    // sb.append("Valid wcet="+validMethodWcet+"( if all bytecodes used have a
    // valid cycle count)\n");

    // info and wcet for each block
    // listing
    sb.append("\nTable of basic blocks\n");
    sb.append("============================\n");
    sb.append("Block   Cyc. hit   Cyc. miss\n");
    sb.append("----------------------------\n");
   
    int mwcetHit = 0;
    int mwcetMiss = 0;
    boolean validMethodWcet = true;

    for (Iterator iter = bbs.keySet().iterator(); iter.hasNext();) {
      Integer keyInt = (Integer) iter.next();
      WCETBasicBlock wcbb = (WCETBasicBlock) bbs.get(keyInt);
      sb.append(wcbb.toString() + "\n");
      if (wcbb.getValid()) {
        mwcetHit += wcbb.getWcetHit();
        mwcetMiss += wcbb.getWcetMiss();
      } else {
        validMethodWcet = false;
      }
    }
    sb.append("============================\n");
    sb.append("Sum:    " 
        +WU.prepad(Integer.toString(mwcetHit),8)
        +"   "
        +WU.prepad(Integer.toString(mwcetMiss),9));
    sb.append("\n");
    sb.append("============================\n");
   
    if (!validMethodWcet)
      sb.append("*NB: invalid BB (ie. cycle count not available)\n");
    
    sb.append("\n");

    // directed graph
    sb.append("Directed graph of basic blocks(row->column):\n");
    StringBuffer top = new StringBuffer();
    top.append("    ");
    for (int i = 0; i < dg.length; i++) {

      top.append("B" + i);
      if (i < 100)
        top.append(" ");
      if (i < 10)
        top.append(" ");
    }
    top.append("\n");

    for (int i = 0; i < top.length() - 2; i++) {
      sb.append("=");
    }
    sb.append("\n" + top.toString());

    for (int i = 0; i < dg.length; i++) {
      sb.append("B" + i);
      // if(i<100)
      // sb.append(" ");
      if (i < 10)
        sb.append(" ");

      for (int j = 0; j < dg.length; j++) {
        if (dg[i][j] == 0)
          sb.append(" ."); // a space does not clutter it as much as a zero
        else
          sb.append(" " + dg[i][j]);

        if (dg[i][j] < 100)
          sb.append(" ");
        if (dg[i][j] < 10)
          sb.append(" ");
      }
      sb.append("\n");
    }
    for (int i = 0; i < top.length() - 2; i++) {
      sb.append("=");
    }
    sb.append("\n");

    // bytecode listing
    sb.append("\nTable of basic blocks' and instructions\n");
    sb.append("======================================================\n");
    sb.append("Block Addr. Bytecode[opcode]      Cyc. hit   Cyc. miss\n");
    sb.append("------------------------------------------------------\n");

    for (Iterator iter = bbs.keySet().iterator(); iter.hasNext();) {
      Integer keyInt = (Integer) iter.next();
      WCETBasicBlock wcbb = (WCETBasicBlock) bbs.get(keyInt);
      sb.append(wcbb.toCodeString());
    }
    sb.append("======================================================\n");
    sb.append("Sum:                              " 
        +WU.prepad(Integer.toString(mwcetHit),8)
        +"   "
        +WU.prepad(Integer.toString(mwcetMiss),9)
        +"\n");
    sb.append("======================================================\n");
    return sb.toString();
  }

  public TreeMap getBbs() {
    return bbs;
  }

  public int getN() {
    return n;
  }
}

/**
 * Basic block of byte codes
 */
class WCETBasicBlock {
  // parent
  WCETMethodBlock wcmb;
 
  // id of the bb
  int id;

  // The reason why we are doing this...
  int wcetHit;
  int wcetMiss;

  // False if we encounter WCETNOTAVAILABLE bytecodes while counting
  boolean valid;

  // start pos
  final int start;

  final Integer key;

  final InstructionHandle stih;

  // end pos which will change as splitting happens
  int end;

  // end instruction handle
  InstructionHandle endih;

  // target branch block
  WCETBasicBlock tarbb;

  // sucessor block
  WCETBasicBlock sucbb;

  // invard links from other BBs called targeters
  HashMap inbbs;

  WCETBasicBlock(InstructionHandle stih, InstructionHandle endih, WCETMethodBlock wcmb) {
    this.wcmb = wcmb;
    valid = false;
    wcetHit = -1;
    wcetMiss = -1;
    inbbs = new HashMap();
    start = stih.getPosition();
    key = new Integer(start);
    end = endih.getPosition();
    this.stih = stih;
    this.endih = endih;
  }

  /**
   * Add wbb that points to this wbb.
   * 
   * @param wbbtargeter
   *          a wbb that points to this wbb.
   * @return true if it was already added
   */
  boolean addTargeter(WCETBasicBlock wbbtargeter) {
    WCETBasicBlock wbbold = (WCETBasicBlock) inbbs.put(wbbtargeter.getKey(),
        wbbtargeter);
    if (wbbold == null) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * Will create a new BB by splitting the old.
   * 
   * @param stih
   *          the first instruction of the new block
   * @return the new BB
   */
  // TODO: Do they inherit the targeters (a "targeter" is something that points
  // to a target)
  WCETBasicBlock split(InstructionHandle newstih) {
    WCETBasicBlock spbb = new WCETBasicBlock(newstih, endih, wcmb);
    // spbb.end = stih.getPrev().getPosition();
    // end the last block with the previous pos
    end = newstih.getPrev().getPosition();
    endih = newstih.getPrev();
    // start the new block with stih handle
    // spbb.inbbs.put(new Integer(spbb.start), spbb);
    return spbb;
  }

  /**
   * Returns the cycle count for cache hit. Remember to check validWcet() for validity.
   * 
   * @return wcet count
   */
  public int getWcetHit() {
    return wcetHit;
  }

  /**
   * Calculte wcetHit and wcetMiss for the Basic block.
   */
  public void calculateWcet() {
    InstructionHandle ih = stih;
    wcetHit = 0;
    wcetMiss = 0;
    valid = true;
    do {
      int wcetHitTmp = WCETInstruction.getCyclesFromHandle(ih, false, wcmb.getN());
      int wcetMissTmp = WCETInstruction.getCyclesFromHandle(ih, true, wcmb.getN());
      if (wcetHitTmp != WCETInstruction.WCETNOTAVAILABLE) {
        wcetHit += wcetHitTmp;
        wcetMiss += wcetMissTmp;
      } else {
        valid = false;
      }
    } while (ih != endih && (ih = ih.getNext()) != null); // null will never
                                                          // happen, but need
                                                          // the getNext
    // TODO: Is the above correct?
  }

  /**
   * True if the
   * 
   * @return
   */
  public boolean getValid() {
    return valid;
  }

  public String toString() {
    StringBuffer sb = new StringBuffer();
    // block (6)
    String s = "B" + id;
    if (!getValid())
      s+="*";
    
    sb.append(WU.postpad(s,8));

    // Cyc. hit   Cyc. miss
    sb.append(WU.prepad(Integer.toString(wcetHit),8));
    sb.append("   ");
    sb.append(WU.prepad(Integer.toString(wcetMiss),9));
    //sb.append("\n");

    // if(tarbb!=null){
    // sb.append("target block id="+tarbb.getId()+"\n");
    // }else
    // {
    // sb.append("target block id=null\n");
    // }
    // if(sucbb!=null){
    // sb.append("successor block id="+sucbb.getId()+"\n");
    // }else
    // {
    // sb.append("successor block id=null\n");
    // }
    // int i=0;
    // for (Iterator iter = inbbs.keySet().iterator(); iter.hasNext();) {
    // Integer keyInt = (Integer) iter.next();
    // WCETBasicBlock wcbb = (WCETBasicBlock) inbbs.get(keyInt);
    // sb.append("targeter["+i+"] id="+wcbb.getId()+"\n");
    // i++;
    // }
    return sb.toString();
  }

  /**
   * Outputs in the format similar to Table 1 in the DATE paper.
   * 
   * @return the formatted string
   */
  public String toCodeString() {
    StringBuffer sb = new StringBuffer();

    InstructionHandle ih = stih;
    do {
      // block (len 6)
      if (ih == stih) {
        sb.append("B" + id + "  ");
        if (id < 100)
          sb.append(" ");
        if (id < 10)
          sb.append(" ");
      } else {
        sb.append("      ");
      }
      // addr (len 6)
      sb.append(ih.getPosition() + ":" + "  ");
      if (ih.getPosition() < 100)
        sb.append(" ");
      if (ih.getPosition() < 10)
        sb.append(" ");
      
      // bytecode (len 22)
      StringBuffer ihs = new StringBuffer(ih.getInstruction().getName() + "["
          + ih.getInstruction().getOpcode() + "]");
      if(!WCETInstruction.wcetAvailable(ih.getInstruction().getOpcode()))
        sb.append("*");
      
      if (ih.getInstruction() instanceof BranchInstruction) {
        // target
        InstructionHandle ihtar = ((BranchInstruction) ih.getInstruction())
            .getTarget();
        int tarpos = ihtar.getPosition();
        ihs.append(" -> " + tarpos + ":");
      }
      int pad = 22 - ihs.length();
      if (pad < 0)
        pad = 0;
      for (int i = 0; i < pad; i++) {
        ihs.append(" ");
      }
      sb.append(ihs.toString());

      // "Cyc. hit   Cyc. miss" 8+3+9
      int wcetihMiss = WCETInstruction.getCyclesFromHandle(ih, true, wcmb.getN());
      int wcetihHit = WCETInstruction.getCyclesFromHandle(ih, false, wcmb.getN());

      sb.append(WU.prepad(Integer.toString(wcetihHit),8));
      sb.append("   ");
      sb.append(WU.prepad(Integer.toString(wcetihMiss),9));
      sb.append("\n");
    } while (ih != endih && (ih = ih.getNext()) != null);

    return sb.toString();
  }

  public int getStart() {
    return start;
  }

  public int getEnd() {
    return end;
  }

  public void setEnd(int end) {
    this.end = end;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public InstructionHandle getStih() {
    return stih;
  }

  public InstructionHandle getEndih() {
    return endih;
  }

  public void setEndih(InstructionHandle endih) {
    this.endih = endih;
  }

  public WCETBasicBlock getTarbb() {
    return tarbb;
  }

  public WCETBasicBlock getSucbb() {
    return sucbb;
  }

  public void setTarbb(WCETBasicBlock tarbb) {
    this.tarbb = tarbb;
  }

  public void setSucbb(WCETBasicBlock sucbb) {
    this.sucbb = sucbb;
  }

  public Integer getKey() {
    return key;
  }

  public int getWcetMiss() {
    return wcetMiss;
  }
}

/**
 * It has wcet info on byte code instruction granlularity. Should we consider
 * making a class that wraps the microcodes into objects?
 */
class WCETInstruction {
  // indicate that wcet is not available for this byte code
  public static final int WCETNOTAVAILABLE = -1;

  // bytecode load
  public static final int a = 3;

  // mem read: 3 for mem and 3 for pipe
  public static final int r = 6;

  // mem write
  public static final int w = 6;

  private static String ILLEGAL_OPCODE = "ILLEGAL_OPCODE";

  /**
   * Names of opcodes.
   */
  protected static final String[] OPCODE_NAMES = { "nop", "aconst_null",
      "iconst_m1", "iconst_0", "iconst_1", "iconst_2", "iconst_3", "iconst_4",
      "iconst_5", "lconst_0", "lconst_1", "fconst_0", "fconst_1", "fconst_2",
      "dconst_0", "dconst_1", "bipush", "sipush", "ldc", "ldc_w", "ldc2_w",
      "iload", "lload", "fload", "dload", "aload", "iload_0", "iload_1",
      "iload_2", "iload_3", "lload_0", "lload_1", "lload_2", "lload_3",
      "fload_0", "fload_1", "fload_2", "fload_3", "dload_0", "dload_1",
      "dload_2", "dload_3", "aload_0", "aload_1", "aload_2", "aload_3",
      "iaload", "laload", "faload", "daload", "aaload", "baload", "caload",
      "saload", "istore", "lstore", "fstore", "dstore", "astore", "istore_0",
      "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1", "lstore_2",
      "lstore_3", "fstore_0", "fstore_1", "fstore_2", "fstore_3", "dstore_0",
      "dstore_1", "dstore_2", "dstore_3", "astore_0", "astore_1", "astore_2",
      "astore_3", "iastore", "lastore", "fastore", "dastore", "aastore",
      "bastore", "castore", "sastore", "pop", "pop2", "dup", "dup_x1",
      "dup_x2", "dup2", "dup2_x1", "dup2_x2", "swap", "iadd", "ladd", "fadd",
      "dadd", "isub", "lsub", "fsub", "dsub", "imul", "lmul", "fmul", "dmul",
      "idiv", "ldiv", "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg",
      "lneg", "fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr",
      "iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f",
      "i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f",
      "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg", "dcmpl", "dcmpg", "ifeq",
      "ifne", "iflt", "ifge", "ifgt", "ifle", "if_icmpeq", "if_icmpne",
      "if_icmplt", "if_icmpge", "if_icmpgt", "if_icmple", "if_acmpeq",
      "if_acmpne", "goto", "jsr", "ret", "tableswitch", "lookupswitch",
      "ireturn", "lreturn", "freturn", "dreturn", "areturn", "return",
      "getstatic", "putstatic", "getfield", "putfield", "invokevirtual",
      "invokespecial", "invokestatic", "invokeinterface", ILLEGAL_OPCODE,
      "new", "newarray", "anewarray", "arraylength", "athrow", "checkcast",
      "instanceof", "monitorenter", "monitorexit", "wide", "multianewarray",
      "ifnull", "ifnonnull", "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
      ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE };

  // TODO: make those missing (the rup/ms speciffic ones, but are they
  // reachable?)

  /**
   * Same as getWCET, but using the handle.
   * 
   * @param ih
   * @param pmiss true if the cache is missed and false if there is a cache hit
   * @return wcet or WCETNOTAVAILABLE (-1)
   */
  static int getCyclesFromHandle(InstructionHandle ih, boolean pmiss, int n) {
    Instruction ins = ih.getInstruction();
    int opcode = ins.getOpcode();
     
    return getCycles(opcode, pmiss, n);
  }

  /**
   * Get the name using the opcode. Used when WCA toWCAString().
   * 
   * @param opcode
   * @return name or "ILLEGAL_OPCODE"
   */
  static String getNameFromOpcode(int opcode) {
    return OPCODE_NAMES[opcode];
  }

  /**
   * See the WCET values
   * 
   * @return
   */

  static String toWCAString() {
    StringBuffer sb = new StringBuffer();
    for (int op = 0; op <= 255; op++) {
      // name (25)
      String str = new String("[" + op + "] " + getNameFromOpcode(op));
      int pad = 25 - str.length();
      sb.append(str);
      for (int i = 0; i < pad; i++) {
        sb.append(" ");
      }

      // wcet (7), assuming n=0
      int wcettmp = getCycles(op, false, 0);
      if (wcettmp < 10000)
        sb.append(" ");
      if (wcettmp < 10000)
        sb.append(" ");
      if (wcettmp < 1000)
        sb.append(" ");
      if (wcettmp < 100)
        sb.append(" ");
      if (wcettmp < 10)
        sb.append(" ");
      if (wcettmp >= 0)
        sb.append(" ");
      
      sb.append(wcettmp + "\n");

    }
    return sb.toString();
  }

  /**
   * Returns the wcet count for the instruction.
   * 
   * @see table D.1 in ms thesis
   * @param opcode
   * @param pmiss true if cacle is misses and false if a cache hit
   * @return wcet cycle count or -1 if wcet not available
   */
  static int getCycles(int opcode, boolean pmiss, int n) {
    int wcet = 0;
    int b = -1;

    // cache miss
    if(pmiss){
      b=calculateB(n);
    } else // cache hit
    {
      b=0;
    }
    
    switch (opcode) {
    // NOP = 0
    case org.apache.bcel.Constants.NOP:
      wcet = 1;
      break;
    // ACONST_NULL = 1
    case org.apache.bcel.Constants.ACONST_NULL:
      wcet = 1;
      break;
    // ICONST_M1 = 2
    case org.apache.bcel.Constants.ICONST_M1:
      wcet = 1;
      break;
    // ICONST_0 = 3
    case org.apache.bcel.Constants.ICONST_0:
      wcet = 1;
      break;
    // ICONST_1 = 4
    case org.apache.bcel.Constants.ICONST_1:
      wcet = 1;
      break;
    // ICONST_2 = 5
    case org.apache.bcel.Constants.ICONST_2:
      wcet = 1;
      break;
    // ICONST_3 = 6
    case org.apache.bcel.Constants.ICONST_3:
      wcet = 1;
      break;
    // ICONST_4 = 7
    case org.apache.bcel.Constants.ICONST_4:
      wcet = 1;
      break;
    // ICONST_5 = 8
    case org.apache.bcel.Constants.ICONST_5:
      wcet = 1;
      break;
    // LCONST_0 = 9
    case org.apache.bcel.Constants.LCONST_0:
      wcet = 2;
      break;
    // LCONST_1 = 10
    case org.apache.bcel.Constants.LCONST_1:
      wcet = 2;
      break;
    // FCONST_0 = 11
    case org.apache.bcel.Constants.FCONST_0:
      wcet = -1;
      break;
    // FCONST_1 = 12
    case org.apache.bcel.Constants.FCONST_1:
      wcet = -1;
      break;
    // FCONST_2 = 13
    case org.apache.bcel.Constants.FCONST_2:
      wcet = -1;
      break;
    // DCONST_0 = 14
    case org.apache.bcel.Constants.DCONST_0:
      wcet = -1;
      break;
    // DCONST_1 = 15
    case org.apache.bcel.Constants.DCONST_1:
      wcet = -1;
      break;
    // BIPUSH = 16
    case org.apache.bcel.Constants.BIPUSH:
      wcet = 2;
      break;
    // SIPUSH = 17
    case org.apache.bcel.Constants.SIPUSH:
      wcet = 3;
      break;
    // LDC = 18
    case org.apache.bcel.Constants.LDC:
      wcet = 3 + r;
      break;
    // LDC_W = 19
    case org.apache.bcel.Constants.LDC_W:
      wcet = 4 + r;
      break;
    // LDC2_W = 20
    case org.apache.bcel.Constants.LDC2_W:
      wcet = 8 + r;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      break;
    // ILOAD = 21
    case org.apache.bcel.Constants.ILOAD:
      wcet = 2;
      break;
    // LLOAD = 22
    case org.apache.bcel.Constants.LLOAD:
      wcet = 11;
      break;
    // FLOAD = 23
    case org.apache.bcel.Constants.FLOAD:
      wcet = 2;
      break;
    // DLOAD = 24
    case org.apache.bcel.Constants.DLOAD:
      wcet = 11;
      break;
    // ALOAD = 25
    case org.apache.bcel.Constants.ALOAD:
      wcet = 2;
      break;
    // ILOAD_0 = 26
    case org.apache.bcel.Constants.ILOAD_0:
      wcet = 1;
      break;
    // ILOAD_1 = 27
    case org.apache.bcel.Constants.ILOAD_1:
      wcet = 1;
      break;
    // ILOAD_2 = 28
    case org.apache.bcel.Constants.ILOAD_2:
      wcet = 1;
      break;
    // ILOAD_3 = 29
    case org.apache.bcel.Constants.ILOAD_3:
      wcet = 1;
      break;
    // LLOAD_0 = 30
    case org.apache.bcel.Constants.LLOAD_0:
      wcet = 2;
      break;
    // LLOAD_1 = 31
    case org.apache.bcel.Constants.LLOAD_1:
      wcet = 2;
      break;
    // LLOAD_2 = 32
    case org.apache.bcel.Constants.LLOAD_2:
      wcet = 2;
      break;
    // LLOAD_3 = 33
    case org.apache.bcel.Constants.LLOAD_3:
      wcet = 11;
      break;
    // FLOAD_0 = 34
    case org.apache.bcel.Constants.FLOAD_0:
      wcet = 1;
      break;
    // FLOAD_1 = 35
    case org.apache.bcel.Constants.FLOAD_1:
      wcet = 1;
      break;
    // FLOAD_2 = 36
    case org.apache.bcel.Constants.FLOAD_2:
      wcet = 1;
      break;
    // FLOAD_3 = 37
    case org.apache.bcel.Constants.FLOAD_3:
      wcet = 1;
      break;
    // DLOAD_0 = 38
    case org.apache.bcel.Constants.DLOAD_0:
      wcet = 2;
      break;
    // DLOAD_1 = 39
    case org.apache.bcel.Constants.DLOAD_1:
      wcet = 2;
      break;
    // DLOAD_2 = 40
    case org.apache.bcel.Constants.DLOAD_2:
      wcet = 2;
      break;
    // DLOAD_3 = 41
    case org.apache.bcel.Constants.DLOAD_3:
      wcet = 11;
      break;
    // ALOAD_0 = 42
    case org.apache.bcel.Constants.ALOAD_0:
      wcet = 1;
      break;
    // ALOAD_1 = 43
    case org.apache.bcel.Constants.ALOAD_1:
      wcet = 1;
      break;
    // ALOAD_2 = 44
    case org.apache.bcel.Constants.ALOAD_2:
      wcet = 1;
      break;
    // ALOAD_3 = 45
    case org.apache.bcel.Constants.ALOAD_3:
      wcet = 1;
      break;
    // IALOAD = 46
    case org.apache.bcel.Constants.IALOAD:
      wcet = 19 + r;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      break;
    // LALOAD = 47
    case org.apache.bcel.Constants.LALOAD:
      wcet = -1;
      break;
    // FALOAD = 48
    case org.apache.bcel.Constants.FALOAD:
      wcet = 19 + r;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      break;
    // DALOAD = 49
    case org.apache.bcel.Constants.DALOAD:
      wcet = -1;
      break;
    // AALOAD = 50
    case org.apache.bcel.Constants.AALOAD:
      wcet = 19 + r;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      break;
    // BALOAD = 51
    case org.apache.bcel.Constants.BALOAD:
      wcet = 19 + r;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      break;
    // CALOAD = 52
    case org.apache.bcel.Constants.CALOAD:
      wcet = 19 + r;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      break;
    // SALOAD = 53
    case org.apache.bcel.Constants.SALOAD:
      wcet = 19 + r;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      break;
    // ISTORE = 54
    case org.apache.bcel.Constants.ISTORE:
      wcet = 2;
      break;
    // LSTORE = 55
    case org.apache.bcel.Constants.LSTORE:
      wcet = 11;
      break;
    // FSTORE = 56
    case org.apache.bcel.Constants.FSTORE:
      wcet = 2;
      break;
    // DSTORE = 57
    case org.apache.bcel.Constants.DSTORE:
      wcet = 11;
      break;
    // ASTORE = 58
    case org.apache.bcel.Constants.ASTORE:
      wcet = 2;
      break;
    // ISTORE_0 = 59
    case org.apache.bcel.Constants.ISTORE_0:
      wcet = 1;
      break;
    // ISTORE_1 = 60
    case org.apache.bcel.Constants.ISTORE_1:
      wcet = 1;
      break;
    // ISTORE_2 = 61
    case org.apache.bcel.Constants.ISTORE_2:
      wcet = 1;
      break;
    // ISTORE_3 = 62
    case org.apache.bcel.Constants.ISTORE_3:
      wcet = 1;
      break;
    // LSTORE_0 = 63
    case org.apache.bcel.Constants.LSTORE_0:
      wcet = 2;
      break;
    // LSTORE_1 = 64
    case org.apache.bcel.Constants.LSTORE_1:
      wcet = 2;
      break;
    // LSTORE_2 = 65
    case org.apache.bcel.Constants.LSTORE_2:
      wcet = 2;
      break;
    // LSTORE_3 = 66
    case org.apache.bcel.Constants.LSTORE_3:
      wcet = 11;
      break;
    // FSTORE_0 = 67
    case org.apache.bcel.Constants.FSTORE_0:
      wcet = 1;
      break;
    // FSTORE_1 = 68
    case org.apache.bcel.Constants.FSTORE_1:
      wcet = 1;
      break;
    // FSTORE_2 = 69
    case org.apache.bcel.Constants.FSTORE_2:
      wcet = 1;
      break;
    // FSTORE_3 = 70
    case org.apache.bcel.Constants.FSTORE_3:
      wcet = 1;
      break;
    // DSTORE_0 = 71
    case org.apache.bcel.Constants.DSTORE_0:
      wcet = 2;
      break;
    // DSTORE_1 = 72
    case org.apache.bcel.Constants.DSTORE_1:
      wcet = 2;
      break;
    // DSTORE_2 = 73
    case org.apache.bcel.Constants.DSTORE_2:
      wcet = 2;
      break;
    // DSTORE_3 = 74
    case org.apache.bcel.Constants.DSTORE_3:
      wcet = 11;
      break;
    // ASTORE_0 = 75
    case org.apache.bcel.Constants.ASTORE_0:
      wcet = 1;
      break;
    // ASTORE_1 = 76
    case org.apache.bcel.Constants.ASTORE_1:
      wcet = 1;
      break;
    // ASTORE_2 = 77
    case org.apache.bcel.Constants.ASTORE_2:
      wcet = 1;
      break;
    // ASTORE_3 = 78
    case org.apache.bcel.Constants.ASTORE_3:
      wcet = 1;
      break;
    // IASTORE = 79
    case org.apache.bcel.Constants.IASTORE:
      wcet = 22;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      wcet += w;
      break;
    // LASTORE = 80
    case org.apache.bcel.Constants.LASTORE:
      wcet = -1;
      break;
    // FASTORE = 81
    case org.apache.bcel.Constants.FASTORE:
      wcet = 22;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      wcet += w;
      break;
    // DASTORE = 82
    case org.apache.bcel.Constants.DASTORE:
      wcet = -1;
      break;
    // AASTORE = 83
    case org.apache.bcel.Constants.AASTORE:
      wcet = 22;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      wcet += w;
      break;
    // BASTORE = 84
    case org.apache.bcel.Constants.BASTORE:
      wcet = 22;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      wcet += w;
      break;
    // CASTORE = 85
    case org.apache.bcel.Constants.CASTORE:
      wcet = 22;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      wcet += w;
      break;
    // SASTORE = 86
    case org.apache.bcel.Constants.SASTORE:
      wcet = 22;
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      wcet += w;
      break;
    // POP = 87
    case org.apache.bcel.Constants.POP:
      wcet = 1;
      break;
    // POP2 = 88
    case org.apache.bcel.Constants.POP2:
      wcet = 2;
      break;
    // DUP = 89
    case org.apache.bcel.Constants.DUP:
      wcet = 1;
      break;
    // DUP_X1 = 90
    case org.apache.bcel.Constants.DUP_X1:
      wcet = 5;
      break;
    // DUP_X2 = 91
    case org.apache.bcel.Constants.DUP_X2:
      wcet = -1;
      break;
    // DUP2 = 92
    case org.apache.bcel.Constants.DUP2:
      wcet = 6;
      break;
    // DUP2_X1 = 93
    case org.apache.bcel.Constants.DUP2_X1:
      wcet = -1;
      break;
    // DUP2_X2 = 94
    case org.apache.bcel.Constants.DUP2_X2:
      wcet = -1;
      break;
    // SWAP = 95
    case org.apache.bcel.Constants.SWAP:
      wcet = -1;
      break;
    // IADD = 96
    case org.apache.bcel.Constants.IADD:
      wcet = 1;
      break;
    // LADD = 97
    case org.apache.bcel.Constants.LADD:
      wcet = -1;
      break;
    // FADD = 98
    case org.apache.bcel.Constants.FADD:
      wcet = -1;
      break;
    // DADD = 99
    case org.apache.bcel.Constants.DADD:
      wcet = -1;
      break;
    // ISUB = 100
    case org.apache.bcel.Constants.ISUB:
      wcet = 1;
      break;
    // LSUB = 101
    case org.apache.bcel.Constants.LSUB:
      wcet = -1;
      break;
    // FSUB = 102
    case org.apache.bcel.Constants.FSUB:
      wcet = -1;
      break;
    // DSUB = 103
    case org.apache.bcel.Constants.DSUB:
      wcet = -1;
      break;
    // IMUL = 104
    case org.apache.bcel.Constants.IMUL:
      wcet = 35;
      break;
    // LMUL = 105
    case org.apache.bcel.Constants.LMUL:
      wcet = -1;
      break;
    // FMUL = 106
    case org.apache.bcel.Constants.FMUL:
      wcet = -1;
      break;
    // DMUL = 107
    case org.apache.bcel.Constants.DMUL:
      wcet = -1;
      break;
    // IDIV = 108
    case org.apache.bcel.Constants.IDIV:
      wcet = -1;
      break;
    // LDIV = 109
    case org.apache.bcel.Constants.LDIV:
      wcet = -1;
      break;
    // FDIV = 110
    case org.apache.bcel.Constants.FDIV:
      wcet = -1;
      break;
    // DDIV = 111
    case org.apache.bcel.Constants.DDIV:
      wcet = -1;
      break;
    // IREM = 112
    case org.apache.bcel.Constants.IREM:
      wcet = -1;
      break;
    // LREM = 113
    case org.apache.bcel.Constants.LREM:
      wcet = -1;
      break;
    // FREM = 114
    case org.apache.bcel.Constants.FREM:
      wcet = -1;
      break;
    // DREM = 115
    case org.apache.bcel.Constants.DREM:
      wcet = -1;
      break;
    // INEG = 116
    case org.apache.bcel.Constants.INEG:
      wcet = 4;
      break;
    // LNEG = 117
    case org.apache.bcel.Constants.LNEG:
      wcet = -1;
      break;
    // FNEG = 118
    case org.apache.bcel.Constants.FNEG:
      wcet = -1;
      break;
    // DNEG = 119
    case org.apache.bcel.Constants.DNEG:
      wcet = -1;
      break;
    // ISHL = 120
    case org.apache.bcel.Constants.ISHL:
      wcet = 1;
      break;
    // LSHL = 121
    case org.apache.bcel.Constants.LSHL:
      wcet = -1;
      break;
    // ISHR = 122
    case org.apache.bcel.Constants.ISHR:
      wcet = 1;
      break;
    // LSHR = 123
    case org.apache.bcel.Constants.LSHR:
      wcet = -1;
      break;
    // IUSHR = 124
    case org.apache.bcel.Constants.IUSHR:
      wcet = 1;
      break;
    // LUSHR = 125
    case org.apache.bcel.Constants.LUSHR:
      wcet = -1;
      break;
    // IAND = 126
    case org.apache.bcel.Constants.IAND:
      wcet = 1;
      break;
    // LAND = 127
    case org.apache.bcel.Constants.LAND:
      wcet = -1;
      break;
    // IOR = 128
    case org.apache.bcel.Constants.IOR:
      wcet = 1;
      break;
    // LOR = 129
    case org.apache.bcel.Constants.LOR:
      wcet = -1;
      break;
    // IXOR = 130
    case org.apache.bcel.Constants.IXOR:
      wcet = 1;
      break;
    // LXOR = 131
    case org.apache.bcel.Constants.LXOR:
      wcet = -1;
      break;
    // IINC = 132
    case org.apache.bcel.Constants.IINC:
      wcet = 11;
      break;
    // I2L = 133
    case org.apache.bcel.Constants.I2L:
      wcet = -1;
      break;
    // I2F = 134
    case org.apache.bcel.Constants.I2F:
      wcet = -1;
      break;
    // I2D = 135
    case org.apache.bcel.Constants.I2D:
      wcet = -1;
      break;
    // L2I = 136
    case org.apache.bcel.Constants.L2I:
      wcet = 3;
      break;
    // L2F = 137
    case org.apache.bcel.Constants.L2F:
      wcet = -1;
      break;
    // L2D = 138
    case org.apache.bcel.Constants.L2D:
      wcet = -1;
      break;
    // F2I = 139
    case org.apache.bcel.Constants.F2I:
      wcet = -1;
      break;
    // F2L = 140
    case org.apache.bcel.Constants.F2L:
      wcet = -1;
      break;
    // F2D = 141
    case org.apache.bcel.Constants.F2D:
      wcet = -1;
      break;
    // D2I = 142
    case org.apache.bcel.Constants.D2I:
      wcet = -1;
      break;
    // D2L = 143
    case org.apache.bcel.Constants.D2L:
      wcet = -1;
      break;
    // D2F = 144
    case org.apache.bcel.Constants.D2F:
      wcet = -1;
      break;
    // I2B = 145
    case org.apache.bcel.Constants.I2B:
      wcet = -1;
      break;
    // INT2BYTE = 145 // Old notion
    // case org.apache.bcel.Constants.INT2BYTE : wcet = -1; break;
    // I2C = 146
    case org.apache.bcel.Constants.I2C:
      wcet = 2;
      break;
    // INT2CHAR = 146 // Old notion
    // case org.apache.bcel.Constants.INT2CHAR : wcet = -1; break;
    // I2S = 147
    case org.apache.bcel.Constants.I2S:
      wcet = -1;
      break;
    // INT2SHORT = 147 // Old notion
    // case org.apache.bcel.Constants.INT2SHORT : wcet = -1; break;
    // LCMP = 148
    case org.apache.bcel.Constants.LCMP:
      wcet = -1;
      break;
    // FCMPL = 149
    case org.apache.bcel.Constants.FCMPL:
      wcet = -1;
      break;
    // FCMPG = 150
    case org.apache.bcel.Constants.FCMPG:
      wcet = -1;
      break;
    // DCMPL = 151
    case org.apache.bcel.Constants.DCMPL:
      wcet = -1;
      break;
    // DCMPG = 152
    case org.apache.bcel.Constants.DCMPG:
      wcet = -1;
      break;
    // IFEQ = 153
    case org.apache.bcel.Constants.IFEQ:
      wcet = 4;
      break;
    // IFNE = 154
    case org.apache.bcel.Constants.IFNE:
      wcet = 4;
      break;
    // IFLT = 155
    case org.apache.bcel.Constants.IFLT:
      wcet = 4;
      break;
    // IFGE = 156
    case org.apache.bcel.Constants.IFGE:
      wcet = 4;
      break;
    // IFGT = 157
    case org.apache.bcel.Constants.IFGT:
      wcet = 4;
      break;
    // IFLE = 158
    case org.apache.bcel.Constants.IFLE:
      wcet = 4;
      break;
    // IF_ICMPEQ = 159
    case org.apache.bcel.Constants.IF_ICMPEQ:
      wcet = 4;
      break;
    // IF_ICMPNE = 160
    case org.apache.bcel.Constants.IF_ICMPNE:
      wcet = 4;
      break;
    // IF_ICMPLT = 161
    case org.apache.bcel.Constants.IF_ICMPLT:
      wcet = 4;
      break;
    // IF_ICMPGE = 162
    case org.apache.bcel.Constants.IF_ICMPGE:
      wcet = 4;
      break;
    // IF_ICMPGT = 163
    case org.apache.bcel.Constants.IF_ICMPGT:
      wcet = 4;
      break;
    // IF_ICMPLE = 164
    case org.apache.bcel.Constants.IF_ICMPLE:
      wcet = 4;
      break;
    // IF_ACMPEQ = 165
    case org.apache.bcel.Constants.IF_ACMPEQ:
      wcet = 4;
      break;
    // IF_ACMPNE = 166
    case org.apache.bcel.Constants.IF_ACMPNE:
      wcet = 4;
      break;
    // GOTO = 167
    case org.apache.bcel.Constants.GOTO:
      wcet = 4;
      break;
    // JSR = 168
    case org.apache.bcel.Constants.JSR:
      wcet = -1;
      break;
    // RET = 169
    case org.apache.bcel.Constants.RET:
      wcet = -1; // TODO: Should this be 1?
      break;
    // TABLESWITCH = 170
    case org.apache.bcel.Constants.TABLESWITCH:
      wcet = -1;
      break;
    // LOOKUPSWITCH = 171
    case org.apache.bcel.Constants.LOOKUPSWITCH:
      wcet = -1;
      break;
    // IRETURN = 172
    case org.apache.bcel.Constants.IRETURN:
      wcet = 15;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (b >= 8) {
        wcet += b - 8;
      } else {
        wcet += 0;
      }
      break;
    // LRETURN = 173
    case org.apache.bcel.Constants.LRETURN:
      wcet = 15;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (b >= 9) {
        wcet += b - 9;
      } else {
        wcet += 0;
      }
      break;
    // FRETURN = 174
    case org.apache.bcel.Constants.FRETURN:
      wcet = 15;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (b >= 8) {
        wcet += b - 8;
      } else {
        wcet += 0;
      }
      break;
    // DRETURN = 175
    case org.apache.bcel.Constants.DRETURN:
      wcet = 15;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (b >= 9) {
        wcet += b - 9;
      } else {
        wcet += 0;
      }
      break;
    // ARETURN = 176
    case org.apache.bcel.Constants.ARETURN:
      wcet = 15;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (b >= 8) {
        wcet += b - 8;
      } else {
        wcet += 0;
      }
      break;
    // RETURN = 177
    // TODO: Check with ms why it is 1 in the DATE paper
    case org.apache.bcel.Constants.RETURN:
      wcet = 13;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (b >= 7) {
        wcet += b - 7;
      } else {
        wcet += 0;
      }
      break;
    // GETSTATIC = 178
    case org.apache.bcel.Constants.GETSTATIC:
      wcet = 4 + 2 * r;
      break;
    // PUTSTATIC = 179
    case org.apache.bcel.Constants.PUTSTATIC:
      wcet = 5 + r + w;
      break;
    // GETFIELD = 180
    case org.apache.bcel.Constants.GETFIELD:
      wcet = 10 + 2 * r;
      break;
    // PUTFIELD = 181
    case org.apache.bcel.Constants.PUTFIELD:
      wcet = 13 + r + w;
      break;
    // INVOKEVIRTUAL = 182
    case org.apache.bcel.Constants.INVOKEVIRTUAL:
      wcet = 78 + 2 * r;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      if (b >= 39) {
        wcet += b - 39;
      } else {
        wcet += 0;
      }
      break;
    // INVOKESPECIAL = 183
    case org.apache.bcel.Constants.INVOKESPECIAL:
      wcet = 58 + r;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      if (b >= 39) {
        wcet += b - 39;
      } else {
        wcet += 0;
      }
      break;
    // INVOKENONVIRTUAL = 183
    // case org.apache.bcel.Constants.INVOKENONVIRTUAL : wcet = -1; break;
    // INVOKESTATIC = 184
    case org.apache.bcel.Constants.INVOKESTATIC:
      wcet = 58 + r;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      if (b >= 39) {
        wcet += b - 39;
      } else {
        wcet += 0;
      }
      break;
    // INVOKEINTERFACE = 185
    case org.apache.bcel.Constants.INVOKEINTERFACE:
      wcet = 84 + 4 * r;
      if (r >= 7) {
        wcet += r - 3;
      } else {
        wcet += 4;
      }
      if (r >= 6) {
        wcet += r - 2;
      } else {
        wcet += 4;
      }
      if (b >= 39) {
        wcet += b - 39;
      } else {
        wcet += 0;
      }
      break;
    // NEW = 187
    case org.apache.bcel.Constants.NEW:
      wcet = -1;
      break;
    // NEWARRAY = 188
    case org.apache.bcel.Constants.NEWARRAY:
      wcet = 12 + w; // TODO: Time to clear array not included
      break;
    // ANEWARRAY = 189
    case org.apache.bcel.Constants.ANEWARRAY:
      wcet = -1;
      break;
    // ARRAYLENGTH = 190
    case org.apache.bcel.Constants.ARRAYLENGTH:
      wcet = 2 + r;
      break;
    // ATHROW = 191
    case org.apache.bcel.Constants.ATHROW:
      wcet = -1;
      break;
    // CHECKCAST = 192
    case org.apache.bcel.Constants.CHECKCAST:
      wcet = -1;
      break;
    // INSTANCEOF = 193
    case org.apache.bcel.Constants.INSTANCEOF:
      wcet = -1;
      break;
    // MONITORENTER = 194
    case org.apache.bcel.Constants.MONITORENTER:
      wcet = 9;
      break;
    // MONITOREXIT = 195
    case org.apache.bcel.Constants.MONITOREXIT:
      wcet = 10;
      wcet = 11; // TODO: Which one to keep?
      break;
    // WIDE = 196
    case org.apache.bcel.Constants.WIDE:
      wcet = -1;
      break;
    // MULTIANEWARRAY = 197
    case org.apache.bcel.Constants.MULTIANEWARRAY:
      wcet = -1;
      break;
    // IFNULL = 198
    case org.apache.bcel.Constants.IFNULL:
      wcet = 4;
      break;
    // IFNONNULL = 199
    case org.apache.bcel.Constants.IFNONNULL:
      wcet = 4;
      break;
    // GOTO_W = 200
    case org.apache.bcel.Constants.GOTO_W:
      wcet = -1;
      break;
    // JSR_W = 201
    case org.apache.bcel.Constants.JSR_W:
      wcet = -1;
      break;
    default:
      wcet = -1;
      break;
    }
    // TODO: Add the JOP speciffic codes?
    return wcet;
  }

  /**
   * Check to see if there is a valid WCET count for the instruction.
   * 
   * @param opcode
   * @return true if there is a valid wcet value
   */
  static boolean wcetAvailable(int opcode) {
    if (getCycles(opcode, false, 0) == WCETNOTAVAILABLE)
      return false;
    else
      return true;
  }

  /**
   * Method load time on invoke or return if there is a cache miss (see pMiss).
   * 
   * @see ms thesis p 232
   */
  public static int calculateB(int n) {
    int b = -1;
    if (n == -1) {
      System.err.println("n not set!");
      System.exit(-1);
    } else {
      b = 2 + (n + 1) * a;
    }
    return b;
  }

}

// BCEL overrides

/**
 * Extends org.apache.bcel.verifier.structurals. Frame just to get access to the
 * _this field, which the the operandWalker method in MethodInfo uses.
 */
class FrameFrame extends Frame {

  public FrameFrame(int maxLocals, int maxStack) {
    super(maxLocals, maxStack);
  }

  public FrameFrame(LocalVariables locals, OperandStack stack) {
    super(locals, stack);
  }

  void setThis(UninitializedObjectType uot) {
    _this = uot;
  }

  UninitializedObjectType getThis() {
    return _this;
  }
}

/**
 * BCEL throws an exception for the util.Dbg class because it overloads a field.
 * The choice (as described in the BCEL method comment for around line 2551 in
 * org.apache.bcel.verifier.structurals.InstConstraintVisitor) is to comment out
 * this check and recompile BCEL jar. Insted of recompiling BCEL the choice is
 * to override the methods, which is ok? as we are not using BCEL for bytecode
 * verification purposes (using Sun Javac).
 */
// TODO: Can this extension be avoided (ie. why did BCEL not like the
// overloaded Dbg field).
class AnInstConstraintVisitor extends InstConstraintVisitor {
  public void visitAALOAD(AALOAD o) {
  }

  public void visitAASTORE(AASTORE o) {
  }

  public void visitACONST_NULL(ACONST_NULL o) {
  }

  public void visitALOAD(ALOAD o) {
  }

  public void visitANEWARRAY(ANEWARRAY o) {
  }

  public void visitARETURN(ARETURN o) {
  }

  public void visitARRAYLENGTH(ARRAYLENGTH o) {
  }

  public void visitASTORE(ASTORE o) {
  }

  public void visitATHROW(ATHROW o) {
  }

  public void visitBALOAD(BALOAD o) {
  }

  public void visitBASTORE(BASTORE o) {
  }

  public void visitBIPUSH(BIPUSH o) {
  }

  public void visitBREAKPOINT(BREAKPOINT o) {
  }

  public void visitCALOAD(CALOAD o) {
  }

  public void visitCASTORE(CASTORE o) {
  }

  public void visitCHECKCAST(CHECKCAST o) {
  }

  public void visitCPInstruction(CPInstruction o) {
  }

  public void visitD2F(D2F o) {
  }

  public void visitD2I(D2I o) {
  }

  public void visitD2L(D2L o) {
  }

  public void visitDADD(DADD o) {
  }

  public void visitDALOAD(DALOAD o) {
  }

  public void visitDASTORE(DASTORE o) {
  }

  public void visitDCMPG(DCMPG o) {
  }

  public void visitDCMPL(DCMPL o) {
  }

  public void visitDCONST(DCONST o) {
  }

  public void visitDDIV(DDIV o) {
  }

  public void visitDLOAD(DLOAD o) {
  }

  public void visitDMUL(DMUL o) {
  }

  public void visitDNEG(DNEG o) {
  }

  public void visitDREM(DREM o) {
  }

  public void visitDRETURN(DRETURN o) {
  }

  public void visitDSTORE(DSTORE o) {
  }

  public void visitDSUB(DSUB o) {
  }

  public void visitDUP_X1(DUP_X1 o) {
  }

  public void visitDUP_X2(DUP_X2 o) {
  }

  public void visitDUP(DUP o) {
  }

  public void visitDUP2_X1(DUP2_X1 o) {
  }

  public void visitDUP2_X2(DUP2_X2 o) {
  }

  public void visitDUP2(DUP2 o) {
  }

  public void visitF2D(F2D o) {
  }

  public void visitF2I(F2I o) {
  }

  public void visitF2L(F2L o) {
  }

  public void visitFADD(FADD o) {
  }

  public void visitFALOAD(FALOAD o) {
  }

  public void visitFASTORE(FASTORE o) {
  }

  public void visitFCMPG(FCMPG o) {
  }

  public void visitFCMPL(FCMPL o) {
  }

  public void visitFCONST(FCONST o) {
  }

  public void visitFDIV(FDIV o) {
  }

  public void visitFieldInstruction(FieldInstruction o) {
  }

  public void visitFLOAD(FLOAD o) {
  }

  public void visitFMUL(FMUL o) {
  }

  public void visitFNEG(FNEG o) {
  }

  public void visitFREM(FREM o) {
  }

  public void visitFRETURN(FRETURN o) {
  }

  public void visitFSTORE(FSTORE o) {
  }

  public void visitFSUB(FSUB o) {
  }

  public void visitGETFIELD(GETFIELD o) {
  }

  public void visitGETSTATIC(GETSTATIC o) {
  }

  public void visitGOTO_W(GOTO_W o) {
  }

  public void visitGOTO(GOTO o) {
  }

  public void visitI2B(I2B o) {
  }

  public void visitI2C(I2C o) {
  }

  public void visitI2D(I2D o) {
  }

  public void visitI2F(I2F o) {
  }

  public void visitI2L(I2L o) {
  }

  public void visitI2S(I2S o) {
  }

  public void visitIADD(IADD o) {
  }

  public void visitIALOAD(IALOAD o) {
  }

  public void visitIAND(IAND o) {
  }

  public void visitIASTORE(IASTORE o) {
  }

  public void visitICONST(ICONST o) {
  }

  public void visitIDIV(IDIV o) {
  }

  public void visitIF_ACMPEQ(IF_ACMPEQ o) {
  }

  public void visitIF_ACMPNE(IF_ACMPNE o) {
  }

  public void visitIF_ICMPEQ(IF_ICMPEQ o) {
  }

  public void visitIF_ICMPGE(IF_ICMPGE o) {
  }

  public void visitIF_ICMPGT(IF_ICMPGT o) {
  }

  public void visitIF_ICMPLE(IF_ICMPLE o) {
  }

  public void visitIF_ICMPLT(IF_ICMPLT o) {
  }

  public void visitIF_ICMPNE(IF_ICMPNE o) {
  }

  public void visitIFEQ(IFEQ o) {
  }

  public void visitIFGE(IFGE o) {
  }

  public void visitIFGT(IFGT o) {
  }

  public void visitIFLE(IFLE o) {
  }

  public void visitIFLT(IFLT o) {
  }

  public void visitIFNE(IFNE o) {
  }

  public void visitIFNONNULL(IFNONNULL o) {
  }

  public void visitIFNULL(IFNULL o) {
  }

  public void visitIINC(IINC o) {
  }

  public void visitILOAD(ILOAD o) {
  }

  public void visitIMPDEP1(IMPDEP1 o) {
  }

  public void visitIMPDEP2(IMPDEP2 o) {
  }

  public void visitIMUL(IMUL o) {
  }

  public void visitINEG(INEG o) {
  }

  public void visitINSTANCEOF(INSTANCEOF o) {
  }

  public void visitInvokeInstruction(InvokeInstruction o) {
  }

  public void visitINVOKEINTERFACE(INVOKEINTERFACE o) {
  }

  public void visitINVOKESPECIAL(INVOKESPECIAL o) {
  }

  public void visitINVOKESTATIC(INVOKESTATIC o) {
  }

  public void visitINVOKEVIRTUAL(INVOKEVIRTUAL o) {
  }

  public void visitIOR(IOR o) {
  }

  public void visitIREM(IREM o) {
  }

  public void visitIRETURN(IRETURN o) {
  }

  public void visitISHL(ISHL o) {
  }

  public void visitISHR(ISHR o) {
  }

  public void visitISTORE(ISTORE o) {
  }

  public void visitISUB(ISUB o) {
  }

  public void visitIUSHR(IUSHR o) {
  }

  public void visitIXOR(IXOR o) {
  }

  public void visitJSR_W(JSR_W o) {
  }

  public void visitJSR(JSR o) {
  }

  public void visitL2D(L2D o) {
  }

  public void visitL2F(L2F o) {
  }

  public void visitL2I(L2I o) {
  }

  public void visitLADD(LADD o) {
  }

  public void visitLALOAD(LALOAD o) {
  }

  public void visitLAND(LAND o) {
  }

  public void visitLASTORE(LASTORE o) {
  }

  public void visitLCMP(LCMP o) {
  }

  public void visitLCONST(LCONST o) {
  }

  public void visitLDC_W(LDC_W o) {
  }

  public void visitLDC(LDC o) {
  }

  public void visitLDC2_W(LDC2_W o) {
  }

  public void visitLDIV(LDIV o) {
  }

  public void visitLLOAD(LLOAD o) {
  }

  public void visitLMUL(LMUL o) {
  }

  public void visitLNEG(LNEG o) {
  }

  public void visitLoadClass(LoadClass o) {
  }

  public void visitLoadInstruction(LoadInstruction o) {
  }

  public void visitLocalVariableInstruction(LocalVariableInstruction o) {
  }

  public void visitLOOKUPSWITCH(LOOKUPSWITCH o) {
  }

  public void visitLOR(LOR o) {
  }

  public void visitLREM(LREM o) {
  }

  public void visitLRETURN(LRETURN o) {
  }

  public void visitLSHL(LSHL o) {
  }

  public void visitLSHR(LSHR o) {
  }

  public void visitLSTORE(LSTORE o) {
  }

  public void visitLSUB(LSUB o) {
  }

  public void visitLUSHR(LUSHR o) {
  }

  public void visitLXOR(LXOR o) {
  }

  public void visitMONITORENTER(MONITORENTER o) {
  }

  public void visitMONITOREXIT(MONITOREXIT o) {
  }

  public void visitMULTIANEWARRAY(MULTIANEWARRAY o) {
  }

  public void visitNEW(NEW o) {
  }

  public void visitNEWARRAY(NEWARRAY o) {
  }

  public void visitNOP(NOP o) {
  }

  public void visitPOP(POP o) {
  }

  public void visitPOP2(POP2 o) {
  }

  public void visitPUTFIELD(PUTFIELD o) {
  }

  public void visitPUTSTATIC(PUTSTATIC o) {
  }

  public void visitRET(RET o) {
  }

  public void visitRETURN(RETURN o) {
  }

  public void visitReturnInstruction(ReturnInstruction o) {
  }

  public void visitSALOAD(SALOAD o) {
  }

  public void visitSASTORE(SASTORE o) {
  }

  public void visitSIPUSH(SIPUSH o) {
  }

  public void visitStackConsumer(StackConsumer o) {
  }

  public void visitStackInstruction(StackInstruction o) {
  }

  public void visitStackProducer(StackProducer o) {
  }

  public void visitStoreInstruction(StoreInstruction o) {
  }

  public void visitSWAP(SWAP o) {
  }

  public void visitTABLESWITCH(TABLESWITCH o) {
  }
}

// We may need this later in controlFlowMethod to simulate the basic blocks
// // TODO: Do we even need the controlflowgraph for this?
// cfg = new ControlFlowGraph(mg);
// // InstructionContext as key for inFrame
// HashMap inFrames = new HashMap();
// HashMap outFrames = new HashMap();
//
// // Build the initial frame situation for this method.
// FrameFrame fStart = new FrameFrame(mg.getMaxLocals(), mg.getMaxStack());
// if (!mg.isStatic()) {
// if (mg.getName().equals(Constants.CONSTRUCTOR_NAME)) {
// fStart.setThis(new UninitializedObjectType(new ObjectType(jc
// .getClassName())));
// fStart.getLocals().set(0, fStart.getThis());
// } else {
// fStart.setThis(null);
// fStart.getLocals().set(0, new ObjectType(jc.getClassName()));
// }
// }
// Type[] argtypes = mg.getArgumentTypes();
// int twoslotoffset = 0;
// for (int j = 0; j < argtypes.length; j++) {
// if (argtypes[j] == Type.SHORT || argtypes[j] == Type.BYTE
// || argtypes[j] == Type.CHAR || argtypes[j] == Type.BOOLEAN) {
// argtypes[j] = Type.INT;
// }
// fStart.getLocals().set(twoslotoffset + j + (mg.isStatic() ? 0 : 1),
// argtypes[j]);
// if (argtypes[j].getSize() == 2) {
// twoslotoffset++;
// fStart.getLocals().set(twoslotoffset + j + (mg.isStatic() ? 0 : 1),
// Type.UNKNOWN);
// }
// }
//
// // if (method.getName().equalsIgnoreCase("sort")) {
// // System.out.println(method.getCode().toString());
// //
// // }
//
// InstructionContext start = cfg.contextOf(mg.getInstructionList()
// .getStart());
// // don't need to compare for first frame
// inFrames.put(start, fStart);
//
// boolean fbool = start.execute(fStart, new ArrayList(), icv, ev);
// Frame fout = start.getOutFrame(new ArrayList());
// outFrames.put(start, fout);
// start.setTag(start.getTag() + 1);
// // int posnow = start.getInstruction().getPosition();
//
// Vector ics = new Vector(); // Type: InstructionContext
// Vector ecs = new Vector(); // Type: ArrayList (of
// // InstructionContext)
//
// ics.add(start);
// ecs.add(new ArrayList());
// int loopcnt = 1;
// // LOOP!
// while (!ics.isEmpty()) {
// loopcnt++;
// InstructionContext u;
// ArrayList ec;
// u = (InstructionContext) ics.get(0);
// // TODO: Would it be better to call wcet here instead of in the TAG
// // count
// // loop?
// // System.out.println(u.toString());
// ec = (ArrayList) ecs.get(0);
// ics.remove(0);
// ecs.remove(0);
// ArrayList oldchain = (ArrayList) (ec.clone());
// ArrayList newchain = (ArrayList) (ec.clone());
// newchain.add(u);
//
// if ((u.getInstruction().getInstruction()) instanceof RET) {
// // We can only follow _one_ successor, the one after the
// // JSR that was recently executed.
// RET ret = (RET) (u.getInstruction().getInstruction());
// ReturnaddressType t = (ReturnaddressType) u.getOutFrame(oldchain)
// .getLocals().get(ret.getIndex());
// InstructionContext theSuccessor = cfg.contextOf(t.getTarget());
//
// // Sanity check
// InstructionContext lastJSR = null;
// int skip_jsr = 0;
// for (int ss = oldchain.size() - 1; ss >= 0; ss--) {
// if (skip_jsr < 0) {
// throw new AssertionViolatedException(
// "More RET than JSR in execution chain?!");
// }
// if (((InstructionContext) oldchain.get(ss)).getInstruction()
// .getInstruction() instanceof JsrInstruction) {
// if (skip_jsr == 0) {
// lastJSR = (InstructionContext) oldchain.get(ss);
// break;
// } else {
// skip_jsr--;
// }
// }
// if (((InstructionContext) oldchain.get(ss)).getInstruction()
// .getInstruction() instanceof RET) {
// skip_jsr++;
// }
// }
// if (lastJSR == null) {
// throw new AssertionViolatedException(
// "RET without a JSR before in ExecutionChain?! EC: '" + oldchain
// + "'.");
// }
// JsrInstruction jsr = (JsrInstruction) (lastJSR.getInstruction()
// .getInstruction());
// if (theSuccessor != (cfg.contextOf(jsr.physicalSuccessor()))) {
// throw new AssertionViolatedException("RET '" + u.getInstruction()
// + "' info inconsistent: jump back to '" + theSuccessor
// + "' or '" + cfg.contextOf(jsr.physicalSuccessor()) + "'?");
// }
//
// if (theSuccessor.execute(u.getOutFrame(oldchain), newchain, icv, ev)) {
// ics.add(theSuccessor);
// ecs.add((ArrayList) newchain.clone());
// }
// // inFrames.put(theSuccessor,u.getOutFrame(oldchain));
// theSuccessor.setTag(theSuccessor.getTag() + 1);
// // osa[theSuccessor.getInstruction().getPosition()].add(fStart
// // .getStack().getClone());
// // lva[theSuccessor.getInstruction().getPosition()].add(fStart
// // .getLocals().getClone());
// Frame prevf = (Frame) inFrames.put(theSuccessor, u
// .getOutFrame(oldchain));
// Frame newf = theSuccessor.getOutFrame(newchain);
// Frame prevof = (Frame) outFrames.put(theSuccessor, newf);
//
// } else {// "not a ret"
// // Normal successors. Add them to the queue of successors.
// // TODO: Does u get executed?
// InstructionContext[] succs = u.getSuccessors();
//
// // System.out.println("suss#:" + succs.length);
// for (int s = 0; s < succs.length; s++) {
// InstructionContext v = succs[s];
// // System.out.println(v.toString());
// if (v.execute(u.getOutFrame(oldchain), newchain, icv, ev)) {
// ics.add(v);
// ecs.add((ArrayList) newchain.clone());
// }
// v.setTag(v.getTag() + 1);
// Frame prevf = (Frame) inFrames.put(v, u.getOutFrame(oldchain));
// Frame newf = v.getOutFrame(newchain);
// Frame prevof = (Frame) outFrames.put(v, newf);
// }
// }// end "not a ret"
//
// // Exception Handlers. Add them to the queue of successors.
// // [subroutines are never protected; mandated by JustIce]
// ExceptionHandler[] exc_hds = u.getExceptionHandlers();
// for (int s = 0; s < exc_hds.length; s++) {
// InstructionContext v = cfg.contextOf(exc_hds[s].getHandlerStart());
// Frame f = new Frame(u.getOutFrame(oldchain).getLocals(),
// new OperandStack(u.getOutFrame(oldchain).getStack().maxStack(),
// (exc_hds[s].getExceptionType() == null ? Type.THROWABLE
// : exc_hds[s].getExceptionType())));
//
// if (v.execute(f, new ArrayList(), icv, ev)) {
// ics.add(v);
// ecs.add(new ArrayList());
// }
// v.setTag(v.getTag() + 1);
// Frame prevf = (Frame) inFrames.put(v, f);
// Frame newf = v.getOutFrame(new ArrayList());
// Frame prevof = (Frame) outFrames.put(v, newf);
//
// }
// }// while (!ics.isEmpty()) END
//
// // Check that all instruction have been simulated
// do {
// InstructionContext ic = cfg.contextOf(ih);
// if (ic.getTag() == 0) {
// System.err
// .println("Instruction " + ic.toString() + " not simulated.");
// System.exit(-1);
// }
// // TODO: Can it handle direct loops back
// if (ih.getInstruction() instanceof BranchInstruction) {
// int target = ((BranchInstruction) ih.getInstruction()).getTarget()
// .getPosition();
// InstructionHandle btarget = ((BranchInstruction) ih.getInstruction())
// .getTarget();
// // check and possibly create a new bb starting at the target
// createBasicBlock(btarget);
// InstructionHandle ihnext = ih.getNext();
// // check if the next instruction was the target and if not see if a
// // new bb is to be created
// // TODO: Could it be true?
// if (!ihnext.equals(btarget)) {
// createBasicBlock(ihnext);
// }
//
// }
//
// } while ((ih = ih.getNext()) != null);

// Some utilitilities
class WU{
  /**
   * Inserts spaces in front of a string.
   * @param len the desired total length
   * @param val the string
   * @return the prepadded string
   */
  public static String prepad(String val, int len){
    StringBuffer sb = new StringBuffer();
    for(int i=len;i>val.length();i--){
      sb.append(" ");
    }
    sb.append(val);
    return sb.toString();
  }

  /**
   * Inserts spaces behind a string.
   * @param len the desired total length
   * @param val the string
   * @return the prepadded string
   */
  public static String postpad(String val, int len){
    StringBuffer sb = new StringBuffer();
    sb.append(val);
    for(int i=len;i>val.length();i--){
        sb.append(" ");
    }
    return sb.toString();
  }

}