Advertisement
Guest User

VirtualMachine.cpp

a guest
Apr 25th, 2011
705
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.06 KB | None | 0 0
  1. /******************************************************************************
  2. Filename: VirtualMachine.cpp
  3. By: Matthew **** and Ronald ****
  4. Created: 04/11/2011
  5. Last Modified: 04/25/2011
  6. Description: This cpp code creates and executes our VirtualMachine class
  7. ******************************************************************************/
  8.  
  9. #include <cstdlib>  
  10. #include <iostream>
  11. #include <fstream>
  12. #include <string>
  13. #include <vector>
  14. #include <sstream>
  15. #include "VirtualMachine.h"
  16. using namespace std;
  17.  
  18. // Begin Member Functions //
  19.  
  20. VirtualMachine::VirtualMachine()
  21. {
  22.     for (int i=0;i<MEM_SIZE;i++) // construct memory vector
  23.     {
  24.         mem.push_back(0);
  25.     }
  26.     for (int i=0;i<REG_FILE_SIZE;i++) // construct register vector
  27.     {
  28.         r.push_back(0);
  29.     }
  30.     this->pc=0;
  31.     this->sr=0;
  32.     this->clock=0;
  33.     this->base=0;
  34.     this->sp=MEM_SIZE;
  35.     fstream infile;
  36.     infile.open("prog.o", ios::in);
  37.     if (!infile.is_open())
  38.     {
  39.         cout << "prog.o failed to open.\n";
  40.         exit(1);
  41.     }
  42.     getline(infile, this->line);
  43.  
  44.     int temp;
  45.     int iterator=0;
  46.  
  47.     while (!infile.eof())
  48.     {
  49.         istringstream str(line.c_str()); //convert to c-string
  50.         temp=0;
  51.         str >> temp;
  52.         mem[iterator]=temp; // insert value into memory vector, filling it with instructions.
  53.         iterator++;
  54.         this->limit=iterator;
  55.         getline(infile, this->line);
  56.     }
  57.  
  58.  
  59.  
  60.     infile.close();
  61.     Execute(); // construction finished, begin execution.
  62. }
  63.  
  64. // sign extender
  65. int VirtualMachine::signExtend(int i)
  66. {
  67.     unsigned bits=16; // extend to 16 bits
  68.     int extended;      // output
  69.     int const mask = 32768; // mask
  70.     i = i & ((1U << bits) - 1);
  71.     extended = (i ^ mask) - mask;
  72.     //cout << extended;
  73.     return extended;
  74. }
  75.  
  76. // Set SR bits to 0 or 1
  77. void VirtualMachine::setV(int i)
  78. {
  79.     i=i<<4;
  80.     sr = sr&15; // mask to clear the V location to 0;
  81.     sr = sr+i;  // insert new V value into sr.
  82. }
  83. void VirtualMachine::setL(int i) // set less
  84. {
  85.     i=i<<3;
  86.     sr = sr&23; // mask to clear the current L
  87.     sr = sr+i;
  88. }
  89. void VirtualMachine::setE(int i)
  90. {
  91.     i=i<<2;
  92.     sr = sr&27; // clear current E
  93.     sr = sr+i;
  94. } //
  95. void VirtualMachine::setG(int i)
  96. {
  97.     i=i<<1;
  98.     sr = sr&29; // clear current G
  99.     sr = sr+i;
  100. }
  101. void VirtualMachine::setC(int i)
  102. {
  103.     i=i<<0;
  104.     sr = sr&30; // clear current C
  105.     sr = sr+i;
  106. }
  107.  
  108. // Get SR bits, return 1 if given bit was active
  109. int VirtualMachine::getV()
  110. {
  111.     int j = sr&16; // mask to isolate bit
  112.     if (j==16)
  113.     {
  114.         return 1;
  115.     }
  116.     else
  117.     {
  118.         return 0;
  119.     }
  120. }
  121. int VirtualMachine::getL()
  122. {
  123.     int j = sr&8; // mask to isolate bit
  124.     if (j==8)
  125.     {
  126.         return 1;
  127.     }
  128.     else
  129.     {
  130.         return 0;
  131.     }
  132. }
  133. int VirtualMachine::getE()
  134. {
  135.     int j = sr&4; // mask to isolate bit
  136.     if (j==4)
  137.     {
  138.         return 1;
  139.     }
  140.     else
  141.     {
  142.         return 0;
  143.     }
  144. }
  145. int VirtualMachine::getG()
  146. {
  147.     int j = sr&2; // mask to isolate bit
  148.     if (j==2)
  149.     {
  150.         return 1;
  151.     }
  152.     else
  153.     {
  154.         return 0;
  155.     }
  156. }
  157. int VirtualMachine::getC()
  158. {
  159.     int j = sr&1; // mask to isolate bit
  160.     if (j==1)
  161.     {
  162.         return 1;
  163.     }
  164.     else
  165.     {
  166.         return 0;
  167.     }
  168. }
  169.  
  170. bool VirtualMachine::checkOverflow(int a, int b)
  171. {
  172.     if (a+b>=65536)
  173.     {
  174.         return true;
  175.     }
  176.     else
  177.     {
  178.         return false;
  179.     }
  180. }
  181. bool VirtualMachine::checkOverflow3(int a, int b, int c)
  182. {
  183.     if (a+b+c>=65536)
  184.     {
  185.         return true;
  186.     }
  187.     else
  188.     {
  189.         return false;
  190.     }
  191. }
  192. bool VirtualMachine::checkOverflow1(int a)
  193. {
  194.     if (a>=65536)
  195.     {
  196.         return true;
  197.     }
  198.     else
  199.     {
  200.         return false;
  201.     }
  202. }
  203.  
  204. // Begin Processing of Instructions
  205. void VirtualMachine::Execute()
  206. {
  207.     instruction ins;
  208.     int constant, addr, imm, carry, rs, rd, opcode;
  209.  
  210.     while(true) // MUST CHANGE to INFINITE LOOP
  211.     {
  212.         ir = mem[pc]; // Set the current instruction to be processed.
  213.         ins.i = ir; // for parsing with format classes
  214.         pc++; // pc always gets incremented.
  215.         carry = getC(); // carry is always set each operation
  216.  
  217.         // gather opcode, imm, rd, rs, constant, and addr for processing.
  218.         opcode = ins.f1.OP;
  219.         imm = ins.f1.I;
  220.         rd = ins.f1.RD;
  221.         rs = ins.f1.RS;
  222.         constant = ins.f3.CONST;
  223.         addr = ins.f2.ADDR;
  224.  
  225.         // **** TEST PURPOSES, remove later. *****
  226.         cout << "opcode: " << opcode << " rd: " << rd << " rs: " << rs << " constant: " << constant << " address: " << addr << " r0 " << r[0] <<  " r1 " << r[1] <<  " r2 " << r[2] <<  " r3 " << r[3] << endl;
  227.        
  228.         // end test
  229.  
  230.  
  231.         if (constant < 0)
  232.         {
  233.             constant = signExtend(constant);
  234.         }
  235.         else
  236.         {}
  237.  
  238.  
  239.         if (opcode==0)
  240.         {  
  241.             if (imm==0) // load RD ADDR
  242.             {
  243.                 r[rd] = mem[addr]; // load contents of mem[address] into r[rd]
  244.             }
  245.             else // loadi RD CONST
  246.             {
  247.                 r[rd] = constant; // load direct value into r[rd]
  248.             }
  249.         }
  250.  
  251.  
  252.         else if (opcode==1) //store
  253.         {
  254.             mem[addr] = r[rd];
  255.             clock=clock+4;
  256.         }
  257.  
  258.         else if (opcode==2)
  259.         {   clock++;
  260.  
  261.         if (imm==0) // add RD RS
  262.         {
  263.             if (checkOverflow(r[rd], r[rs])==true)
  264.             {
  265.                 setC(1); // set carry if overflowed
  266.                 r[rd] = r[rd] + r[rs]; //add
  267.             }
  268.             else
  269.             {
  270.                 setC(0);
  271.                 r[rd] = r[rd] + r[rs]; //add
  272.             }
  273.         }
  274.         else
  275.         {
  276.             if (checkOverflow(r[rd], constant)==true)
  277.             {
  278.                 setC(1); // set carry if overflowed
  279.                 r[rd] = r[rd] + constant;
  280.             }
  281.             else
  282.             {
  283.                 setC(0);
  284.                 r[rd] = r[rd] + constant;
  285.             }
  286.         }
  287.         }
  288.  
  289.         else if (opcode==3)
  290.         {
  291.             clock++;
  292.             if (imm==0) // addc RD RS
  293.             {
  294.                 if (checkOverflow3(r[rd], r[rs], carry)==true)
  295.                 {
  296.                     setC(1); // set carry if overflowed
  297.                     r[rd] = r[rd] + r[rs] + carry; //add
  298.                 }
  299.                 else
  300.                 {
  301.                     setC(0);
  302.                     r[rd] = r[rd] + r[rs] + carry; //add
  303.                 }
  304.  
  305.             }
  306.             else
  307.             {  
  308.                 if (checkOverflow3(r[rd], constant, carry)==true)
  309.                 {
  310.                     setC(1); // set carry if overflowed
  311.                     r[rd] = r[rd] + constant + carry; //add
  312.                 }
  313.                 else
  314.                 {
  315.                     setC(0);
  316.                     r[rd] = r[rd] + constant + carry; //add
  317.                 }      
  318.             }
  319.  
  320.         }
  321.  
  322.  
  323.  
  324.         else if (opcode==4)
  325.         {
  326.             if (imm==0)
  327.             {
  328.                 if(checkOverflow(rd, rs)==true)
  329.                 {
  330.                     setC(1);
  331.                     r[rd] = r[rd] - r[rs];
  332.                 }
  333.                 else
  334.                 {
  335.                     setC(0);
  336.                     r[rd] = r[rd] - r[rs];
  337.                 }
  338.                 clock++;
  339.                
  340.             }
  341.             else
  342.             {
  343.                 if(checkOverflow(rd, rs)==true)
  344.                 {
  345.                     setC(1);
  346.                     r[rd] = r[rd] - constant;
  347.                 }
  348.                 else
  349.                 {
  350.                     setC(0);
  351.                     r[rd] = r[rd] - constant;
  352.                 }
  353.                 clock++;   
  354.             }
  355.         }
  356.  
  357.         else if (opcode==5)
  358.         {
  359.             if (imm==0)
  360.             {
  361.                 if(checkOverflow(rd, rs)==true)
  362.                 {
  363.                 setC(1);
  364.                 r[rd] = r[rd] - r[rs] - carry;
  365.                 }
  366.                 else
  367.                 {
  368.                     setC(0);
  369.                     r[rd] = r[rd] - r[rs] - carry;
  370.                 }
  371.                 clock++;
  372.                
  373.             }
  374.             else
  375.             {
  376.                 if(checkOverflow(rd, rs)==true)
  377.                 {
  378.                     setC(1);
  379.                     r[rd] = r[rd] - constant - carry;
  380.                 }
  381.                 else
  382.                 {
  383.                     setC(0);
  384.                     r[rd] = r[rd] - constant - carry;
  385.                 }
  386.                 clock++;
  387.                 }
  388.         }
  389.  
  390.  
  391.         else if (opcode==6)
  392.         {
  393.             if (imm==0)
  394.             {
  395.                 r[rd] = r[rd] & r[rs];
  396.                 clock++;
  397.             }
  398.             else
  399.             {
  400.                 r[rd] = r[rd] & constant;
  401.                 clock++;
  402.             }
  403.         }
  404.  
  405.         else if (opcode==7)
  406.         {
  407.             if (imm==0)
  408.             {
  409.                 r[rd] = r[rd] ^ r[rs];
  410.                 clock++;
  411.             }
  412.             else
  413.             {
  414.                 r[rd] = r[rd] ^ constant;
  415.                 clock++;
  416.             }
  417.         }
  418.  
  419.         else if (opcode==8) // negate value of r[rd]
  420.         {
  421.             r[rd] = r[rd] * -1;
  422.             clock++;
  423.         }
  424.  
  425.         else if (opcode==9) //shl
  426.         {
  427.             if (r[rd]>1)
  428.             {
  429.             r[rd] = r[rd] << 1;
  430.             }
  431.             else{}
  432.  
  433.             if(checkOverflow1(r[rd])==true)
  434.             {
  435.                 setC(1);
  436.             }
  437.             else
  438.             {
  439.                 setC(0);
  440.             }
  441.             clock++;
  442.         }
  443.  
  444.         else if (opcode==10) //shl
  445.         {
  446.             r[rd] = r[rd] << 1;
  447.             if(checkOverflow1(r[rd])==true)
  448.             {
  449.                 setC(1);
  450.             }
  451.             else
  452.             {
  453.                 setC(0);
  454.             }
  455.             signExtend(r[rd]);
  456.             clock++;
  457.         }
  458.  
  459.         else if (opcode==11)
  460.         {
  461.             r[rd] = r[rd] >> 1;
  462.             if(checkOverflow1(r[rd])==true)
  463.             {
  464.                 setC(1);
  465.             }
  466.             else
  467.             {
  468.                 setC(0);
  469.             }
  470.             clock++;
  471.         }
  472.        
  473.  
  474.         else if (opcode==12)
  475.         {
  476.             r[rd] = r[rd] >> 1;
  477.             if(checkOverflow1(r[rd])==true)
  478.             {
  479.                 setC(1);
  480.             }
  481.             else
  482.             {
  483.                 setC(0);
  484.             }
  485.             signExtend(r[rd]);
  486.             clock++;
  487.         }
  488.  
  489.         else if (opcode==13) // set bits in sr based on comparing registers
  490.         {
  491.             if (imm==0)
  492.             {
  493.                 if (r[rd] < r[rs])
  494.                 {
  495.                     setL(1); // set less bit and reset rest.
  496.                     setE(0);
  497.                     setG(0);
  498.                     clock++;
  499.                 }
  500.                 else if (r[rd] == r[rs])
  501.                 {
  502.                     setL(0);
  503.                     setE(1); // set equal bit and reset rest
  504.                     setG(0);
  505.                     clock++;
  506.                 }
  507.                 else if (r[rd] > r[rs])
  508.                 {
  509.                     setL(0);
  510.                     setE(0);
  511.                     setG(1); // set greater bit and reset rest
  512.                     clock++;
  513.                 }
  514.             }
  515.             else
  516.             {
  517.                 if (r[rd] < constant)
  518.                 {
  519.                     setL(1); // set less bit and reset rest.
  520.                     setE(0);
  521.                     setG(0);
  522.                     clock++;
  523.                 }
  524.                 else if (r[rd] == constant)
  525.                 {
  526.                     setL(0);
  527.                     setE(1); // set equal bit and reset rest
  528.                     setG(0);
  529.                     clock++;
  530.                 }
  531.                 else if (r[rd] > constant)
  532.                 {
  533.                     setL(0);
  534.                     setE(0);
  535.                     setG(1); // set greater bit and reset rest
  536.                     clock++;
  537.                 }
  538.                 else {}
  539.  
  540.             }
  541.         }
  542.  
  543.         else if (opcode==14) //save sr into the given register
  544.         {
  545.             r[rd] = this->sr;
  546.             clock++;
  547.         }
  548.  
  549.         else if (opcode==15) //putstat (sr=rd) sets the status register=given register
  550.         {
  551.             this->sr = r[rd];
  552.             clock++;
  553.         }
  554.         else if (opcode==16) //jump
  555.         {
  556.             this->pc = addr;
  557.             clock++;
  558.         }
  559.         else if (opcode==17) //jump if less
  560.         {
  561.             int j = getL(); // returns 1 if LESS was set
  562.             if (j==1)
  563.             {
  564.                 pc = addr;
  565.                 clock++;
  566.             }
  567.             else{}
  568.  
  569.         }      
  570.         else if (opcode==18) //jump if equal
  571.         {
  572.             int j = getE(); // returns 1 if EQUAL was set
  573.             if (j==1)
  574.             {
  575.                 pc = addr;
  576.                 clock++;
  577.             }          
  578.         }      
  579.         else if (opcode==19) //jump if greater
  580.         {
  581.             int j = getG(); // returns 1 if GREATER was set
  582.             if (j==1)
  583.             {
  584.                 pc = addr;
  585.                 clock++;
  586.             }
  587.             else{}
  588.         }      
  589.         else if (opcode==20) //CALL pc=addr .... push vm status (rd, sr, r0,r1,r2,r3)
  590.         {
  591.  
  592.             if(sp<limit+6)
  593.             {
  594.                 cout << "ERROR STACK FULL!!";
  595.                 cout << endl << "Cannot perform CALL operation, press Enter to continue";
  596.                 cin.get();
  597.  
  598.             }
  599.             else //push VM status onto stack
  600.             {
  601.                 mem[sp-1]=pc;
  602.                 mem[sp-2]=sr;
  603.                 mem[sp-3]=r[0];
  604.                 mem[sp-4]=r[1];
  605.                 mem[sp-5]=r[2];
  606.                 mem[sp-6]=r[3];
  607.                 this->sp=sp-6; // set new stack pointer
  608.                 clock=clock+4;
  609.                 pc=addr;
  610.             }  
  611.         }
  612.  
  613.         else if (opcode==21) // return
  614.         {
  615.             if (sp>=MEM_SIZE)
  616.             {
  617.                 // stack is empty, nothing to pop.
  618.             }
  619.             else
  620.             {
  621.                 // load values stored in memory to pc, sr, r0, r1, r2, r3
  622.                 pc=mem[sp+5];
  623.                 cout << pc<< endl;
  624.                 sr=mem[sp+4];
  625.                 r[0]=mem[sp+3];
  626.                 r[1]=mem[sp+2];
  627.                 r[2]=mem[sp+1];
  628.                 r[3]=mem[sp];
  629.  
  630.                 //pop used values off the stack
  631.                 mem[sp+5]=0;
  632.                 mem[sp+4]=0;
  633.                 mem[sp+3]=0;
  634.                 mem[sp+2]=0;
  635.                 mem[sp+1]=0;
  636.                 mem[sp]=0;
  637.  
  638.                 if(sp<MEM_SIZE-6)
  639.                 {
  640.                     sp=sp+6; // set new stack pointer
  641.                 }
  642.                 else
  643.                 {
  644.                     sp=MEM_SIZE;
  645.                 }
  646.             }
  647.  
  648.             clock=clock+4;
  649.         }  
  650.  
  651.         else if (opcode==22) //read new content of r[rd] from .in file
  652.         {
  653.             clock=clock+28;
  654.             fstream inputfile;
  655.             inputfile.open("prog.in", ios::in);
  656.             if (!inputfile.is_open())
  657.             {
  658.                 cout << "prog.in failed to open.\n";
  659.             }
  660.             else
  661.             {
  662.                 int temp;
  663.                 inputfile>>temp;
  664.                 r[rd]=temp; // insert new value into r[rd]
  665.                 inputfile.close();
  666.             }
  667.         }
  668.  
  669.  
  670.  
  671.  
  672.         else if (opcode==23) //write r[rd] into .out file
  673.         {
  674.             fstream outputfile;
  675.             outputfile.open("prog.out", ios::out);
  676.             if (!outputfile.is_open())
  677.             {
  678.                 cout << "could not create prog.o .\n";
  679.             }
  680.             else
  681.             {
  682.                 outputfile<<"Register Value: "<<r[rd]<<endl;
  683.                 outputfile<<"R0 Value: "<<r[0]<<endl;
  684.                 outputfile<<"R1 Value: "<<r[1]<<endl;
  685.                 outputfile<<"R2 Value: "<<r[2]<<endl;
  686.                 outputfile<<"R3 Value: "<<r[3]<<endl;
  687.                
  688.                 outputfile.close();
  689.             }
  690.             clock=clock+28;
  691.         }  
  692.  
  693.         else if (opcode==24)
  694.         {
  695.             clock++;
  696.  
  697.             //write final clock value when program halts
  698.             fstream outputfile;
  699.             outputfile.open("prog.out", ios::app); //append
  700.             if (!outputfile.is_open())
  701.             {
  702.                 cout << "could not create/open prog.o .\n";
  703.             }
  704.             else
  705.             {
  706.                 outputfile<<"Clock: "<<clock<<endl;
  707.                 outputfile.close();
  708.             }
  709.             //cin.get();
  710.             //cout<<"add 5: "<<mem[8];
  711.             cout << mem[33] << "   " << mem[34] << "  " << mem[35]<<endl;
  712.             cin.get(); // pause
  713.             exit(0);
  714.         }  
  715.         else if (opcode==25)
  716.         {
  717.             //noop
  718.             clock++;
  719.         }  
  720.  
  721.     }
  722.  
  723. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement