// -------------------------------------------------------------------------- // // Instruction Set Simulator // Rafael Lopez -- Tony Givargis & Randy January // 07/20/00 // University of California Riverside // Department of Computer Science -- Embedded Systems // // -------------------------------------------------------------------------- #include #include #include "simm.h" int main(int argc, char* argv[]) { int size = -1; if( argc != 2 ){ cout << "Correct input is: simm \n"; return -1; } ifstream inFile( argv[ 1 ], ios::in ); while ( inFile ){ // This loop reads and decodes file size++; if ( (unsigned)size >= progsize ) { cout << "Unable to simulate: program is too large for simulator\n"; return -1; } program[size].OPCODE = decode( inFile, adrs, byte ); program[size].Rn = decode( inFile, adrs, byte ); program[size].Rm = decode( inFile, byte, mask ); } run_program( size ); inFile.close(); return 0; } // ----------------------------------------------------------------------- // // Read the file and decode bytes. fb will become OPCODE,Rn // sb will become Rm // // ----------------------------------------------------------------------- int decode ( ifstream & inFile, int num, int val ) { char bit; int CODE = 0; for ( int i = 0; i < num; i++ ){ inFile >> bit; if ( bit == '1' ){ CODE |= ( val >> i ); } } return CODE; } // ----------------------------------------------------------------------- // // Read the Instruction Set // // ----------------------------------------------------------------------- int run_program( int size ) { int pc = -1; int reg[ regs ] = {0}; int frequency[ 8 ] = {0}; while( ++pc < size ) { switch( program[pc].OPCODE ) { case MOV0: // ---- MOV Rn, direct reg[program[pc].Rn] = memory[program[pc].Rm]; frequency[ MOV0 ]++; break; case MOV1: // ----- MOV direct, Rn memory[program[pc].Rm] = reg[program[pc].Rn]; frequency[ MOV1 ]++; break; case MOV2: // ----- MOV @Rn, Rm memory[reg[program[pc].Rn]] = reg[program[pc].Rm >> 4]; frequency[ MOV2 ]++; break; case MOV3: // ----- MOV Rn, #immediate twos_complement( pc ); reg[program[pc].Rn] = program[pc].Rm; frequency[ MOV3 ]++; break; case ADD: // ----- ADD Rn, Rm reg[program[pc].Rn] += reg[program[pc].Rm >> 4]; frequency[ ADD ]++; break; case SUB: // ----- SUB Rn, Rm reg[program[pc].Rn] -= reg[program[pc].Rm >> 4]; frequency[ SUB ]++; break; case JZ: // ----- JZ Rn, relative twos_complement( pc ); frequency[ JZ ]++; if ( reg[program[pc].Rn] == 0 ){ pc += program[pc].Rm; break; } else break; default: cout << "ERROR: Unknown Instruction found in input file\n" << " at line: " << pc + 1 << endl; return -1; } } cout << "Result : " << reg[0] << endl; print_stats( frequency, size ); return 0; } // ------------------------------------------------------------------------- // // This function will take care of two's complement for numbers that are // passed in Rn and might be needed for computation by JZ, or MOV # // // ------------------------------------------------------------------------- void twos_complement( int pc ) { if ( program[pc].Rm & mask ) // only for negative numbers program[pc].Rm = ((~(char)program[pc].Rm + 1 ) * -1 ); } // ------------------------------------------------------------------------- // // Print statistics // // ------------------------------------------------------------------------- void print_stats( int frequency[], int size ) { int total = 0; int i,j; const char Opcode [7][17] = { // Instruction Set Supported "MOV Rn, direct ", "MOV direct, Rn ", "MOV @Rn, Rm ", "MOV Rn, #imm ", "ADD Rn, Rm ", "SUB Rn, Rm ", "JZ Rn, Relative " }; const char Decode [7][5] = { // For printing purposes "MOV ","MOV ","MOV ","MOV ","ADD ","SUB ","JZ " }; cout << "\nThis is your program: \n"; for ( i = 0; i < size; i++ ) // Decode user's file and { // output the program for ( j = 0; j < 4; j++ ) { cout << Decode[ program[ i ].OPCODE ][ j ]; } switch ( program[ i ].OPCODE ) // Display input program { case MOV0: case JZ: cout << "R" << program[ i ].Rn << ", " << program[ i ].Rm << endl; break; case MOV1: cout << program[ i ].Rm << ", R" << program[ i ].Rn << endl; break; case MOV2: cout << "@R" << program[ i ].Rn << ", R" << (program[ i ].Rm >> 4) << endl; break; case MOV3: cout << "R" << program[ i ].Rn << ", #" << program[ i ].Rm << endl; break; case ADD: case SUB: cout << "R" << program[ i ].Rn << ", R" << (program[ i ].Rm >> 4) << endl; break; default: cout << "Unknown Instruction" << endl; break; } } cout << "\nInstructions Executed : \n"; for ( i = 0; i < 7; i++ ) { total += frequency[ i ]; for ( j = 0; j < 16; j++ ) { cout << Opcode[ i ][ j ]; // print instructions } cout << frequency[ i ] << " Times\n"; } cout << "\nTotal Instructions : " << total << "\n\n"; cout << "Clock cycles required: " << total * cycles << "\n"; cout << "( 4 cycles per Instr )\n\n"; }