Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /******************************************************************************
- Filename: VirtualMachine.cpp
- By: Matthew **** and Ronald ****
- Created: 04/11/2011
- Last Modified: 04/25/2011
- Description: This cpp code creates and executes our VirtualMachine class
- ******************************************************************************/
- #include <cstdlib>
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- #include <sstream>
- #include "VirtualMachine.h"
- using namespace std;
- // Begin Member Functions //
- VirtualMachine::VirtualMachine()
- {
- for (int i=0;i<MEM_SIZE;i++) // construct memory vector
- {
- mem.push_back(0);
- }
- for (int i=0;i<REG_FILE_SIZE;i++) // construct register vector
- {
- r.push_back(0);
- }
- this->pc=0;
- this->sr=0;
- this->clock=0;
- this->base=0;
- this->sp=MEM_SIZE;
- fstream infile;
- infile.open("prog.o", ios::in);
- if (!infile.is_open())
- {
- cout << "prog.o failed to open.\n";
- exit(1);
- }
- getline(infile, this->line);
- int temp;
- int iterator=0;
- while (!infile.eof())
- {
- istringstream str(line.c_str()); //convert to c-string
- temp=0;
- str >> temp;
- mem[iterator]=temp; // insert value into memory vector, filling it with instructions.
- iterator++;
- this->limit=iterator;
- getline(infile, this->line);
- }
- infile.close();
- Execute(); // construction finished, begin execution.
- }
- // sign extender
- int VirtualMachine::signExtend(int i)
- {
- unsigned bits=16; // extend to 16 bits
- int extended; // output
- int const mask = 32768; // mask
- i = i & ((1U << bits) - 1);
- extended = (i ^ mask) - mask;
- //cout << extended;
- return extended;
- }
- // Set SR bits to 0 or 1
- void VirtualMachine::setV(int i)
- {
- i=i<<4;
- sr = sr&15; // mask to clear the V location to 0;
- sr = sr+i; // insert new V value into sr.
- }
- void VirtualMachine::setL(int i) // set less
- {
- i=i<<3;
- sr = sr&23; // mask to clear the current L
- sr = sr+i;
- }
- void VirtualMachine::setE(int i)
- {
- i=i<<2;
- sr = sr&27; // clear current E
- sr = sr+i;
- } //
- void VirtualMachine::setG(int i)
- {
- i=i<<1;
- sr = sr&29; // clear current G
- sr = sr+i;
- }
- void VirtualMachine::setC(int i)
- {
- i=i<<0;
- sr = sr&30; // clear current C
- sr = sr+i;
- }
- // Get SR bits, return 1 if given bit was active
- int VirtualMachine::getV()
- {
- int j = sr&16; // mask to isolate bit
- if (j==16)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- int VirtualMachine::getL()
- {
- int j = sr&8; // mask to isolate bit
- if (j==8)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- int VirtualMachine::getE()
- {
- int j = sr&4; // mask to isolate bit
- if (j==4)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- int VirtualMachine::getG()
- {
- int j = sr&2; // mask to isolate bit
- if (j==2)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- int VirtualMachine::getC()
- {
- int j = sr&1; // mask to isolate bit
- if (j==1)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- bool VirtualMachine::checkOverflow(int a, int b)
- {
- if (a+b>=65536)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- bool VirtualMachine::checkOverflow3(int a, int b, int c)
- {
- if (a+b+c>=65536)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- bool VirtualMachine::checkOverflow1(int a)
- {
- if (a>=65536)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- // Begin Processing of Instructions
- void VirtualMachine::Execute()
- {
- instruction ins;
- int constant, addr, imm, carry, rs, rd, opcode;
- while(true) // MUST CHANGE to INFINITE LOOP
- {
- ir = mem[pc]; // Set the current instruction to be processed.
- ins.i = ir; // for parsing with format classes
- pc++; // pc always gets incremented.
- carry = getC(); // carry is always set each operation
- // gather opcode, imm, rd, rs, constant, and addr for processing.
- opcode = ins.f1.OP;
- imm = ins.f1.I;
- rd = ins.f1.RD;
- rs = ins.f1.RS;
- constant = ins.f3.CONST;
- addr = ins.f2.ADDR;
- // **** TEST PURPOSES, remove later. *****
- cout << "opcode: " << opcode << " rd: " << rd << " rs: " << rs << " constant: " << constant << " address: " << addr << " r0 " << r[0] << " r1 " << r[1] << " r2 " << r[2] << " r3 " << r[3] << endl;
- // end test
- if (constant < 0)
- {
- constant = signExtend(constant);
- }
- else
- {}
- if (opcode==0)
- {
- if (imm==0) // load RD ADDR
- {
- r[rd] = mem[addr]; // load contents of mem[address] into r[rd]
- }
- else // loadi RD CONST
- {
- r[rd] = constant; // load direct value into r[rd]
- }
- }
- else if (opcode==1) //store
- {
- mem[addr] = r[rd];
- clock=clock+4;
- }
- else if (opcode==2)
- { clock++;
- if (imm==0) // add RD RS
- {
- if (checkOverflow(r[rd], r[rs])==true)
- {
- setC(1); // set carry if overflowed
- r[rd] = r[rd] + r[rs]; //add
- }
- else
- {
- setC(0);
- r[rd] = r[rd] + r[rs]; //add
- }
- }
- else
- {
- if (checkOverflow(r[rd], constant)==true)
- {
- setC(1); // set carry if overflowed
- r[rd] = r[rd] + constant;
- }
- else
- {
- setC(0);
- r[rd] = r[rd] + constant;
- }
- }
- }
- else if (opcode==3)
- {
- clock++;
- if (imm==0) // addc RD RS
- {
- if (checkOverflow3(r[rd], r[rs], carry)==true)
- {
- setC(1); // set carry if overflowed
- r[rd] = r[rd] + r[rs] + carry; //add
- }
- else
- {
- setC(0);
- r[rd] = r[rd] + r[rs] + carry; //add
- }
- }
- else
- {
- if (checkOverflow3(r[rd], constant, carry)==true)
- {
- setC(1); // set carry if overflowed
- r[rd] = r[rd] + constant + carry; //add
- }
- else
- {
- setC(0);
- r[rd] = r[rd] + constant + carry; //add
- }
- }
- }
- else if (opcode==4)
- {
- if (imm==0)
- {
- if(checkOverflow(rd, rs)==true)
- {
- setC(1);
- r[rd] = r[rd] - r[rs];
- }
- else
- {
- setC(0);
- r[rd] = r[rd] - r[rs];
- }
- clock++;
- }
- else
- {
- if(checkOverflow(rd, rs)==true)
- {
- setC(1);
- r[rd] = r[rd] - constant;
- }
- else
- {
- setC(0);
- r[rd] = r[rd] - constant;
- }
- clock++;
- }
- }
- else if (opcode==5)
- {
- if (imm==0)
- {
- if(checkOverflow(rd, rs)==true)
- {
- setC(1);
- r[rd] = r[rd] - r[rs] - carry;
- }
- else
- {
- setC(0);
- r[rd] = r[rd] - r[rs] - carry;
- }
- clock++;
- }
- else
- {
- if(checkOverflow(rd, rs)==true)
- {
- setC(1);
- r[rd] = r[rd] - constant - carry;
- }
- else
- {
- setC(0);
- r[rd] = r[rd] - constant - carry;
- }
- clock++;
- }
- }
- else if (opcode==6)
- {
- if (imm==0)
- {
- r[rd] = r[rd] & r[rs];
- clock++;
- }
- else
- {
- r[rd] = r[rd] & constant;
- clock++;
- }
- }
- else if (opcode==7)
- {
- if (imm==0)
- {
- r[rd] = r[rd] ^ r[rs];
- clock++;
- }
- else
- {
- r[rd] = r[rd] ^ constant;
- clock++;
- }
- }
- else if (opcode==8) // negate value of r[rd]
- {
- r[rd] = r[rd] * -1;
- clock++;
- }
- else if (opcode==9) //shl
- {
- if (r[rd]>1)
- {
- r[rd] = r[rd] << 1;
- }
- else{}
- if(checkOverflow1(r[rd])==true)
- {
- setC(1);
- }
- else
- {
- setC(0);
- }
- clock++;
- }
- else if (opcode==10) //shl
- {
- r[rd] = r[rd] << 1;
- if(checkOverflow1(r[rd])==true)
- {
- setC(1);
- }
- else
- {
- setC(0);
- }
- signExtend(r[rd]);
- clock++;
- }
- else if (opcode==11)
- {
- r[rd] = r[rd] >> 1;
- if(checkOverflow1(r[rd])==true)
- {
- setC(1);
- }
- else
- {
- setC(0);
- }
- clock++;
- }
- else if (opcode==12)
- {
- r[rd] = r[rd] >> 1;
- if(checkOverflow1(r[rd])==true)
- {
- setC(1);
- }
- else
- {
- setC(0);
- }
- signExtend(r[rd]);
- clock++;
- }
- else if (opcode==13) // set bits in sr based on comparing registers
- {
- if (imm==0)
- {
- if (r[rd] < r[rs])
- {
- setL(1); // set less bit and reset rest.
- setE(0);
- setG(0);
- clock++;
- }
- else if (r[rd] == r[rs])
- {
- setL(0);
- setE(1); // set equal bit and reset rest
- setG(0);
- clock++;
- }
- else if (r[rd] > r[rs])
- {
- setL(0);
- setE(0);
- setG(1); // set greater bit and reset rest
- clock++;
- }
- }
- else
- {
- if (r[rd] < constant)
- {
- setL(1); // set less bit and reset rest.
- setE(0);
- setG(0);
- clock++;
- }
- else if (r[rd] == constant)
- {
- setL(0);
- setE(1); // set equal bit and reset rest
- setG(0);
- clock++;
- }
- else if (r[rd] > constant)
- {
- setL(0);
- setE(0);
- setG(1); // set greater bit and reset rest
- clock++;
- }
- else {}
- }
- }
- else if (opcode==14) //save sr into the given register
- {
- r[rd] = this->sr;
- clock++;
- }
- else if (opcode==15) //putstat (sr=rd) sets the status register=given register
- {
- this->sr = r[rd];
- clock++;
- }
- else if (opcode==16) //jump
- {
- this->pc = addr;
- clock++;
- }
- else if (opcode==17) //jump if less
- {
- int j = getL(); // returns 1 if LESS was set
- if (j==1)
- {
- pc = addr;
- clock++;
- }
- else{}
- }
- else if (opcode==18) //jump if equal
- {
- int j = getE(); // returns 1 if EQUAL was set
- if (j==1)
- {
- pc = addr;
- clock++;
- }
- }
- else if (opcode==19) //jump if greater
- {
- int j = getG(); // returns 1 if GREATER was set
- if (j==1)
- {
- pc = addr;
- clock++;
- }
- else{}
- }
- else if (opcode==20) //CALL pc=addr .... push vm status (rd, sr, r0,r1,r2,r3)
- {
- if(sp<limit+6)
- {
- cout << "ERROR STACK FULL!!";
- cout << endl << "Cannot perform CALL operation, press Enter to continue";
- cin.get();
- }
- else //push VM status onto stack
- {
- mem[sp-1]=pc;
- mem[sp-2]=sr;
- mem[sp-3]=r[0];
- mem[sp-4]=r[1];
- mem[sp-5]=r[2];
- mem[sp-6]=r[3];
- this->sp=sp-6; // set new stack pointer
- clock=clock+4;
- pc=addr;
- }
- }
- else if (opcode==21) // return
- {
- if (sp>=MEM_SIZE)
- {
- // stack is empty, nothing to pop.
- }
- else
- {
- // load values stored in memory to pc, sr, r0, r1, r2, r3
- pc=mem[sp+5];
- cout << pc<< endl;
- sr=mem[sp+4];
- r[0]=mem[sp+3];
- r[1]=mem[sp+2];
- r[2]=mem[sp+1];
- r[3]=mem[sp];
- //pop used values off the stack
- mem[sp+5]=0;
- mem[sp+4]=0;
- mem[sp+3]=0;
- mem[sp+2]=0;
- mem[sp+1]=0;
- mem[sp]=0;
- if(sp<MEM_SIZE-6)
- {
- sp=sp+6; // set new stack pointer
- }
- else
- {
- sp=MEM_SIZE;
- }
- }
- clock=clock+4;
- }
- else if (opcode==22) //read new content of r[rd] from .in file
- {
- clock=clock+28;
- fstream inputfile;
- inputfile.open("prog.in", ios::in);
- if (!inputfile.is_open())
- {
- cout << "prog.in failed to open.\n";
- }
- else
- {
- int temp;
- inputfile>>temp;
- r[rd]=temp; // insert new value into r[rd]
- inputfile.close();
- }
- }
- else if (opcode==23) //write r[rd] into .out file
- {
- fstream outputfile;
- outputfile.open("prog.out", ios::out);
- if (!outputfile.is_open())
- {
- cout << "could not create prog.o .\n";
- }
- else
- {
- outputfile<<"Register Value: "<<r[rd]<<endl;
- outputfile<<"R0 Value: "<<r[0]<<endl;
- outputfile<<"R1 Value: "<<r[1]<<endl;
- outputfile<<"R2 Value: "<<r[2]<<endl;
- outputfile<<"R3 Value: "<<r[3]<<endl;
- outputfile.close();
- }
- clock=clock+28;
- }
- else if (opcode==24)
- {
- clock++;
- //write final clock value when program halts
- fstream outputfile;
- outputfile.open("prog.out", ios::app); //append
- if (!outputfile.is_open())
- {
- cout << "could not create/open prog.o .\n";
- }
- else
- {
- outputfile<<"Clock: "<<clock<<endl;
- outputfile.close();
- }
- //cin.get();
- //cout<<"add 5: "<<mem[8];
- cout << mem[33] << " " << mem[34] << " " << mem[35]<<endl;
- cin.get(); // pause
- exit(0);
- }
- else if (opcode==25)
- {
- //noop
- clock++;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement