/*
 * driver.java
 *
 * Copyright (c) 2004 Rutgers, The State University of New Jersey
 *
 * Daniel A. Jiménez
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL RUTGERS, THE STATE UNIVERSITY
 * OF NEW JERSEY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*
 * This program takes a stream of bytes representing branch traces on the
 * standard input, running a branch predictor simulator on them.
 */

import java.lang.*;
import java.io.*;

public class driver {

public static void main (String args[]) {
	int 	a, b, c, d, address;
	long	count = 0;
	boolean	taken;

	// make a branch predictor

	branch_predictor bp = new fpbnp (2048, 37, 8);

	// loop until break

	for (;;) {

		// get four bytes

		try {
                        a = System.in.read();
                        b = System.in.read();
                        c = System.in.read();
                        d = System.in.read();
                } catch (java.io.IOException e) {
			System.err.println ("error");
			return;
		}

		// break for end of file

		if (a == -1) break;
		if (d >= 128) {
			d -= 128;
			taken = true;
		} else {
			taken = false;
		}

		// assemble bytes into an address

		address = d;
		address = (address << 8) | c;
		address = (address << 8) | b;
		address = (address << 8) | a;
		address &= 0x7fffffff;

		// get a branch prediction

		branch_update u = bp.predict (address);

		// update the predictor

		bp.update_and_measure (u, taken);

		// one more branch

		count++;
		if (count % 1000000 == 0) {

			// print stats

			int mri = (int) (bp.miss_rate() * 100000);
			double mr = (double) mri / (double) 1000.0;
			System.out.print (benchmarks[(int)(count/1000000-1)]);
			System.out.print (": ");
			System.out.println (mr);
			bp.reset();
		}
	}
}

final static String benchmarks[] = {
"099.go      ",
"124.m88ksim ",
"129.compress",
"130.li      ",
"132.ijpeg   ",
"164.gzip    ",
"175.vpr     ",
"176.gcc     ",
"181.mcf     ",
"186.crafty  ",
"197.parser  ",
"252.eon     ",
"253.perlbmk ",
"254.gap     ",
"255.vortex  ",
"256.bzip2   ",
"300.twolf   " };

};
