/******************************************************* analyzerAux.cpp CMSC-411 Spring 2004 Project2 Spencer Shimko, sshimko1 Created: 24 April 2004 Current: 24 April 2004 auxillary for analyze the effects and hazards when pipelineing a small set of the MIPS instruction set *********************************************************/ using namespace std; #include #include #include #include #include #include "analyzerAux.h" #include "Stages.h" /* * parse the input file * Params: input file to parse * Params: pointer to a linked list of instructions */ bool parseIFile ( const char * iFile, Instruction ** hD ) { char * fop; // op code string line; // operands char * operands; char * fop1; // operand 1 char * fop2; // operand 2 char * fop3; // operand 3 int addr; // instruction addresst // temporary string for conversion ostrstream s; // create instruction and redirect head->next struct Instruction *iP = (Instruction*) malloc(sizeof ( struct Instruction ) ); // open/test file ifstream sFile( iFile, ios::in ); // if file did not open properly display error and die if ( !sFile ){ return false; } addr = 0; // read in file while ( getline ( sFile, line ) ){ // reset operands fop = NULL; fop1 = NULL; fop2 = NULL; fop3 = NULL; operands = const_cast(line.c_str()); // extract opcode fop = strtok ( operands, " "); // convert them to a standard lower case for ( int index = 0; fop[index]; index++ ){ fop[index] = tolower ( fop[index] ); } fop1 = strtok ( NULL, "," ); // parse data transfer ops if ( ( ! strcmp (fop, "lw" ) ) || ( ! strcmp ( fop, "sw" ) ) ) { // replace any constants with unique indentifier s << addr; fop2 = s.str(); // if we have a sw swap the op1 and op2 // this makes looking for data hazards easier later if ( ! strcmp ( fop, "sw" ) ){ char * str = fop1; fop2 = fop1; fop1 = str; } // snag register as 3rd operand ingoring ( ) fop3 = strtok ( NULL, "(" ); fop3 = strtok ( NULL, ")" ); } else if ( ! strcmp ( fop, "lui" ) ) { // convert addr to string for place a unique place holder s << addr; fop3 = s.str(); fop2 = fop3; } // parse arithmetic/logical ops else { // every other operand is sperated by , and has 3 fop2 = strtok ( NULL, "," ); fop3 = strtok ( NULL, "\n" ); } remove_whitespace ( fop ); remove_whitespace ( fop1 ); remove_whitespace ( fop2 ); remove_whitespace ( fop3 ); // setup this instruction iP->op = fop; iP->op1 = fop1; iP->op2 = fop2; iP->op3 = fop3; iP->addr = addr; Instruction *nx = (Instruction*) malloc(sizeof ( struct Instruction ) ); nx->back = iP; iP->next = nx; Instruction *t = (Instruction*) malloc(sizeof ( struct Instruction ) ); t = iP; int c = 0; while ( t != NULL ){ cout << "back" << c << ": " << t->op << " " << t->op1 << " " << t->op2 << " " << t->op3 << endl; if ( t->back != NULL ) cout << "backback" << c << ": " << t->back->op << " " << t->back->op1 << " " << t->back->op2 << " " << t->back->op3 << endl; t = t->back; c++; } iP = iP->next; addr += 4; } while ( iP->back != NULL ){ iP = iP->back; cout << iP->op << " " << iP->op1 << " " << iP->op2 << " " << iP->op3 << endl; } *hD = iP; sFile.close(); return true; } /* * run the instruction sequence analysis * Params: pointer to a linked list of instructions */ Statistics analyze ( Instruction * iP ) { // initialize pipeline Stages *Pipeline = new Stages ( iP ); // clock tick and advance the pipeline while ( Pipeline->clockTick ( ) ){ } return Pipeline->getStats ( ); } /* * display results of analysis */ void displayData ( const Statistics & stats ) { cout << "Structural hazards" << endl; if ( sizeof(stats.sHaz) < 1 ){ cout << "NONE" << endl; } else { cout << stats.sHaz << endl; } cout << endl; cout << "Data hazards" << endl; if ( sizeof(stats.sHaz) < 1 ){ cout << "NONE" << endl; } else { cout << stats.sHaz << endl; } cout << endl; cout << "Total execution time of the program is: " << stats.time << "ns" << endl; } void remove_whitespace(char *s) { char *t = s; while(t) { while (isspace(*t)) ++t; *s = *t; if(*t==0)return; s++;t++; } }