/* Copyright (c) 1996-1998 Swiss Federal Institute of Technology, Computer Engineering and Networks Laboratory. All rights reserved. Written by David Schweikert . For more documentation please visit http://www.tik.ee.ethz.ch/~gfa. */ import java.io.*; import java.util.*; public final class Tracer { final static int MAX_RECURSION = 20; final static String INDENT_STRING = " "; PrintStream output; Hashtable symbolsTable; boolean symbolicMode = false; int pc, pc1, pc2; // pc, pc-1, pc-2 int opCode, opCode1, opCode2; int rs, rs1, rs2; int insCount[]; // used to count the number of instructions in a "subroutine" int insCountTotal[]; boolean symbolicLevel[]; // which level (JAL/JR) is symbolic Stack symbolsStack; // used to write the end of a subroutine int recursionLevel=0; // subroutine recursion level boolean singleLine=false; // single line trick (subroutines with no further recursion) Tracer(String traceFilename) throws IOException { OutputStream o = new FileOutputStream(traceFilename); OutputStream ob = new BufferedOutputStream(o); output = new PrintStream(ob); } Tracer(String traceFilename, String symbolsFilename) throws IOException { this(traceFilename); symbolicMode = true; symbolsTable = new Hashtable(); new SymbolsReader(symbolsFilename, symbolsTable); insCount = new int[MAX_RECURSION]; insCountTotal = new int[MAX_RECURSION]; symbolicLevel = new boolean[MAX_RECURSION]; symbolsStack = new Stack(); } public void trace(int pc, Instruction instr, boolean verbose) { // pc and opCode history pc2 = pc1; pc1 = this.pc; this.pc = pc; opCode2 = opCode1; opCode1 = opCode; rs2 = rs1; rs1 = rs; if(instr!=null) { opCode = instr.opCode; rs = instr.rs; } symbolicTrace(); if (verbose) { output.print(toHexString(pc) + " "); output.println(instr.disassemble()); } } public void trace(String str) { if(singleLine) output.println(" {"); output.println("-------- " + str); singleLine=false; } void symbolicTrace() { // Increment instruction count for(int r=recursionLevel; r>=0; r--) insCountTotal[r]++; insCount[recursionLevel]++; String symbol; switch(opCode2) { case Instruction.OP_JR: if (rs2==31) { recursionLevel--; if (recursionLevel<0) recursionLevel=0; if (symbolicLevel[recursionLevel]) { symbolicLevel[recursionLevel]=false; try { symbol = (String) symbolsStack.pop(); } catch (EmptyStackException e) { symbol = ""; } if(singleLine) { output.println(" (" + insCount[recursionLevel+1] + "/" + insCountTotal[recursionLevel+1] + ")"); singleLine=false; } else { output.print(" "); for(int i=0; i "); for(int i=0; i=MAX_RECURSION) recursionLevel=MAX_RECURSION-1; for(int r=recursionLevel; r=MAX_RECURSION) recursionLevel=MAX_RECURSION-1; for(int r=recursionLevel; r>> (4*pos)) & 0xf; switch(masked) { case 0: str[7-pos]='0'; break; case 1: str[7-pos]='1'; break; case 2: str[7-pos]='2'; break; case 3: str[7-pos]='3'; break; case 4: str[7-pos]='4'; break; case 5: str[7-pos]='5'; break; case 6: str[7-pos]='6'; break; case 7: str[7-pos]='7'; break; case 8: str[7-pos]='8'; break; case 9: str[7-pos]='9'; break; case 10: str[7-pos]='a'; break; case 11: str[7-pos]='b'; break; case 12: str[7-pos]='c'; break; case 13: str[7-pos]='d'; break; case 14: str[7-pos]='e'; break; case 15: str[7-pos]='f'; break; } } return new String(str); } } // Local Variables: // c-basic-offset: 8 // End: