00001
00002
00003
00004
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
00023 int Reg[32];
00024 int HI, LO;
00025
00026
00027 int numjmpls;
00028 int arch1cycles;
00029
00030
00031 #define b31(z) (((z) >>31 )&0x1)
00032
00033
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
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;
00068 register int icount;
00069 extern char *strcpy();
00070
00071 icount = 0;
00072 pc = startpc; npc = pc + 4;
00073 i = MEMSIZE - 1024 + memoffset;
00074 Reg[29] = i;
00075
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;
00094
00095 if ( instr != 0 )
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) )
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
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()
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
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
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
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
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
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
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