Main Page   Compound List   File List   Compound Members   File Members  

execute.c

Go to the documentation of this file.
00001 /*
00002  Copyright (c) 1992-1993 The Regents of the University of California.
00003  All rights reserved.  See copyright.h for copyright notice and limitation 
00004  of liability and disclaimer of warranty provisions.
00005  */
00006 
00007 #include "copyright.h"
00008 
00009 #include <stdio.h>
00010 #include "instr.h"
00011 #include "encode.h"
00012 #include "int.h"
00013 
00014 #define FAST    0
00015 #define true    1
00016 #define false   0
00017 
00018 
00019 extern char mem[];
00020 extern int TRACE, Regtrace;
00021 
00022 /* Machine registers */
00023 int Reg[32];                    /* GPR's */
00024 int HI, LO;                     /* mul/div machine registers */
00025 
00026 /* statistics gathering places */
00027 int numjmpls;
00028 int arch1cycles;
00029 
00030 /* Condition-code calculations */
00031 #define  b31(z)         (((z) >>31 )&0x1)       /* extract bit 31 */
00032 
00033 /* code looks funny but is fast thanx to MIPS! */
00034 #define cc_add(rr, op1, op2)    \
00035         N = (rr < 0);   \
00036         Z = (rr == 0);  \
00037         C = ((unsigned) rr < (unsigned) op2);   \
00038         V = ((op1^op2) >= 0  &&  (op1^rr) < 0);
00039 
00040 #define cc_sub(rr, op1, op2)    \
00041         N = (rr < 0);   \
00042         Z = (rr == 0);  \
00043         V = b31((op1 & ~op2 & ~rr) | (~op1 & op2 & rr));        \
00044         C = ((unsigned) op1 < (unsigned) op2);
00045 
00046         /* C = b31((~op1 & op2) | (rr & (~op1 | op2))); /* */
00047 
00048 #define cc_logic(rr)    \
00049         N = (rr < 0);   \
00050         Z = (rr == 0);  \
00051         V = 0;  \
00052         C = 0;
00053 
00054 #define cc_mulscc(rr, op1, op2) \
00055         N = (rr < 0);   \
00056         Z = (rr == 0);  \
00057         V = b31((op1 & op2 & ~rr) | (~op1 & ~op2 & rr));        \
00058         C = b31((op1 & op2) | (~rr & (op1 | op2)));
00059 
00060 
00061 runprogram(startpc, argc, argv)
00062 int startpc, argc;
00063 char *argv[];
00064 {
00065     int aci, ai, j;
00066     register int instr, pc, xpc, npc;
00067     register int i;             /* temporary for local stuff */
00068     register int icount;
00069     extern char *strcpy();
00070 
00071     icount = 0;
00072     pc = startpc; npc = pc + 4;
00073     i = MEMSIZE - 1024 + memoffset;     /* Initial SP value */
00074     Reg[29] = i;                        /* Initialize SP  */
00075     /* setup argc and argv stuff (icky!) */
00076     store(i, argc);
00077     aci = i + 4;
00078     ai = aci + 32;
00079     for  ( j=0; j<argc; ++j )
00080     {
00081         strcpy((mem-memoffset)+ai, argv[j]);
00082         store(aci, ai);
00083         aci += 4;
00084         ai += strlen(argv[j]) + 1;
00085     }
00086 
00087 
00088     for  ( ; ; )
00089     {
00090         ++icount;
00091         xpc = pc; pc = npc; npc = pc + 4;
00092         instr = ifetch(xpc);
00093         Reg[0] = 0;     /* Force r0 = 0 */
00094 
00095         if  ( instr != 0 )      /* eliminate no-ops */
00096         {
00097         switch ( (instr>>26) & 0x0000003f)
00098         {
00099                 case I_SPECIAL:
00100                 {
00101                     switch ( instr & 0x0000003f )
00102                     {
00103 
00104                         case I_SLL:
00105                             Reg[rd(instr)] = Reg[rt(instr)] << shamt(instr);
00106                             break;
00107                         case I_SRL:
00108                             Reg[rd(instr)] = 
00109                                 (unsigned) Reg[rt(instr)] >> shamt(instr);
00110                             break;
00111                         case I_SRA:
00112                             Reg[rd(instr)] = Reg[rt(instr)] >> shamt(instr);
00113                             break;
00114                         case I_SLLV:
00115                             Reg[rd(instr)] = Reg[rt(instr)] << Reg[rs(instr)];
00116                             break;
00117                         case I_SRLV:
00118                             Reg[rd(instr)] = 
00119                                 (unsigned) Reg[rt(instr)] >> Reg[rs(instr)];
00120                             break;
00121                         case I_SRAV:
00122                             Reg[rd(instr)] = Reg[rt(instr)] >> Reg[rs(instr)];
00123                             break;
00124                         case I_JR:
00125                             npc = Reg[rs(instr)];
00126                             break;
00127                         case I_JALR:
00128                             npc = Reg[rs(instr)];
00129                             Reg[rd(instr)] = xpc + 8;
00130                             break;
00131 
00132                         case I_SYSCALL: system_trap(); break;
00133                         case I_BREAK: system_break(); break;
00134 
00135                         case I_MFHI: Reg[rd(instr)] = HI; break;
00136                         case I_MTHI: HI = Reg[rs(instr)]; break;
00137                         case I_MFLO: Reg[rd(instr)] = LO; break;
00138                         case I_MTLO: LO = Reg[rs(instr)]; break;
00139 
00140                         case I_MULT:
00141                             {
00142                                 int t1, t2;
00143                                 int t1l, t1h, t2l, t2h;
00144                                 int neg;
00145 
00146                                 t1 = Reg[rs(instr)];
00147                                 t2 = Reg[rt(instr)];
00148                                 neg = 0;
00149                                 if ( t1 < 0 ) { t1 = -t1 ; neg = !neg; }
00150                                 if ( t2 < 0 ) { t2 = -t2 ; neg = !neg; }
00151                                 LO = t1 * t2;
00152                                 t1l = t1 & 0xffff;
00153                                 t1h = (t1 >> 16) & 0xffff;
00154                                 t2l = t2 & 0xffff;
00155                                 t2h = (t2 >> 16) & 0xffff;
00156                                 HI = t1h*t2h+((t1h*t2l)>>16)+((t2h*t1l)>>16);
00157                                 if ( neg )
00158                                 {
00159                                         LO = ~LO; HI = ~HI; LO = LO + 1;
00160                                         if  ( LO == 0 )  HI = HI + 1;
00161                                 }
00162                             }
00163                             break;
00164                         case I_MULTU:
00165                             {
00166                                 int t1, t2;
00167                                 int t1l, t1h, t2l, t2h;
00168 
00169                                 t1 = Reg[rs(instr)];
00170                                 t2 = Reg[rt(instr)];
00171                                 t1l = t1 & 0xffff;
00172                                 t1h = (t1 >> 16) & 0xffff;
00173                                 t2l = t2 & 0xffff;
00174                                 t2h = (t2 >> 16) & 0xffff;
00175                                 LO = t1*t2;
00176                                 HI = t1h*t2h+((t1h*t2l)>>16)+((t2h*t1l)>>16);
00177                             }break;
00178                         case I_DIV:
00179                             LO = Reg[rs(instr)] / Reg[rt(instr)];
00180                             HI = Reg[rs(instr)] % Reg[rt(instr)];
00181                             break;
00182                         case I_DIVU:
00183                             LO =
00184                             (unsigned)Reg[rs(instr)] / (unsigned)Reg[rt(instr)];
00185                             HI =
00186                             (unsigned)Reg[rs(instr)] % (unsigned)Reg[rt(instr)];
00187                             break;
00188 
00189                         case I_ADD:
00190                         case I_ADDU:
00191                             Reg[rd(instr)] = Reg[rs(instr)] + Reg[rt(instr)];
00192                             break;
00193                         case I_SUB:
00194                         case I_SUBU:
00195                             Reg[rd(instr)] = Reg[rs(instr)] - Reg[rt(instr)];
00196                             break;
00197                         case I_AND:
00198                             Reg[rd(instr)] = Reg[rs(instr)] & Reg[rt(instr)];
00199                             break;
00200                         case I_OR:
00201                             Reg[rd(instr)] = Reg[rs(instr)] | Reg[rt(instr)];
00202                             break;
00203                         case I_XOR:
00204                             Reg[rd(instr)] = Reg[rs(instr)] ^ Reg[rt(instr)];
00205                             break;
00206                         case I_NOR:
00207                             Reg[rd(instr)] = ~(Reg[rs(instr)] | Reg[rt(instr)]);
00208                             break;
00209 
00210                         case I_SLT:
00211                             Reg[rd(instr)] = (Reg[rs(instr)] < Reg[rt(instr)]);
00212                             break;
00213                         case I_SLTU:
00214                             Reg[rd(instr)] =
00215                                 ((unsigned) Reg[rs(instr)] 
00216                                         < (unsigned) Reg[rt(instr)]);
00217                             break;
00218                         default: u(); break;
00219                     }
00220                 } break;
00221 
00222                 case I_BCOND:
00223                 {
00224                     switch ( rt(instr) )        /* this field encodes the op */
00225                     {
00226                         case I_BLTZ:
00227                                 if ( Reg[rs(instr)] < 0 )
00228                                         npc = xpc + 4 + (immed(instr)<<2);
00229                                 break;
00230                         case I_BGEZ:
00231                                 if ( Reg[rs(instr)] >= 0 )
00232                                         npc = xpc + 4 + (immed(instr)<<2);
00233                                 break;
00234 
00235                         case I_BLTZAL:
00236                                 Reg[31] = xpc + 8;
00237                                 if ( Reg[rs(instr)] < 0 )
00238                                         npc = xpc + 4 + (immed(instr)<<2);
00239                                 break;
00240                         case I_BGEZAL:
00241                                 Reg[31] = xpc + 8;
00242                                 if ( Reg[rs(instr)] >= 0 )
00243                                         npc = xpc + 4 + (immed(instr)<<2);
00244                                 break;
00245                         default: u(); break;
00246                     }
00247                         
00248                 } break;
00249 
00250                 case I_J:
00251                         npc = (xpc & 0xf0000000) | ((instr & 0x03ffffff) << 2);
00252                         break;
00253                 case I_JAL:
00254                         Reg[31] = xpc + 8;
00255                         npc = (xpc & 0xf0000000) | ((instr & 0x03ffffff) << 2);
00256                         break;
00257                 case I_BEQ:
00258                         if  ( Reg[rs(instr)] == Reg[rt(instr)] )
00259                                 npc = xpc + 4 + (immed(instr) << 2);
00260                         break;
00261                 case I_BNE:
00262                         if  ( Reg[rs(instr)] != Reg[rt(instr)] )
00263                                 npc = xpc + 4 + (immed(instr) << 2);
00264                         break;
00265                 case I_BLEZ:
00266                         if  ( Reg[rs(instr)] <= 0 )
00267                                 npc = xpc + 4 + (immed(instr) << 2);
00268                         break;
00269                 case I_BGTZ:
00270                         if  ( Reg[rs(instr)] > 0 )
00271                                 npc = xpc + 4 + (immed(instr) << 2);
00272                         break;
00273                 case I_ADDI:
00274                         Reg[rt(instr)] = Reg[rs(instr)] + immed(instr);
00275                         break;
00276                 case I_ADDIU:
00277                         Reg[rt(instr)] = Reg[rs(instr)] + immed(instr);
00278                         break;
00279                 case I_SLTI:
00280                         Reg[rt(instr)] = (Reg[rs(instr)] < immed(instr));
00281                         break;
00282                 case I_SLTIU:
00283                         Reg[rt(instr)] =
00284                           ((unsigned) Reg[rs(instr)] < (unsigned) immed(instr));
00285                         break;
00286                 case I_ANDI:
00287                         Reg[rt(instr)] = Reg[rs(instr)] & immed(instr);
00288                         break;
00289                 case I_ORI:
00290                         Reg[rt(instr)] = Reg[rs(instr)] | immed(instr);
00291                         break;
00292                 case I_XORI:
00293                         Reg[rt(instr)] = Reg[rs(instr)] ^ immed(instr);
00294                         break;
00295                 case I_LUI:
00296                         Reg[rt(instr)] = instr << 16;
00297                         break;
00298 
00299                 case I_LB:
00300                         Reg[rt(instr)] = cfetch(Reg[rs(instr)] + immed(instr));
00301                         break;
00302                 case I_LH:
00303                         Reg[rt(instr)] = sfetch(Reg[rs(instr)] + immed(instr));
00304                         break;
00305                 case I_LWL:
00306                     i = Reg[rs(instr)] + immed(instr);
00307                     Reg[rt(instr)] &= (-1 >> 8*((-i) & 0x03));
00308                     Reg[rt(instr)] |= ((fetch(i & 0xfffffffc)) << 8*(i & 0x03));
00309                     break;
00310                 case I_LW:
00311                         Reg[rt(instr)] = fetch(Reg[rs(instr)] + immed(instr));
00312                         break;
00313                 case I_LBU:
00314                         Reg[rt(instr)] = ucfetch(Reg[rs(instr)] + immed(instr));
00315                         break;
00316                 case I_LHU:
00317                         Reg[rt(instr)] = usfetch(Reg[rs(instr)] + immed(instr));
00318                         break;
00319                 case I_LWR:
00320                     i = Reg[rs(instr)] + immed(instr);
00321                     Reg[rt(instr)] &= (-1 << 8*(i & 0x03));
00322                     if  ( (i & 0x03)== 0 )
00323                         Reg[rt(instr)] = 0;
00324                     Reg[rt(instr)] |= 
00325                         ((fetch(i & 0xfffffffc)) >> 8*((-i) & 0x03));
00326                     break;
00327 
00328                 case I_SB:
00329                         cstore(Reg[rs(instr)] + immed(instr), Reg[rt(instr)]);
00330                         break;
00331                 case I_SH:
00332                         sstore(Reg[rs(instr)] + immed(instr), Reg[rt(instr)]);
00333                         break;
00334                 case I_SWL:
00335                         fprintf(stderr, "sorry, no SWL yet.\n");
00336                         u();
00337                         break;
00338                 case I_SW:
00339                         store(Reg[rs(instr)] + immed(instr), Reg[rt(instr)]);
00340                         break;
00341 
00342                 case I_SWR:
00343                         fprintf(stderr, "sorry, no SWR yet.\n");
00344                         u();
00345                         break;
00346 
00347                 case I_LWC0: case I_LWC1:
00348                 case I_LWC2: case I_LWC3:
00349                 case I_SWC0: case I_SWC1:
00350                 case I_SWC2: case I_SWC3:
00351                 case I_COP0: case I_COP1:
00352                 case I_COP2: case I_COP3:
00353                         fprintf(stderr, "Sorry, no coprocessors.\n");
00354                         exit(2);
00355                         break;
00356 
00357                 default: u(); break;
00358         }
00359         }
00360 
00361 #ifdef DEBUG
00362 /*
00363 printf(" %d(%x) = %d(%x) op  %d(%x)\n", Reg[rd], Reg[rd], op1, op1, op2, op2);
00364 /* */
00365 #endif
00366 #if !FAST
00367         if  ( TRACE )
00368         {
00369             dump_ascii(instr, xpc); printf("\n"); /* */
00370             if  ( Regtrace )  dump_reg();
00371         }
00372 #endif
00373     }
00374 }
00375 
00376 
00377 
00378 u()                             /* unimplemented */
00379 {
00380         printf("Unimplemented Instruction\n"); exit(2);
00381 }
00382 
00383 ny()
00384 {
00385         printf("This opcode not implemeted yet.\n"); exit(2);
00386 }
00387 
00388 
00389 /* debug aids */
00390 
00391 RS(i)
00392 int i;
00393 {
00394         return rs(i);
00395 }
00396 
00397 RT(i)
00398 int i;
00399 {
00400         return rt(i);
00401 }
00402 
00403 RD(i)
00404 int i;
00405 {
00406         return rd(i);
00407 }
00408 
00409 IM(i)
00410 int i;
00411 {
00412         return immed(i);
00413 }
00414 
00415 
00416 
00417 dump_reg()
00418 {
00419         int j;
00420 
00421         printf(" 0:"); for  ( j=0; j<8; ++j ) printf(" %08x", Reg[j]);
00422                 printf("\n");
00423         printf(" 8:"); for  ( ; j<16; ++j ) printf(" %08x", Reg[j]);
00424                 printf("\n");
00425         printf("16:"); for  ( ; j<24; ++j ) printf(" %08x", Reg[j]);
00426                 printf("\n");
00427         printf("24:"); for  ( ; j<32; ++j ) printf(" %08x", Reg[j]);
00428                 printf("\n");
00429 
00430 }
00431 
00432 
00433 
00434 /*
00435         0 -> 0
00436         1 -> 1
00437         2 -> 1
00438         3 -> 2
00439         4 -> 2
00440         5 -> 2
00441         6 -> 2
00442         7 -> 3
00443         8 -> 3
00444         9 -> 3  ...
00445         Treats all ints as unsigned numbers.
00446 */
00447 ilog2(i)
00448 int i;
00449 {
00450         int j, l;
00451 
00452         if  ( i == 0 )  return 0;
00453         j = 0;
00454         l = 1;
00455         if  ( (j=(i&0xffff0000)) != 0 ) { i = j; l += 16; }
00456         if  ( (j=(i&0xff00ff00)) != 0 ) { i = j; l += 8; }
00457         if  ( (j=(i&0xf0f0f0f0)) != 0 ) { i = j; l += 4; }
00458         if  ( (j=(i&0xcccccccc)) != 0 ) { i = j; l += 2; }
00459         if  ( (j=(i&0xaaaaaaaa)) != 0 ) { i = j; l += 1; }
00460         return l;
00461 }
00462 
00463 
00464 
00465 #define NH     32
00466 #define NNN     33
00467 
00468 static int hists[NH][NNN];
00469 int hoflo[NH], htotal[NH];
00470 
00471 void henters(n, hist)
00472 int n, hist;
00473 {
00474         if  ( 0 <= n  &&  n < NNN ) ++hists[hist][n]; else ++hoflo[hist];
00475         ++htotal[hist];
00476 }
00477 
00478 hprint()
00479 {
00480         int h, i;
00481         double I;
00482 
00483         for  ( h=0; h<=NH; ++h ) if  ( htotal[h] > 0 )
00484         {
00485                 printf("\nhisto %d:\n", h);
00486                 I = 0.0;
00487                 for  ( i=0; i<NNN; ++i )
00488                 {
00489                         I += hists[h][i];
00490                         printf("%d\t%d\t%5.2f%%\t%5.2f%%\n",
00491                                 i, hists[h][i],
00492                                 (double) 100*hists[h][i] / htotal[h],
00493                                 (double) 100*I/htotal[h]);
00494                 }
00495                 printf("oflo %d:\t%d/%d\t%5.2f%%\n", 
00496                         h, hoflo[h], htotal[h],
00497                         (double) 100*hoflo[h] / htotal[h]);
00498         }
00499 }
00500 
00501 int numadds=1, numsubs=1, numsuccesses, numcarries;
00502 int addtable[33][33];
00503 int subtable[33][33];
00504 
00505 char fmt[] = "%6d";
00506 char fmt2[] = "------";
00507 
00508 patable(tab)
00509 int tab[33][33];
00510 {
00511         int i, j;
00512 
00513         printf("  |");
00514         for  ( j=0; j<33; ++j )
00515                 printf(fmt, j);
00516         putchar('\n');
00517         printf("  |");
00518         for  ( j=0; j<33; ++j )
00519                 printf(fmt2);
00520         putchar('\n');
00521         for  ( i=0; i<33; ++i )
00522         {
00523                 printf("%2d|", i);
00524                 for  ( j=0; j<33; ++j )
00525                         printf(fmt, tab[i][j]);
00526                 putchar('\n');
00527         }
00528 }
00529 
00530 
00531 
00532 
00533 printstatistics()
00534 {
00535         /*
00536         printhist();
00537         /*
00538         printf("numjmpls = %d / %d = %5.2f%%\n",
00539                 numjmpls, arch1cycles, 100.0*numjmpls/arch1cycles);
00540         printf("numadds = %d, numsubs = %d, numcycles = %d, frac = %5.2f%%\n",
00541                 numadds, numsubs,
00542                 arch1cycles, (double) 100 * (numadds+numsubs) / arch1cycles);
00543         printf("numsuccesses = %d (%5.2f%%) numcarries = %d\n", 
00544                 numsuccesses, 100.0*numsuccesses/(numadds+numsubs), numcarries);
00545 
00546         /*
00547         hprint();
00548         printf("\nADD table:\n");patable(addtable);
00549         printf("\nSUB table:\n");patable(subtable);
00550         */
00551 }
00552 
00553 
00554 
00555 #define NNNN    (64)
00556 
00557 static int hist[NNNN];
00558 
00559 henter(n)
00560 int n;
00561 {
00562         if  ( 0 <= n  &&  n < NNNN )
00563                 ++hist[n];
00564 }
00565 
00566 printhist()
00567 {
00568         int i;
00569 
00570         for  ( i=0; i<NNNN; ++i )
00571                 printf("%d %d\n", i, hist[i]);
00572 }
00573 
00574 

Generated on Mon Feb 10 09:54:45 2003 for nachos by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002
The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees