1 /* arithmetic.cc This is a part of SimuAlpha Version 2.2a 2 * Copyright (c) 1999,2000,2001, Kenji KISE 3 ***************************************************************/ 4 #include 5 #include 6 #include 7 #include 8 #include "define.h" 9 #include "code.h" 10 11 void mul128(DATA_TYPE a, DATA_TYPE b, DATA_TYPE *rh, DATA_TYPE *rl){ 12 DATA_TYPE ah, al, bh, bl; 13 DATA_TYPE x, y, z; 14 int carry=0; /* has a value of 0, 1 and 2 */ 15 16 ah = a >> 32; 17 al = a & 0xFFFFFFFF; 18 19 bh = b >> 32; 20 bl = b & 0xFFFFFFFF; 21 22 x = al*bl; 23 y = (al*bh << 32); 24 z = x + y; 25 if(z> 32) + (ah*bl >> 32) + carry; 33 } 34 35 36 DATA_TYPE zap(int byte_mask, DATA_TYPE ret){ 37 if(byte_mask & BIT0) ret &= ZAP0; 38 if(byte_mask & BIT1) ret &= ZAP1; 39 if(byte_mask & BIT2) ret &= ZAP2; 40 if(byte_mask & BIT3) ret &= ZAP3; 41 if(byte_mask & BIT4) ret &= ZAP4; 42 if(byte_mask & BIT5) ret &= ZAP5; 43 if(byte_mask & BIT6) ret &= ZAP6; 44 if(byte_mask & BIT7) ret &= ZAP7; 45 return ret; 46 } 47 48 /***** 49 * There are four instruction types; 50 * (1)PAL Code Type ; Code<31:26> Function_code<25:0> ; 51 * (2)Branch Type ; Code<31:26> Ra<25:21> Diff<20:0> ; 52 * (3)Memory Type ; Code<31:26> Ra<25:21> Rb<20:16> Diff<15:0> ; 53 * (4)Operation Type; Code<31:26> Ra<25:21> Rb<20:16> Function<15:5> Rc<4:0>; 54 *****/ 55 56 57 DATA_TYPE ex_cmov(int code, unsigned int func11, 58 DATA_TYPE Rav, DATA_TYPE Rbv, DATA_TYPE Rmv){ 59 DATA_TYPE Rcv=0; 60 61 switch(code){ 62 case 0x11: 63 switch(func11 & 0x7F) 64 { 65 case 0x24: /* __CMOVEQ; */ 66 if(Rav==0) Rcv = Rbv; else Rcv = Rmv; 67 break; 68 case 0x46: /* __CMOVGE; */ 69 if((long long)Rav>=0) Rcv = Rbv; else Rcv = Rmv; 70 break; 71 case 0x66: /* __CMOVGT; */ 72 if((long long)Rav>0) Rcv = Rbv; else Rcv = Rmv; 73 break; 74 case 0x16: /* __CMOVLBC; */ 75 if(!(Rav & 1)) Rcv = Rbv; else Rcv = Rmv; 76 break; 77 case 0x14: /* __CMOVLBS; */ 78 if(Rav & 1) Rcv = Rbv; else Rcv = Rmv; 79 break; 80 case 0x64: /*__CMOVLE; */ 81 if((long long)Rav<=0) Rcv = Rbv; else Rcv = Rmv; 82 break; 83 case 0x44: /*__CMOVLT; */ 84 if((long long)Rav<0) Rcv = Rbv; else Rcv = Rmv; 85 break; 86 case 0x26: /* __CMOVNE; */ 87 if(Rav!=0) Rcv = Rbv; else Rcv = Rmv; 88 break; 89 default: 90 cout << "Warning 0x11 CMOV Default\n"; 91 Rcv=0; 92 break; 93 } 94 break; 95 96 case 0x17: 97 { 98 double Fav=0.0, Fbv=0.0, Fcv=0.0, Fmv=0.0; 99 memcpy(&Fav, &Rav, 8); 100 memcpy(&Fbv, &Rbv, 8); 101 memcpy(&Fmv, &Rmv, 8); 102 103 switch(func11){ 104 case 0x02a:/*__FCMOVEQ; */ 105 if(Fav==0.0) Fcv=Fbv; else Fcv=Fmv; 106 break; 107 case 0x02b:/*__FCMOVNE; */ 108 if(Fav!=0.0) Fcv=Fbv; else Fcv=Fmv; 109 break; 110 default: 111 printf("Warning 0x17 Floating CMOV func11 0x%x\n",func11); 112 Fcv=0.0; 113 break; 114 } 115 116 memcpy(&Rcv, &Fcv, 8); 117 break; 118 } 119 } 120 return Rcv; 121 } 122 123 DATA_TYPE ex_arith(int code, unsigned int func11, 124 DATA_TYPE Rav, DATA_TYPE Rbv){ 125 DATA_TYPE Rcv=0; 126 DATA_TYPE tmp, tmp2, tmp3; 127 unsigned int byte_mask, byte_loc; 128 129 switch(code){ 130 case 0x10: 131 switch(func11 & 0x7F) 132 { 133 case 0x00: 134 Rcv = ((Rav + Rbv) & MASK32); 135 if(Rcv & BIT31) Rcv |= EXTND32; 136 break; 137 case 0x20: /* __ADDQ; */ 138 Rcv = Rav + Rbv; 139 break; 140 case 0x09: /* __SUBL; */ 141 Rcv = (Rav - Rbv) & MASK32; 142 if(Rcv & BIT31) Rcv |= EXTND32; 143 break; 144 case 0x29: /* __SUBQ; */ 145 Rcv = Rav - Rbv; 146 break; 147 case 0x2d: /* __CMPEQ; */ 148 Rcv = ((long long)Rav == (long long)Rbv); 149 break; 150 case 0x4d: /* __CMPLT; */ 151 Rcv = ((long long)Rav < (long long)Rbv); 152 break; 153 case 0x6d: /* __CMPLE; */ 154 Rcv = ((long long)Rav <= (long long)Rbv); 155 break; 156 case 0x3d: /* __CMPULE; */ 157 Rcv = (Rav <= Rbv); 158 break; 159 case 0x1d: /* __CMPULT; */ 160 Rcv = (Rav < Rbv); 161 break; 162 case 0x02: /* __S4ADDL; */ 163 Rcv = ((Rav << 2) + Rbv) & MASK32; 164 if(Rcv & BIT31) Rcv |= EXTND32; 165 break; 166 case 0x12: /* __S8ADDL; */ 167 Rcv = ((Rav << 3) + Rbv) & MASK32; 168 if(Rcv & BIT31) Rcv |= EXTND32; 169 break; 170 case 0x22: /* __S4ADDQ; */ 171 Rcv = (Rav << 2) + Rbv; 172 break; 173 case 0x32: /* __S8ADDQ; */ 174 Rcv = (Rav << 3) + Rbv; 175 break; 176 case 0x0b: /* __S4SUBL; */ 177 Rcv = ((Rav << 2) - Rbv) & MASK32; 178 if(Rcv & BIT31) Rcv |= EXTND32; 179 break; 180 case 0x1b: /* __S8SUBL; */ 181 Rcv = ((Rav << 3) - Rbv) & MASK32; 182 if(Rcv & BIT31) Rcv |= EXTND32; 183 break; 184 case 0x2b: /* __S4SUBQ; */ 185 Rcv = (Rav << 2) - Rbv; 186 break; 187 case 0x3b: /* __S8SUBQ; */ 188 Rcv = (Rav << 3) - Rbv; 189 break; 190 case 0x0f: /*__CMPBGE; */ 191 Rcv=0; 192 if((Rav & ~ZAP0) >= (Rbv & ~ZAP0)) Rcv |= BIT0; 193 if((Rav & ~ZAP1) >= (Rbv & ~ZAP1)) Rcv |= BIT1; 194 if((Rav & ~ZAP2) >= (Rbv & ~ZAP2)) Rcv |= BIT2; 195 if((Rav & ~ZAP3) >= (Rbv & ~ZAP3)) Rcv |= BIT3; 196 if((Rav & ~ZAP4) >= (Rbv & ~ZAP4)) Rcv |= BIT4; 197 if((Rav & ~ZAP5) >= (Rbv & ~ZAP5)) Rcv |= BIT5; 198 if((Rav & ~ZAP6) >= (Rbv & ~ZAP6)) Rcv |= BIT6; 199 if((Rav & ~ZAP7) >= (Rbv & ~ZAP7)) Rcv |= BIT7; 200 break; 201 202 case 0x40: printf("Not implemented addl/v\n"); Rcv=0; break; 203 case 0x60: printf("Not implemented addq/v\n"); Rcv=0; break; 204 case 0x49: printf("Not implemented subl/v\n"); Rcv=0; break; 205 case 0x69: printf("Not implemented subq/v\n"); Rcv=0; break; 206 207 default: 208 printf("Warning in 0x10 arithmetic.\n"); 209 Rcv=0; 210 } 211 break; 212 213 case 0x11: 214 switch(func11 & 0x7F) 215 { 216 case 0x00: /* __AND; */ 217 Rcv = Rav & Rbv; 218 break; 219 case 0x20: /* __BIS; */ 220 Rcv = Rav | Rbv; 221 break; 222 case 0x40: /* __XOR; */ 223 Rcv = Rav ^ Rbv; 224 break; 225 case 0x08: /* __BIC; */ 226 Rcv = Rav & ~Rbv; 227 break; 228 case 0x28: /* __ORNOT; */ 229 Rcv = Rav | ~Rbv; 230 break; 231 case 0x48: /* __EQV; */ 232 Rcv = Rav ^ ~Rbv; 233 break; 234 } 235 break; 236 237 case 0x13: 238 switch(func11 & 0x7F) 239 { 240 case 0x00: /*__MULL; */ 241 Rcv = (Rav*Rbv) & 0x00000000FFFFFFFFllu; 242 if(Rcv & BIT31) Rcv |= EXTND32; 243 break; 244 case 0x30: /*__UMULH; */ 245 mul128(Rav, Rbv, &tmp2, &tmp3); 246 Rcv = tmp2; 247 break; 248 case 0x20: /*__MULQ; */ 249 mul128(Rav, Rbv, &tmp2, &tmp3); 250 Rcv = tmp3; 251 break; 252 253 default: 254 printf("Warning Code 0x13 defalult execution. func11 %x\n", 255 func11&0x7F); 256 Rcv = 0; 257 } 258 break; 259 260 261 case 0x12: 262 switch(func11 & 0x7F) 263 { 264 case 0x39: /*__SLL; */ 265 Rcv=(DATA_TYPE)Rav << (Rbv & 0x3F); 266 break; 267 case 0x34: /*__SRL; */ 268 Rcv=(DATA_TYPE)Rav >> (Rbv & 0x3F); 269 break; 270 case 0x3c: /*__SRA; */ 271 Rcv=(long long)Rav >> (Rbv & 0x3F); 272 break; 273 274 case 0x06: /*__EXTBL; */ 275 Rcv = (DATA_TYPE)Rav >> ((Rbv & 0x7)*8); 276 Rcv &= 0x00000000000000FFllu; 277 break; 278 case 0x16: /*__EXTWL; */ 279 Rcv = (DATA_TYPE)Rav >> ((Rbv & 0x7)*8); 280 Rcv &= 0x000000000000FFFFllu; 281 break; 282 case 0x5a: /*__EXTWH; */ 283 Rcv = (DATA_TYPE)Rav << (64-(Rbv & 0x7)*8); 284 Rcv &= 0x000000000000FFFFllu; 285 break; 286 case 0x26: /*__EXTLL; */ 287 Rcv = (DATA_TYPE)Rav >> ((Rbv & 0x7)*8); 288 Rcv &= 0x00000000FFFFFFFFllu; 289 break; 290 case 0x6a: /*__EXTLH; */ 291 Rcv = (DATA_TYPE)Rav << (64-(Rbv & 0x7)*8); 292 Rcv &= 0x00000000FFFFFFFFllu; 293 break; 294 case 0x36: /*__EXTQL; */ 295 Rcv = (DATA_TYPE)Rav >> ((Rbv & 0x7)*8); 296 break; 297 case 0x7a: /*__EXTQH; */ 298 Rcv = (DATA_TYPE)Rav << (64-(Rbv & 0x7)*8); 299 break; 300 301 case 0x0b: /*__INSBL; */ 302 byte_mask = 0x00000001ull << (Rbv & 0x7); 303 byte_loc = (Rbv & 0x7)*8; 304 Rbv = Rav << (byte_loc & 0x3F); 305 Rcv = zap(~byte_mask, Rbv); 306 break; 307 case 0x1b: /*__INSWL; */ 308 byte_mask = 0x00000003ull << (Rbv & 0x7); 309 byte_loc = (Rbv & 0x7)*8; 310 Rbv = Rav << (byte_loc & 0x3F); 311 Rcv = zap(~byte_mask, Rbv); 312 break; 313 case 0x57: /*__INSWH; */ 314 byte_mask = 0x00000003ull << (Rbv & 0x7); 315 byte_loc = 64 - (Rbv & 0x7)*8; 316 Rbv = Rav >> (byte_loc & 0x3F); 317 Rcv = zap(~(byte_mask >> 8), Rbv); 318 break; 319 case 0x2b: /*__INSLL; */ 320 byte_mask = 0x0000000Full << (Rbv & 0x7); 321 byte_loc = (Rbv & 0x7)*8; 322 Rbv = Rav << (byte_loc & 0x3F); 323 Rcv = zap(~byte_mask, Rbv); 324 break; 325 case 0x67: /*__INSLH; */ 326 byte_mask = 0x0000000Full << (Rbv & 0x7); 327 byte_loc = 64 - (Rbv & 0x7)*8; 328 Rbv = Rav >> (byte_loc & 0x3F); 329 Rcv = zap(~(byte_mask >> 8), Rbv); 330 break; 331 case 0x3b: /*__INSQL; */ 332 byte_mask = 0x000000FFull << (Rbv & 0x7); 333 byte_loc = (Rbv & 0x7)*8; 334 Rbv = Rav << (byte_loc & 0x3F); 335 Rcv = zap(~byte_mask, Rbv); 336 break; 337 case 0x77: /*__INSQH; */ 338 byte_mask = 0x000000FFull << (Rbv & 0x7); 339 byte_loc = 64 - (Rbv & 0x7)*8; 340 Rbv = Rav >> (byte_loc & 0x3F); 341 Rcv = zap(~(byte_mask >> 8), Rbv); 342 break; 343 344 case 0x02: /*__MSKBL; */ 345 Rbv = 0x00000001ull << (Rbv & 0x7); 346 Rcv = zap(Rbv, Rav); 347 break; 348 case 0x12: /*__MSKWL; */ 349 Rbv = 0x00000003ull << (Rbv & 0x7); 350 Rcv = zap(Rbv, Rav); 351 break; 352 case 0x52: /*__MSKWH; */ 353 Rbv = 0x00000003ull << (Rbv & 0x7); 354 Rbv = Rbv >> 8; 355 Rcv = zap(Rbv, Rav); 356 break; 357 case 0x22: /*__MSKLL; */ 358 Rbv = 0x0000000Full << (Rbv & 0x7); 359 Rcv = zap(Rbv, Rav); 360 break; 361 case 0x62: /*__MSKLH; */ 362 Rbv = 0x0000000Full << (Rbv & 0x7); 363 Rbv = Rbv >> 8; 364 Rcv = zap(Rbv, Rav); 365 break; 366 case 0x32: /*__MSKQL; */ 367 Rbv = 0x000000FFull << (Rbv & 0x7); 368 Rcv = zap(Rbv, Rav); 369 break; 370 case 0x72: /*__MSKQH; */ 371 Rbv = 0x000000FFull << (Rbv & 0x7); 372 Rbv = Rbv >> 8; 373 Rcv = zap(Rbv, Rav); 374 break; 375 376 case 0x30: /*__ZAP; */ 377 Rcv = zap(Rbv, Rav); 378 break; 379 case 0x31: /*__ZAPNOT; */ 380 Rcv = zap(~Rbv, Rav); 381 break; 382 383 default: 384 printf("Warning Code 0x12 defalult execution. func11 0x%u\n", 385 func11 & 0x7F); 386 Rcv = 0; 387 } 388 break; 389 390 391 case 0x16: /** Floating Point Codes **/ 392 { 393 double Fav=0.0, Fbv=0.0, Fcv=0.0; 394 memcpy(&Fav, &Rav, 8); 395 memcpy(&Fbv, &Rbv, 8); 396 397 switch(func11){ 398 case 0x0a0: /*__ADDT; */ 399 Fcv = Fav + Fbv; 400 break; 401 case 0x020: 402 case 0x080: /*__ADDS; */ 403 Fcv = Fav + Fbv; 404 break; 405 406 case 0x081: 407 case 0x0a1: 408 Fcv = Fav - Fbv; 409 break; 410 411 case 0x0be: /*__CVTQT; */ 412 Fcv = (double)Rbv; 413 break; 414 415 case 0x0a2: /*__MULT; */ 416 Fcv = Fav * Fbv; 417 break; 418 419 case 0x0a3: /*__DIVT; */ 420 if(Fbv==0.0){ 421 Fcv = 0.0; 422 break; 423 } 424 Fcv = (float)(Fav / Fbv); 425 break; 426 427 case 0x083: /*__DIVS; */ 428 if(Fbv==0.0){ 429 Fcv = 0.0; 430 break; 431 } 432 Fcv = Fav / Fbv; 433 break; 434 435 case 0x5a5: 436 case 0x0a5:/*__CMPTEQ; */ 437 if(Fav==Fbv) Fcv=2.0; else Fcv=0.0; 438 break; 439 case 0x0a7:/*__CMPTLE; */ 440 if(Fav<=Fbv) Fcv=2.0; else Fcv=0.0; 441 break; 442 case 0x0a6:/*__CMPTLT; */ 443 if(Fav< Fbv) Fcv=2.0; else Fcv=0.0; 444 break; 445 446 case 0x02f:/*__CVTTQ; */ 447 tmp = (unsigned long long)Fbv; 448 memcpy(&Fcv, &tmp, 8); 449 break; 450 451 default: printf("Warn 0x16 Floating Arithmetic func11 0x%x\n", 452 func11); 453 Fcv = 0.0; 454 } 455 456 memcpy(&Rcv, &Fcv, 8); 457 break; 458 } 459 460 case 0x17: /** Floating Point Codes **/ 461 { 462 double Fav=0.0, Fbv=0.0, Fcv=0.0; 463 memcpy(&Fav, &Rav, 8); 464 memcpy(&Fbv, &Rbv, 8); 465 466 switch(func11){ 467 case 0x020: /*__CPYS; */ 468 tmp = Rav; 469 tmp2 = Rbv; 470 tmp2 = ((tmp2 << 1) >> 1); /* clear bit63 */ 471 if(tmp & BIT63) tmp2 |= BIT63; 472 memcpy(&Fcv, &tmp2, 8); 473 break; 474 case 0x022: /*__CPYSE; */ 475 tmp = Rav; 476 tmp2 = Rbv; 477 tmp &= 0xFFF0000000000000llu; /* sign and Exp of Fra */ 478 tmp2 &= 0x000FFFFFFFFFFFFFllu; /* Fraction of Frb */ 479 tmp |= tmp2; 480 memcpy(&Fcv, &tmp, 8); 481 break; 482 483 case 0x010: /*__CVTLQ; */ 484 tmp = Rbv; 485 tmp2 = (tmp >> 62) & 0x3; 486 tmp2 = tmp2 << 30; 487 tmp2 |= ((tmp >> 29) & 0x3FFFFFFFull); 488 if(tmp2 & BIT31) tmp2 |= EXTND32; 489 memcpy(&Fcv, &tmp2, 8); 490 break; 491 492 default: 493 Fcv = 0.0; 494 break; 495 } 496 memcpy(&Rcv, &Fcv, 8); 497 break; 498 } 499 } 500 501 return Rcv; 502 } 503 /* branch.cc This is a part of SimuAlpha Version 2.2a 504 * Copyright (c) 1999,2000,2001, Kenji KISE 505 ***************************************************************/ 506 #include 507 #include 508 #include "define.h" 509 510 /* 511 * Execute Unconditional Branch, BR and BSR 512 **********************************************************/ 513 ADDR_TYPE execute_jmp(ADDR_TYPE *pc, DATA_TYPE Rbv){ 514 ADDR_TYPE ret=*pc; 515 *pc = Rbv & 0xFFFFFFFFFFFFFFFcull; 516 return ret; 517 } 518 519 /* 520 * Execute Unconditional Branch, BR and BSR 521 **********************************************************/ 522 ADDR_TYPE execute_branch(ADDR_TYPE *pc, DATA_TYPE diff21){ 523 ADDR_TYPE ret=*pc; 524 *pc += 4*diff21; 525 return ret; 526 } 527 528 /* 529 * Execute Integer Conditional Branch 530 **********************************************************/ 531 void ex_branch(int code, ADDR_TYPE *pc, 532 DATA_TYPE Rav, DATA_TYPE dif){ 533 double Fav=0.0; 534 // signal(SIGFPE, (void *)signal_float_branch); 535 switch(code) 536 { 537 case 0x39: if(Rav==0) *pc += 4*dif;break; 538 case 0x3e: if((long long)Rav>=0) *pc += 4*dif;break; 539 case 0x3f: if((long long)Rav>0) *pc += 4*dif;break; 540 case 0x38: if(!(Rav & 1)) *pc += 4*dif;break; 541 case 0x3c: if( Rav & 1 ) *pc += 4*dif;break; 542 case 0x3b: if((long long)Rav<=0) *pc += 4*dif;break; 543 case 0x3a: if((long long)Rav<0 ) *pc += 4*dif;break; 544 case 0x3d: if(Rav!=0) *pc += 4*dif;break; 545 546 case 0x31: memcpy(&Fav,&Rav,8);if(Fav==0.0) *pc+=4*dif;break; 547 case 0x36: memcpy(&Fav,&Rav,8);if(Fav>=0.0) *pc+=4*dif;break; 548 case 0x37: memcpy(&Fav,&Rav,8);if(Fav> 0.0) *pc+=4*dif;break; 549 case 0x33: memcpy(&Fav,&Rav,8);if(Fav<=0.0) *pc+=4*dif;break; 550 case 0x32: memcpy(&Fav,&Rav,8);if(Fav< 0.0) *pc+=4*dif;break; 551 case 0x35: memcpy(&Fav,&Rav,8);if(Fav!=0.0) *pc+=4*dif;break; 552 } 553 // signal(SIGFPE, SIG_IGN); 554 } 555 #include 556 #include 557 #include 558 #include 559 #include 560 #include 561 #include "define.h" 562 563 /* global variables */ 564 extern class architecture_state as; 565 extern struct evaluate e; 566 567 extern FILE *outfile; 568 extern char *get_assem_a(unsigned int ir, unsigned long long pc); 569 DATA_TYPE get_hex(char *buf); 570 571 extern Imemory Imem; // Instruction Memory 572 extern Dmemory Dmem; 573 574 void print_reg_name(int i){ 575 switch(i){ 576 case 0: printf("v0 "); break; 577 case 1: printf("t0 "); break; 578 case 2: printf("t1 "); break; 579 case 3: printf("t2 "); break; 580 case 4: printf("t3 "); break; 581 case 5: printf("t4 "); break; 582 case 6: printf("t5 "); break; 583 case 7: printf("t6 "); break; 584 case 8: printf("t7 "); break; 585 case 9: printf("s0 "); break; 586 case 10: printf("s1 "); break; 587 case 11: printf("s2 "); break; 588 case 12: printf("s3 "); break; 589 case 13: printf("s4 "); break; 590 case 14: printf("s5 "); break; 591 case 15: printf("fp "); break; 592 case 16: printf("a0 "); break; 593 case 17: printf("a1 "); break; 594 case 18: printf("a2 "); break; 595 case 19: printf("a3 "); break; 596 case 20: printf("a4 "); break; 597 case 21: printf("a5 "); break; 598 case 22: printf("t8 "); break; 599 case 23: printf("t9 "); break; 600 case 24: printf("t10 "); break; 601 case 25: printf("t11 "); break; 602 case 26: printf("ra "); break; 603 case 27: printf("t12 "); break; 604 case 28: printf("at "); break; 605 case 29: printf("gp "); break; 606 case 30: printf("sp "); break; 607 case 31: printf("zero "); break; 608 case 32: printf("pc "); break; 609 case 33: printf("vfp "); break; 610 } 611 } 612 613 614 /***********************************************************/ 615 void print_status() 616 { 617 int i; 618 unsigned int ir; 619 620 ir = Imem.instruction_load(as.pc); 621 cout << dec <<"TC:" << e.retired_inst << " "; 622 cout << hex << "0x" << as.pc; 623 cout << " " << get_assem_a(ir, as.pc+4) << "\n"; 624 625 /* printf(" mem val 0x%llx\n", load_8byte(0x11ffffb80)); */ 626 /* printf("f1 0x%-16llx %-8f \n", as.f[1],as.f[1]); */ 627 628 for(i=0; i<32; i++){ 629 print_reg_name(i); 630 cout << "r" << dec << setfill('0') << setw(2) << i << " " ; 631 cout.setf(ios::left); 632 cout << "0x" << hex << setw(9) << setfill(' ') << as.r[i] << " "; 633 cout << dec << setw(9) << setfill(' ') << as.r[i] << "\n"; 634 } 635 636 cout << "pc "; 637 cout.setf(ios::left); 638 cout << "0x" << hex << setw(9) << setfill(' ') << as.pc << " "; 639 cout << dec << setw(9) << setfill(' ') << as.pc << "\n"; 640 641 cout << "npc "; 642 cout.setf(ios::left); 643 cout << "0x" << hex << setw(9) << setfill(' ') << 0 << " "; 644 cout << dec << setw(9) << setfill(' ') << 0 << "\n"; 645 } 646 647 648 /************************************************************/ 649 void debugmode() /* -d option is added */ 650 { 651 int i,j; 652 char t_buf[256]; 653 char t_temp[256]; 654 static int stop = 1; 655 ULL tmp; 656 657 char *buf; 658 char *temp; 659 660 static ULL stop_count = 0; 661 static ADDR_TYPE stop_address = 0xFFFFFFFFFFFFFFFFull; 662 ADDR_TYPE address; 663 664 buf = t_buf; 665 temp = t_temp; 666 667 if(stop_count==e.retired_inst){ 668 stop = 1; 669 } 670 671 if(stop_address==as.pc){ 672 stop = 1; 673 } 674 675 if(stop==0) return; 676 677 if(stop==1){ 678 679 print_status(); 680 681 printf("(db)"); 682 fgets(buf,256, stdin); 683 684 while(*buf != (char)NULL){ 685 686 if(!strncmp(buf,"quit",4)) exit(1); 687 if(!strncmp(buf,"h",1)){ /* help */ 688 printf(" command\n"); 689 printf(" c followd by number: stop specified tc.\n"); 690 printf(" s followd by address: stop specified address.\n"); 691 printf(" x followd by address: examine specified address.\n"); 692 printf(" quit: quit simulate.\n"); 693 } 694 695 if(*(buf)=='\n') break; 696 697 if(*(buf)=='x'){ 698 buf++; 699 address = get_hex(buf); 700 address = address >> 4; /* I don't know why? */ 701 702 for(j=0; j<40; j++){ 703 printf("0x%x%x: ",(int)(address >> 32),(int)(address & MASK32)); 704 for(i=0; i<2; i++){ 705 tmp = Dmem.load_8byte(address); 706 printf("0x%08x%08x ", (int)(tmp >> 32), (int)(tmp & MASK32)); 707 address +=8; 708 } 709 printf("\n"); 710 } 711 } 712 713 714 if(*(buf)=='c'){ /* stop by total count */ 715 buf++; 716 stop_count = atol(buf); /* for int use atoi */ 717 cout << "stop_tc = " << dec << stop_count << "\n"; 718 stop=0; 719 break; 720 } 721 722 if(*(buf)=='s'){ /* stop by address */ 723 buf++; 724 stop_address = get_hex(buf); 725 stop_address = stop_address >> 4; 726 cout << "stop_address = " << hex << "0x" << stop_address << "\n"; 727 stop=0; 728 break; 729 } 730 731 cout << "\n" << "(db)"; 732 fgets(buf,256,stdin); 733 } 734 } 735 736 } 737 738 /* 739 * convert hexadecimal value into decimal value 740 **************************************************/ 741 ULL get_hex(char *buf){ 742 int i; 743 int num; 744 char t; 745 ULL temp=0; 746 ULL sum; 747 748 sum=0; 749 num = strlen(buf); 750 751 if(num>16){ 752 printf("Error! hex() can treat within 16digit numbers.\n"); 753 exit(1); 754 } 755 756 for(i=0; i 787 #include "define.h" 788 789 int get_iclass(ULL ir){ 790 int code; 791 int func; 792 code = (ir >> 26) & 0x3F; 793 func = func11(ir); 794 switch(code) 795 { 796 case 0x0a: return EX_LDI; 797 case 0x0e: return EX_STI; 798 case 0x0d: return EX_STI; 799 800 case 0x18: return EX_OPM; 801 case 0x00: return EX_PAL; 802 case 0x1a: return EX_JMP; 803 804 case 0x30: 805 case 0x34: return EX_BRA; 806 807 case 0x38: 808 case 0x39: 809 case 0x3a: 810 case 0x3b: 811 case 0x3c: 812 case 0x3d: 813 case 0x3e: 814 case 0x3f: return EX_CBI; 815 816 case 0x31: 817 case 0x32: 818 case 0x33: 819 case 0x35: 820 case 0x36: 821 case 0x37: return EX_CBF; 822 823 case 0x10: return EX_ARI; 824 case 0x11: 825 switch(func & 0x7F){ 826 case 0x24: 827 case 0x46: 828 case 0x66: 829 case 0x16: 830 case 0x14: 831 case 0x64: 832 case 0x44: 833 case 0x26: return EX_CMI; /* Conditional Move Integer */ 834 default: return EX_ARI; 835 } 836 case 0x12: return EX_ARI; 837 case 0x13: return EX_ARI; 838 839 case 0x08: 840 case 0x09: return EX_ADR; 841 842 case 0x28: 843 case 0x29: 844 case 0x0b: return EX_LDI; 845 846 case 0x22: 847 case 0x23: return EX_LDF; 848 849 case 0x2d: 850 case 0x0f: 851 case 0x2c: return EX_STI; 852 853 case 0x26: 854 case 0x27: return EX_STF; 855 856 case 0x16: return EX_FLO; 857 case 0x17: 858 switch(func){ 859 case 0x02a: 860 case 0x02b: return EX_CMF; /* Conditional Move Floag */ 861 default: return EX_FLO; 862 } 863 } 864 return -1; 865 } 866 /* Decode Instruction and Get Assembler Strings. 867 * get_assem_a for the Alpha AXP. Written by Kenji Kise, 1999. 868 *******************************************************************/ 869 #include 870 #include 871 #include 872 873 #include "define.h" 874 #include "code.h" 875 876 /***** 877 * There are four instruction types; 878 * (1) PAL Code Type ; Code<31:26> Function_code<25:0> ; 879 * (2) Branch Type ; Code<31:26> Ra<25:21> Diff<20:0> ; 880 * (3) Memory Type ; Code<31:26> Ra<25:21> Rb<20:16> Diff<15:0> ; 881 * (4) Operation Type; Code<31:26> Ra<25:21> Rb<20:16> Function<15:5> Rc<4:0>; 882 *****/ 883 884 char buff[256]; 885 886 /* 887 * 888 **********************************************************/ 889 char *get_assem_a(unsigned int ir, unsigned long long pc){ 890 unsigned int code; 891 unsigned int ra,rb,rc; 892 unsigned int func26, func11; 893 unsigned long long diff21, diff16; 894 unsigned int lit8; 895 char temp[256]; 896 897 func26 = ir & 0x3FFFFFF; /* ir<25:0> */ 898 func11 = (ir >> 5) & 0x7FF; /* ir<15:5> */ 899 code = ir >> 26; /* ir<31:26> */ 900 diff21 = ir & 0x1FFFFF; /* ir<21:0> */ 901 diff16 = ir & 0xFFFF; /* ir<15:0> */ 902 ra = (ir >> 21) & 0x1F; /* ir<25:21> */ 903 rb = (ir >> 16) & 0x1F; /* ir<20:16> */ 904 rc = ir & 0x1F; /* ir<4:0> */ 905 lit8 = (ir >> 13) & 0xFF; /* ir<20:13> */ 906 907 if(diff21 & BIT20) diff21 |= EXTND21; /* signed extended */ 908 if(diff16 & BIT15) diff16 |= EXTND16; /* signed extended */ 909 910 switch(code) 911 { 912 /***** Memory Type Without Function Code *****/ 913 case 0x0a: sprintf(buff, "ldub r%d,(r%d)", ra, rb); break; 914 case 0x0e: sprintf(buff, "stb r%d,(r%d)", ra, rb); break; 915 916 case 0x08: sprintf(buff, "lda r%d,(r%d)", ra, rb); break; 917 case 0x09: sprintf(buff, "ldah r%d,(r%d)", ra, rb); break; 918 case 0x28: sprintf(buff, "ldl r%d,(r%d)", ra, rb); break; 919 case 0x29: sprintf(buff, "ldq r%d,(r%d)", ra, rb); break; 920 case 0x0b: sprintf(buff, "ldq_u r%d,(r%d)", ra, rb); break; 921 case 0x2a: sprintf(buff, "ldl_l r%d,(r%d)", ra, rb); break; 922 case 0x2b: sprintf(buff, "ldq_l r%d,(r%d)", ra, rb); break; 923 924 case 0x2e: sprintf(buff, "stl_c r%d,(r%d)", ra, rb); break; 925 case 0x2f: sprintf(buff, "stq_c r%d,(r%d)", ra, rb); break; 926 case 0x2c: sprintf(buff, "stl r%d,(r%d)", ra, rb); break; 927 case 0x2d: sprintf(buff, "stq r%d,(r%d)", ra, rb); break; 928 case 0x0f: sprintf(buff, "stq_u r%d,(r%d)", ra, rb); break; 929 930 case 0x20: sprintf(buff, "ldf f%d,%qd(r%d)", ra, diff16, rb); break; 931 case 0x21: sprintf(buff, "ldg f%d,%qd(r%d)", ra, diff16, rb); break; 932 case 0x22: sprintf(buff, "lds f%d,%qd(r%d)", ra, diff16, rb); break; 933 case 0x23: sprintf(buff, "ldt f%d,%qd(r%d)", ra, diff16, rb); break; 934 case 0x24: sprintf(buff, "stf f%d,%qd(r%d)", ra, diff16, rb); break; 935 case 0x25: sprintf(buff, "stg f%d,%qd(r%d)", ra, diff16, rb); break; 936 case 0x26: sprintf(buff, "sts f%d,%qd(r%d)", ra, diff16, rb); break; 937 case 0x27: sprintf(buff, "stt f%d,%qd(r%d)", ra, diff16, rb); break; 938 939 /***** Memory Type With Function Code *****/ 940 case 0x18: 941 switch(diff16){ 942 case 0x8000: sprintf(buff, "fetch r%d, r%d", ra,rb); break; 943 case 0xe000: sprintf(buff, "rc r%d, r%d", ra,rb); break; 944 case 0x0000: sprintf(buff, "trapb r%d, r%d", ra,rb); break; 945 case 0xa000: sprintf(buff, "fetch_m r%d, r%d",ra,rb); break; 946 case 0xc000: sprintf(buff, "rpcc r%d, r%d", ra,rb); break; 947 case 0x4000: sprintf(buff, "mb r%d, r%d", ra,rb); break; 948 case 0xf000: sprintf(buff, "rs r%d, r%d", ra,rb); break; 949 default: 950 printf("Warning In Memory Type With Function Code.\n"); 951 sprintf(buff, "n/a"); 952 } 953 break; 954 955 /***** branch instruction *****/ 956 case 0x1a: 957 switch((diff16 >> 14) & 3){ 958 case 0: sprintf(buff, "jmp r%d, r%d",ra,rb); break; 959 case 1: sprintf(buff, "jsr r%d, r%d",ra,rb); break; 960 case 3: sprintf(buff, "jsr_coroutine r%d, r%d",ra,rb); break; 961 case 2: sprintf(buff, "ret r%d, r%d",ra,rb); break; 962 default: 963 printf("Warning In Branch Type With Function Code.\n"); 964 sprintf(buff, "n/a"); 965 } break; 966 967 case 0x30: sprintf(buff, "br r%d, 0x%qx", ra, pc+diff21*4); break; 968 case 0x34: sprintf(buff, "bsr r%d, 0x%qx",ra, pc+diff21*4); break; 969 970 case 0x39: sprintf(buff, "beq r%d, 0x%qx",ra, pc+diff21*4); break; 971 case 0x3e: sprintf(buff, "bge r%d, 0x%qx",ra, pc+diff21*4); break; 972 case 0x3f: sprintf(buff, "bgt r%d, 0x%qx",ra, pc+diff21*4); break; 973 case 0x38: sprintf(buff, "blbc r%d, 0x%qx",ra,pc+diff21*4); break; 974 case 0x3c: sprintf(buff, "blbs r%d, 0x%qx",ra,pc+diff21*4); break; 975 case 0x3b: sprintf(buff, "ble r%d, 0x%qx",ra, pc+diff21*4); break; 976 case 0x3a: sprintf(buff, "blt r%d, 0x%qx",ra, pc+diff21*4); break; 977 case 0x3d: sprintf(buff, "bne r%d, 0x%qx",ra, pc+diff21*4); break; 978 979 case 0x31: sprintf(buff, "fbeq r%d, 0x%qx 0x%qx",ra,pc+4,diff21);break; 980 case 0x35: sprintf(buff, "fbne r%d, 0x%qx 0x%qx",ra,pc+4,diff21);break; 981 case 0x32: sprintf(buff, "fblt r%d, 0x%qx 0x%qx",ra,pc+4,diff21);break; 982 case 0x36: sprintf(buff, "fbge r%d, 0x%qx 0x%qx",ra,pc+4,diff21);break; 983 case 0x33: sprintf(buff, "fble r%d, 0x%qx 0x%qx",ra,pc+4,diff21);break; 984 case 0x37: sprintf(buff, "fbgt r%d, 0x%qx 0x%qx",ra,pc+4,diff21);break; 985 986 case 0x10: 987 switch(func11 & 0x7F) 988 { 989 case 0x00: strcpy(buff, "addl "); break; 990 case 0x40: strcpy(buff, "addl/v"); break; 991 case 0x20: strcpy(buff, "addq "); break; 992 case 0x60: strcpy(buff, "addq/v"); break; 993 case 0x3d: strcpy(buff, "cmpule"); break; 994 case 0x0f: strcpy(buff, "cmpbge"); break; 995 case 0x09: strcpy(buff, "subl "); break; 996 case 0x49: strcpy(buff, "subl/v"); break; 997 case 0x29: strcpy(buff, "subq "); break; 998 case 0x69: strcpy(buff, "subq/v"); break; 999 case 0x2d: strcpy(buff, "cmpeq "); break; 1000 case 0x4d: strcpy(buff, "cmplt "); break; 1001 case 0x6d: strcpy(buff, "cmple "); break; 1002 case 0x1d: strcpy(buff, "cmpult"); break; 1003 case 0x02: strcpy(buff, "s4addl"); break; 1004 case 0x22: strcpy(buff, "s4addq"); break; 1005 case 0x0b: strcpy(buff, "s4subl"); break; 1006 case 0x2b: strcpy(buff, "s4subq"); break; 1007 case 0x12: strcpy(buff, "s8addl"); break; 1008 case 0x32: strcpy(buff, "s8addq"); break; 1009 case 0x1b: strcpy(buff, "s8subl"); break; 1010 case 0x3b: strcpy(buff, "s8subq"); break; 1011 default: 1012 printf("Error in 0x10 arithmetic\n"); 1013 sprintf(buff, "n/a"); 1014 } 1015 if(ir & BIT12) sprintf(temp, " r%d,0x%x,r%d",ra,lit8,rc); 1016 else sprintf(temp, " r%d,r%d,r%d", ra,rb,rc); 1017 strcat(buff, temp); 1018 break; 1019 1020 case 0x11: 1021 switch(func11 & 0x7F) 1022 { 1023 case 0x00: strcpy(buff, "and"); break; 1024 case 0x20: strcpy(buff, "bis"); break; 1025 case 0x40: strcpy(buff, "xor"); break; 1026 case 0x08: strcpy(buff, "bic"); break; 1027 case 0x28: strcpy(buff, "ornot"); break; 1028 case 0x48: strcpy(buff, "eqv"); break; 1029 1030 case 0x24: strcpy(buff, "cmoveq"); break; 1031 case 0x46: strcpy(buff, "cmovge"); break; 1032 case 0x66: strcpy(buff, "cmovgt"); break; 1033 case 0x16: strcpy(buff, "cmovlgc"); break; 1034 case 0x14: strcpy(buff, "cmovlbs"); break; 1035 case 0x64: strcpy(buff, "cmovle"); break; 1036 case 0x44: strcpy(buff, "cmovlt"); break; 1037 case 0x26: strcpy(buff, "cmovne"); break; 1038 default: 1039 printf("Error in 0x11 arithmetic\n"); 1040 sprintf(buff, "n/a"); 1041 } 1042 if(ir & BIT12) sprintf(temp, " r%d,0x%x,r%d",ra,lit8,rc); 1043 else sprintf(temp, " r%d,r%d,r%d", ra,rb,rc); 1044 strcat(buff, temp); 1045 break; 1046 1047 case 0x12: 1048 switch(func11 & 0x7F) 1049 { 1050 case 0x39: strcpy(buff, "sll"); break; 1051 case 0x34: strcpy(buff, "srl"); break; 1052 case 0x3c: strcpy(buff, "sra"); break; 1053 case 0x06: strcpy(buff, "extbl"); break; 1054 case 0x16: strcpy(buff, "extwl"); break; 1055 case 0x26: strcpy(buff, "extll"); break; 1056 case 0x36: strcpy(buff, "extql"); break; 1057 case 0x5a: strcpy(buff, "extwh"); break; 1058 case 0x6a: strcpy(buff, "extlh"); break; 1059 case 0x7a: strcpy(buff, "extqh"); break; 1060 case 0x0b: strcpy(buff, "insbl"); break; 1061 case 0x1b: strcpy(buff, "inswl"); break; 1062 case 0x2b: strcpy(buff, "insll"); break; 1063 case 0x3b: strcpy(buff, "insql"); break; 1064 case 0x57: strcpy(buff, "inswh"); break; 1065 case 0x67: strcpy(buff, "inslh"); break; 1066 case 0x77: strcpy(buff, "insqh"); break; 1067 case 0x02: strcpy(buff, "mskbl"); break; 1068 case 0x12: strcpy(buff, "mskwl"); break; 1069 case 0x22: strcpy(buff, "mskll"); break; 1070 case 0x32: strcpy(buff, "mskql"); break; 1071 case 0x52: strcpy(buff, "mskwh"); break; 1072 case 0x62: strcpy(buff, "msklh"); break; 1073 case 0x72: strcpy(buff, "mskqh"); break; 1074 case 0x30: strcpy(buff, "zap"); break; 1075 case 0x31: strcpy(buff, "zapnot"); break; 1076 default: 1077 printf("Warning in 0x12, func11 0x%x arithmetic\n",func11); 1078 sprintf(buff, "n/a"); 1079 } 1080 if(ir & BIT12) sprintf(temp, " r%d,0x%x,r%d",ra,lit8,rc); 1081 else sprintf(temp, " r%d,r%d,r%d", ra,rb,rc); 1082 strcat(buff, temp); 1083 break; 1084 1085 case 0x13: 1086 switch(func11 & 0x7F) 1087 { 1088 case 0x00: sprintf(buff, "mull r%d,r%d,r%d", ra,rb,rc); break; 1089 case 0x60: sprintf(buff, "mulq/v r%d,r%d,r%d", ra,rb,rc); break; 1090 case 0x40: sprintf(buff, "mull/v r%d,r%d,r%d", ra,rb,rc); break; 1091 case 0x30: sprintf(buff, "umulh r%d,r%d,r%d", ra,rb,rc); break; 1092 case 0x20: sprintf(buff, "mulq r%d,r%d,r%d", ra,rb,rc); break; 1093 default: 1094 printf("Warning in 0x13 arithmetic\n"); 1095 sprintf(buff, "n/a"); 1096 } 1097 break; 1098 1099 /***** PAL Code *****/ 1100 case 0x00: 1101 switch(func26 & 0xffff){ 1102 case 0x0000: sprintf(buff, "halt"); break; 1103 case 0x0086: sprintf(buff, "imb"); break; 1104 case 0x0083: sprintf(buff, "callsys"); break; 1105 default: 1106 sprintf(buff, "call_pal 0x%x", func26); 1107 } break; 1108 1109 case 0x19: sprintf(buff, "pal19"); break; 1110 case 0x1f: sprintf(buff, "pal1f"); break; 1111 case 0x1b: sprintf(buff, "pal1b"); break; 1112 case 0x1d: sprintf(buff, "pal1d"); break; 1113 case 0x1e: sprintf(buff, "pal1e"); break; 1114 1115 /***** Floating Arithmetic *****/ 1116 case 0x16: 1117 switch(func11){ 1118 case 0x080: strcpy(buff, "adds"); break; 1119 case 0x000: strcpy(buff, "adds/c"); break; 1120 case 0x040: strcpy(buff, "adds/m"); break; 1121 case 0x0c0: strcpy(buff, "adds/d"); break; 1122 case 0x180: strcpy(buff, "adds/u"); break; 1123 case 0x100: strcpy(buff, "adds/uc"); break; 1124 case 0x140: strcpy(buff, "adds/um"); break; 1125 case 0x1c0: strcpy(buff, "adds/ud"); break; 1126 1127 case 0x0a0: strcpy(buff, "addt"); break; 1128 case 0x0a1: strcpy(buff, "subt"); break; 1129 case 0x020: strcpy(buff, "addt/c"); break; 1130 case 0x060: strcpy(buff, "addt/m"); break; 1131 case 0x0e0: strcpy(buff, "addt/d"); break; 1132 case 0x1a0: strcpy(buff, "addt/u"); break; 1133 case 0x120: strcpy(buff, "addt/uc"); break; 1134 case 0x160: strcpy(buff, "addt/um"); break; 1135 case 0x1e0: strcpy(buff, "addt/ud"); break; 1136 1137 case 0x0a5: strcpy(buff, "cmpteq"); break; 1138 case 0x0a6: strcpy(buff, "cmptlt"); break; 1139 case 0x0a7: strcpy(buff, "cmptle"); break; 1140 case 0x0a4: strcpy(buff, "cmptun"); break; 1141 case 0x0bc: 1142 case 0x03c: 1143 case 0x07c: 1144 case 0x0fc: 1145 strcpy(buff, "cvtqs"); break; 1146 case 0x0be: 1147 case 0x03e: 1148 case 0x07e: 1149 case 0x0fe: 1150 strcpy(buff, "cvtqt"); break; 1151 case 0x083: strcpy(buff, "divs"); break; 1152 case 0x0a3: strcpy(buff, "divt"); break; 1153 1154 default: 1155 sprintf(buff, "Floating Arithmetic func11 0x%x",func11); 1156 break; 1157 } 1158 sprintf(temp, " f%d,f%d,f%d", ra,rb,rc); 1159 strcat(buff, temp); 1160 break; 1161 1162 case 0x17: 1163 switch(func11){ 1164 case 0x020: strcpy(buff, "cpys"); break; 1165 case 0x021: strcpy(buff, "cpysn"); break; 1166 case 0x022: strcpy(buff, "cpyse"); break; 1167 case 0x025: strcpy(buff, "mf_fpcr"); break; 1168 case 0x024: strcpy(buff, "mt_fpcr"); break; 1169 case 0x530: strcpy(buff, "cvtql/sv"); break; 1170 case 0x010: strcpy(buff, "cvtlq"); break; 1171 case 0x030: strcpy(buff, "cvtql"); break; 1172 case 0x130: strcpy(buff, "cvtql/v"); break; 1173 case 0x02a: strcpy(buff, "fcmoveq"); break; 1174 case 0x02c: strcpy(buff, "fcmovlt"); break; 1175 case 0x02e: strcpy(buff, "fcmovle"); break; 1176 case 0x02b: strcpy(buff, "fcmovne"); break; 1177 case 0x02d: strcpy(buff, "fcmovge"); break; 1178 case 0x02f: strcpy(buff, "fcmovgt"); break; 1179 1180 default: sprintf(buff, "Code 0x17 Floating Arithmetic func11 0x%x", 1181 func11); 1182 break; 1183 } 1184 break; 1185 1186 default: 1187 printf("Warning Code 0x%x Default case in decode.c", code); 1188 sprintf(buff,"n/a"); 1189 } 1190 return buff; 1191 } 1192 1193 /* 1194 * 1195 **********************************************************/ 1196 int get_isort(unsigned int ir){ 1197 unsigned int code; 1198 unsigned int func26, func11; 1199 unsigned long long diff16; 1200 int isort=255; 1201 1202 code = ir >> 26; /* ir<31:26> */ 1203 diff16 = ir & 0xFFFF; /* ir<15:0> */ 1204 func11 = (ir >> 5) & 0x7FF; /* ir<15:5> */ 1205 func26 = ir & 0x3FFFFFF; /* ir<25:0> */ 1206 1207 if(diff16 & BIT15) diff16 |= EXTND16; /* signed extended */ 1208 1209 switch(code) 1210 { 1211 /***** Memory Type Without Function Code *****/ 1212 case 0x0a: isort = __LDBU; break; 1213 case 0x0e: isort = __STB; break; 1214 case 0x0d: isort = __STW; break; 1215 1216 case 0x08: isort = __LDA; break; 1217 case 0x09: isort = __LDAH; break; 1218 case 0x28: isort = __LDL; break; 1219 case 0x29: isort = __LDQ; break; 1220 case 0x0b: isort = __LDQ_U; break; 1221 case 0x2a: isort = __LDL_L; break; 1222 case 0x2b: isort = __LDQ_L; break; 1223 case 0x2e: isort = __STL_C; break; 1224 case 0x2f: isort = __STQ_C; break; 1225 case 0x2c: isort = __STL; break; 1226 case 0x2d: isort = __STQ; break; 1227 case 0x0f: isort = __STQ_U; break; 1228 1229 case 0x20: isort=__LDF; break; 1230 case 0x21: isort=__LDQ; break; 1231 case 0x22: isort=__LDS; break; 1232 case 0x23: isort=__LDT; break; 1233 case 0x24: isort=__STF; break; 1234 case 0x25: isort=__STQ; break; 1235 case 0x26: isort=__STS; break; 1236 case 0x27: isort=__STT; break; 1237 1238 /***** Memory Type With Function Code *****/ 1239 case 0x18: 1240 switch(diff16){ 1241 case 0x8000: isort=__FETCH; break; 1242 case 0xe000: isort=__RC; break; 1243 case 0x0000: isort=__TRAPB; break; 1244 case 0xa000: isort=__FETCH_M;break; 1245 case 0xc000: isort=__RPCC; break; 1246 case 0x4000: isort=__MB; break; 1247 case 0xf000: isort=__RS; break; 1248 } 1249 break; 1250 1251 /***** branch instruction *****/ 1252 case 0x1a: 1253 switch((diff16 >> 14) & 3){ 1254 case 0: isort=__JMP; break; 1255 case 1: isort=__JSR; break; 1256 case 3: isort=__JSR_COROUTINE; break; 1257 case 2: isort=__RET; break; 1258 } break; 1259 1260 case 0x30: isort=__BR; break; 1261 case 0x34: isort=__BSR; break; 1262 case 0x39: isort=__BEQ; break; 1263 case 0x3e: isort=__BGE; break; 1264 case 0x3f: isort=__BGT; break; 1265 case 0x38: isort=__BLBC;break; 1266 case 0x3c: isort=__BLBS;break; 1267 case 0x3b: isort=__BLE; break; 1268 case 0x3a: isort=__BLT; break; 1269 case 0x3d: isort=__BNE; break; 1270 case 0x31: isort=__FBEQ; break; 1271 case 0x35: isort=__FBNE; break; 1272 case 0x32: isort=__FBLT; break; 1273 case 0x36: isort=__FBGE; break; 1274 case 0x33: isort=__FBLE; break; 1275 case 0x37: isort=__FBGT; break; 1276 1277 case 0x10: 1278 switch(func11 & 0x7F) 1279 { 1280 case 0x00: isort=__ADDL; break; 1281 case 0x40: isort=__ADDL_V; break; 1282 case 0x20: isort=__ADDQ; break; 1283 case 0x60: isort=__ADDQ_V; break; 1284 case 0x3d: isort=__CMPULE; break; 1285 case 0x0f: isort=__CMPBGE; break; 1286 case 0x09: isort=__SUBL; break; 1287 case 0x49: isort=__SUBL_V; break; 1288 case 0x29: isort=__SUBQ; break; 1289 case 0x69: isort=__SUBQ_V; break; 1290 case 0x2d: isort=__CMPEQ; break; 1291 case 0x4d: isort=__CMPLT; break; 1292 case 0x6d: isort=__CMPLE; break; 1293 case 0x1d: isort=__CMPULT; break; 1294 case 0x02: isort=__S4ADDL; break; 1295 case 0x22: isort=__S4ADDQ; break; 1296 case 0x0b: isort=__S4SUBL; break; 1297 case 0x2b: isort=__S4SUBQ; break; 1298 case 0x12: isort=__S8ADDL; break; 1299 case 0x32: isort=__S8ADDQ; break; 1300 case 0x1b: isort=__S8SUBL; break; 1301 case 0x3b: isort=__S8SUBQ; break; 1302 } 1303 break; 1304 1305 case 0x11: 1306 switch(func11 & 0x7F) 1307 { 1308 case 0x00: isort=__AND; break; 1309 case 0x20: isort=__BIS; break; 1310 case 0x40: isort=__XOR; break; 1311 case 0x08: isort=__BIC; break; 1312 case 0x28: isort=__ORNOT; break; 1313 case 0x48: isort=__EQV; break; 1314 1315 case 0x24: isort=__CMOVEQ; break; 1316 case 0x26: isort=__CMOVNE; break; 1317 case 0x14: isort=__CMOVLBS; break; 1318 case 0x44: isort=__CMOVLT; break; 1319 case 0x46: isort=__CMOVGE; break; 1320 case 0x16: isort=__CMOVLBC; break; 1321 case 0x64: isort=__CMOVLE; break; 1322 case 0x66: isort=__CMOVGT; break; 1323 } 1324 break; 1325 1326 case 0x12: 1327 switch(func11 & 0x7F) 1328 { 1329 case 0x39: isort=__SLL; break; 1330 case 0x34: isort=__SRL; break; 1331 case 0x3c: isort=__SRA; break; 1332 case 0x06: isort=__EXTBL; break; 1333 case 0x16: isort=__EXTWL; break; 1334 case 0x26: isort=__EXTLL; break; 1335 case 0x36: isort=__EXTQL; break; 1336 case 0x5a: isort=__EXTWH; break; 1337 case 0x6a: isort=__EXTLH; break; 1338 case 0x7a: isort=__EXTQH; break; 1339 case 0x0b: isort=__INSBL; break; 1340 case 0x1b: isort=__INSWL; break; 1341 case 0x2b: isort=__INSLL; break; 1342 case 0x3b: isort=__INSQL; break; 1343 case 0x57: isort=__INSWH; break; 1344 case 0x67: isort=__INSLH; break; 1345 case 0x77: isort=__INSQH; break; 1346 case 0x02: isort=__MSKBL; break; 1347 case 0x12: isort=__MSKWL; break; 1348 case 0x22: isort=__MSKLL; break; 1349 case 0x32: isort=__MSKQL; break; 1350 case 0x52: isort=__MSKWH; break; 1351 case 0x62: isort=__MSKLH; break; 1352 case 0x72: isort=__MSKQH; break; 1353 case 0x30: isort=__ZAP; break; 1354 case 0x31: isort=__ZAPNOT; break; 1355 } 1356 break; 1357 1358 case 0x13: 1359 switch(func11 & 0x7F) 1360 { 1361 case 0x00: isort=__MULL; break; 1362 case 0x60: isort=__MULQ_V; break; 1363 case 0x40: isort=__MULL_V; break; 1364 case 0x30: isort=__UMULH; break; 1365 case 0x20: isort=__MULQ; break; 1366 } 1367 break; 1368 1369 /***** PAL Code *****/ 1370 case 0x00: 1371 switch(func26 & 0xffff){ 1372 case 0x0000: isort=__HALT; break; 1373 case 0x0086: isort=__IMB; break; 1374 case 0x0083: isort=__CALLSYS; break; 1375 default: isort=__CALLPAL; 1376 } break; 1377 1378 case 0x19: sprintf(buff, "pal19"); break; 1379 case 0x1f: sprintf(buff, "pal1f"); break; 1380 case 0x1b: sprintf(buff, "pal1b"); break; 1381 case 0x1d: sprintf(buff, "pal1d"); break; 1382 case 0x1e: sprintf(buff, "pal1e"); break; 1383 1384 /***** Floating Arithmetic *****/ 1385 case 0x16: 1386 switch(func11){ 1387 case 0x080: 1388 case 0x000: 1389 case 0x040: 1390 case 0x0c0: 1391 case 0x180: 1392 case 0x100: 1393 case 0x140: 1394 case 0x1c0: isort=__ADDS; break; 1395 1396 case 0x0a0: 1397 case 0x020: 1398 case 0x060: 1399 case 0x0e0: 1400 case 0x1a0: 1401 case 0x120: 1402 case 0x160: 1403 case 0x1e0: isort=__ADDT; break; 1404 1405 case 0x081: isort=__SUBS; break; 1406 case 0x0a1: isort=__SUBT; break; 1407 1408 case 0x0ac: isort=__CVTTS; break; 1409 1410 case 0x5a5: 1411 case 0x0a5: isort=__CMPTEQ; break; 1412 case 0x0a6: isort=__CMPTLT; break; 1413 case 0x0a7: isort=__CMPTLE; break; 1414 case 0x0a4: isort=__CMPTUN; break; 1415 case 0x0bc: 1416 case 0x03c: 1417 case 0x07c: 1418 case 0x0fc: isort=__CVTQS; break; 1419 case 0x0be: 1420 case 0x03e: 1421 case 0x07e: 1422 case 0x0fe: isort=__CVTQT; break; 1423 case 0x083: isort=__DIVS; break; 1424 case 0x0a3: isort=__DIVT; break; 1425 case 0x082: isort=__MULS; break; 1426 case 0x0a2: isort=__MULT; break; 1427 case 0x02f: 1428 case 0x0af: isort=__CVTTQ; 1429 1430 default: sprintf(buff, "Floating Arithmetic func11 0x%x",func11); 1431 break; 1432 } 1433 break; 1434 1435 case 0x17: 1436 switch(func11){ 1437 case 0x020: isort=__CPYS; break; 1438 case 0x021: isort=__CPYSN; break; 1439 case 0x022: isort=__CPYSE; break; 1440 case 0x025: isort=__MF_FPCR; break; 1441 case 0x024: isort=__MT_FPCR; break; 1442 case 0x530: isort=__CVTQL_SV; break; 1443 case 0x010: isort=__CVTLQ; break; 1444 case 0x030: isort=__CVTQL; break; 1445 case 0x130: isort=__CVTQL_V; break; 1446 case 0x02a: isort=__FCMOVEQ; break; 1447 case 0x02c: isort=__FCMOVLT; break; 1448 case 0x02e: isort=__FCMOVLE; break; 1449 case 0x02b: isort=__FCMOVNE; break; 1450 case 0x02d: isort=__FCMOVGE; break; 1451 case 0x02f: isort=__FCMOVGT; break; 1452 } 1453 break; 1454 } 1455 1456 // if(isort==255){ 1457 // printf("In getassem.c default isort. code:0x%x, func11:0x%x.\n", 1458 // code, func11); 1459 // } 1460 return isort; 1461 } 1462 1463 /* instruction.cc This is a part of SimuAlpha Version 2.2a 1464 * Copyright (c) 1999,2000,2001, Kenji KISE 1465 ***************************************************************/ 1466 #include 1467 #include 1468 #include "define.h" 1469 1470 extern Dmemory Dmem; 1471 extern Imemory Imem; 1472 extern class architecture_state as; 1473 1474 DATA_TYPE diff21(unsigned int ir){ 1475 long long diff21; 1476 diff21 = ir & 0x1FFFFFllu; 1477 if(diff21 & BIT20) diff21 |= EXTND21; 1478 return diff21; 1479 } 1480 DATA_TYPE diff16(unsigned int ir){ 1481 long long diff16; 1482 diff16 = ir & 0xFFFFllu; 1483 if(diff16 & BIT15) diff16 |= EXTND16; 1484 return diff16; 1485 } 1486 1487 instruction::instruction(){ /***** Constructor *****/ 1488 memset(this, 0, sizeof(instruction)); 1489 } 1490 1491 void instruction::Fetch(ADDR_TYPE pc){ 1492 static ULL tc=100; // you can select an initial value. 1493 Rav=Rbv=Rmv=Adr=Rcv=0; 1494 1495 tag = tc++; 1496 ir = Imem.instruction_load(pc); 1497 cpc = pc; 1498 iclass = get_iclass(ir); 1499 isort = get_isort(ir); 1500 if(iclass==-1){ 1501 cout << "PC 0x" << hex << cpc << "Error! Unimplemented.\n"; 1502 } 1503 } 1504 1505 void instruction::Decode(){ 1506 switch(iclass){ 1507 case EX_OPM: LW=31; LR1=31; LR2=31; LR3=31; break; 1508 case EX_PAL: LW=31; LR1=31; LR2=31; LR3=31; break; 1509 case EX_ADR: LW=ra(ir); LR1=31; LR2=rb(ir); LR3=31; break; 1510 case EX_JMP: LW=ra(ir); LR1=31; LR2=rb(ir); LR3=31; break; 1511 case EX_BRA: LW=ra(ir); LR1=31; LR2=31; LR3=31; break; 1512 case EX_CBI: LW=31; LR1=ra(ir); LR2=31; LR3=31; break; 1513 case EX_CBF: LW=31; LR1=ra(ir); LR2=31; LR3=31; break; 1514 case EX_LDI: LW=ra(ir); LR1=31; LR2=rb(ir); LR3=31; break; 1515 case EX_LDF: LW=ra(ir); LR1=31; LR2=rb(ir); LR3=31; break; 1516 case EX_STI: LW=31; LR1=ra(ir); LR2=rb(ir); LR3=31; break; 1517 case EX_STF: LW=31; LR1=ra(ir); LR2=rb(ir); LR3=31; break; 1518 case EX_CMF: LW=rc(ir); LR1=ra(ir); LR2=rb(ir); LR3=rc(ir);break; 1519 case EX_FLO: LW=rc(ir); LR1=ra(ir); LR2=rb(ir); LR3=31; break; 1520 case EX_CMI: LW=rc(ir); LR1=ra(ir); LR2=rb(ir); LR3=rc(ir);break; 1521 case EX_ARI: LW=rc(ir); LR1=ra(ir); LR2=rb(ir); LR3=31; break; 1522 } 1523 1524 switch(iclass){ /*** Decode Load/Store, memory access bytes ***/ 1525 case EX_LDI: 1526 case EX_LDF: 1527 case EX_STI: 1528 case EX_STF: 1529 switch(code(ir)){ 1530 case 0x28: /** LDL **/ 1531 case 0x22: /** LDS **/ 1532 case 0x2c: /** STL **/ 1533 case 0x26: /** STS **/ 1534 mem_byte = 4; 1535 break; 1536 case 0x0b: /** LDQ_U **/ 1537 case 0x23: /** LDT **/ 1538 case 0x29: /** LDQ **/ 1539 case 0x0a: /** LDUB, gdb says so **/ 1540 case 0x2d: /** STQ **/ 1541 case 0x0f: /** STQ_U **/ 1542 case 0x27: /** STT */ 1543 case 0x0e: /** STB, gdb says so **/ 1544 case 0x0d: /** STW, gdb says so **/ 1545 mem_byte = 8; 1546 break; 1547 default: 1548 cout << "Warning Decode ld/st default.\n"; 1549 } 1550 } 1551 1552 } 1553 1554 void instruction::RegisterRead(){ 1555 switch(iclass){ 1556 case EX_OPM: Rav=0; Rbv=0; Rmv=0; break; 1557 case EX_PAL: Rav=func26(ir); Rbv=0; Rmv=0; break; 1558 case EX_ADR: Rav=diff16(ir); Rbv=as.r[R2]; Rmv=0; break; 1559 case EX_JMP: Rav=0; Rbv=as.r[R2]; Rmv=0; break; 1560 case EX_BRA: Rav=diff21(ir); Rbv=0; Rmv=0; break; 1561 case EX_CBI: Rav=as.r[R1]; Rbv=diff21(ir);Rmv=0; break; 1562 case EX_LDI: Rav=0; Rbv=as.r[R2]; Rmv=0; break; 1563 case EX_LDF: Rav=0; Rbv=as.r[R2]; Rmv=0; break; 1564 case EX_STI: Rav=as.r[R1]; Rbv=as.r[R2]; Rmv=0; break; 1565 case EX_STF: Rav=as.f[R1]; Rbv=as.r[R2]; Rmv=0; break; 1566 case EX_CBF: Rav=as.f[R1]; Rbv=diff21(ir);Rmv=0; break; 1567 case EX_FLO: Rav=as.f[R1]; Rbv=as.f[R2]; Rmv=0; break; 1568 case EX_CMF: Rav=as.f[R1]; Rbv=as.f[R2]; Rmv=as.f[R3]; break; 1569 case EX_ARI: Rav=as.r[R1]; Rmv=0; 1570 if(ir & BIT12) Rbv=lit8(ir); else Rbv=as.r[R2]; break; 1571 case EX_CMI: Rav=as.r[R1]; Rmv=as.r[R3]; 1572 if(ir & BIT12) Rbv=lit8(ir); else Rbv=as.r[R2]; break; 1573 } 1574 } 1575 1576 void instruction::Rename(){ 1577 W = LW; 1578 R1 = LR1; 1579 R2 = LR2; 1580 R3 = LR3; 1581 } 1582 1583 void instruction::Execute(){ 1584 ADDR_TYPE npc=cpc+4; 1585 switch(iclass){ 1586 case EX_ADR: Rcv=calculate_adr(code(ir), Rbv, Rav); break; 1587 case EX_LDI: 1588 case EX_LDF: 1589 case EX_STI: 1590 case EX_STF: Adr=calculate_adr(code(ir), Rbv, diff16(ir)); break; 1591 case EX_CMI: 1592 case EX_CMF: Rcv=ex_cmov(code(ir),func11(ir),Rav,Rbv,Rmv); break; 1593 case EX_ARI: 1594 case EX_FLO: Rcv=ex_arith(code(ir),func11(ir),Rav,Rbv); break; 1595 case EX_JMP: Rcv=execute_jmp(&npc, Rbv); break; 1596 case EX_BRA: Rcv=execute_branch(&npc, Rav); break; 1597 case EX_CBI: 1598 case EX_CBF: ex_branch(code(ir), &npc, Rav, Rbv); break; 1599 } 1600 switch(iclass){ 1601 case EX_JMP: 1602 case EX_BRA: 1603 case EX_CBI: 1604 case EX_CBF: as.pc=npc; t_pc=npc; 1605 } 1606 } 1607 1608 void instruction::Memory(){ 1609 switch(iclass){ 1610 case EX_LDI: 1611 case EX_LDF: 1612 if(Adr%4!=0) cout << "Warning: Load 4byte alignment miss.\n"; 1613 Rcv = Dmem.load(mem_byte, Adr); 1614 Rcv = get_load_data(code(ir), Rcv); 1615 break; 1616 } 1617 } 1618 1619 void instruction::WriteBack(){ 1620 switch(iclass){ 1621 case EX_PAL: execute_pal(this); break; 1622 case EX_STI: 1623 case EX_STF: 1624 if(Adr%4!=0) cout << "Warning: Store 4byte alignment miss.\n"; 1625 Dmem.store(mem_byte, Adr, get_store_data(code(ir), Rav)); 1626 break; 1627 case EX_JMP: 1628 case EX_BRA: 1629 case EX_ADR: 1630 case EX_LDI: 1631 case EX_CMI: 1632 case EX_ARI: as.r[W]=Rcv; break; 1633 case EX_LDF: 1634 case EX_CMF: 1635 case EX_FLO: as.f[W]=Rcv; break; 1636 } 1637 } 1638 /* load_store.cc This is a part of SimuAlpha Version 2.2a 1639 * Copyright (c) 1999,2000,2001, Kenji KISE 1640 ***************************************************************/ 1641 #include 1642 #include 1643 #include "define.h" 1644 1645 extern Dmemory Dmem; 1646 1647 DATA_TYPE long map_s(unsigned int int_tmp){ 1648 unsigned int i8; 1649 1650 i8 = (int_tmp >> 23) & 0xFF; 1651 1652 if(i8==0xFF) return 0x00000000000007FFull; 1653 if(i8==0x00) return 0x0000000000000000ull; 1654 1655 if(i8 & 0x80) return 0x0000000000000400ull | (i8 & 0x7F); 1656 else return 0x0000000000000380ull | (i8 & 0x7F); 1657 1658 printf("Warning In load_store.c, map_s Error. \n"); 1659 } 1660 1661 DATA_TYPE get_store_data(int code, DATA_TYPE Rav){ 1662 DATA_TYPE tmp; 1663 DATA_TYPE dat=0; 1664 int int_tmp; 1665 1666 switch(code){ 1667 case 0x2d: /** STQ **/ 1668 case 0x0f: /** STQ_U **/ 1669 case 0x27: /** STT **/ 1670 case 0x0e: /** STB, gdb says so **/ 1671 case 0x0d: /** STW, gdb says so **/ 1672 case 0x2c: /** STL **/ 1673 dat = Rav; 1674 break; 1675 case 0x26: /** STS **/ 1676 tmp = Rav; 1677 int_tmp = 0; 1678 if(tmp & BIT63) int_tmp |= BIT8; /* for S */ 1679 int_tmp |= (tmp >> 52) & 0xFF; /* for Exp. */ 1680 int_tmp = int_tmp << 23; 1681 int_tmp |= ((tmp >> 29) & 0x7FFFFFlu); /* Frac. Hi and Lo */ 1682 dat = (DATA_TYPE)int_tmp; 1683 break; 1684 default: 1685 cout << "Warning: default in get_store_data.\n"; 1686 dat=0; 1687 } 1688 return dat; 1689 } 1690 1691 DATA_TYPE get_load_data(int code, DATA_TYPE Rav_tmp){ 1692 DATA_TYPE Rav; 1693 switch(code){ 1694 case 0x28: /** LDL **/ 1695 Rav = Rav_tmp; 1696 if(Rav & BIT31) Rav|=EXTND32; 1697 break; 1698 case 0x22: /** LDS **/ 1699 Rav = 0llu | Rav_tmp >> 31; 1700 Rav = (Rav << 11) | map_s(Rav_tmp); /* MAP_S */ 1701 Rav = (Rav << 23) | (Rav_tmp & 0x7FFFFFlu); 1702 Rav = Rav << 29; 1703 break; 1704 case 0x29: /** LDQ **/ 1705 case 0x0b: /** LDQ_U **/ 1706 case 0x23: /** LDT **/ 1707 case 0x0a: /** LDUB, gdb says so **/ 1708 Rav = Rav_tmp; 1709 break; 1710 default: 1711 cout << "Warning: default in get_load_data.\n"; 1712 Rav=0; 1713 } 1714 return Rav; 1715 } 1716 1717 /************************************************************/ 1718 ADDR_TYPE calculate_adr(int code, DATA_TYPE Rbv, DATA_TYPE dif){ 1719 ADDR_TYPE adr=0; 1720 switch(code){ 1721 case 0x08: adr = Rbv + dif; break; 1722 case 0x09: adr = Rbv + (dif << 16); break; 1723 case 0x28: adr = Rbv + dif; break; 1724 case 0x29: adr = Rbv + dif; break; 1725 case 0x0b: adr = (Rbv + dif) & 0xFFFFFFFFFFFFFFF8llu; break; 1726 case 0x2d: adr = Rbv + dif; break; 1727 case 0x2c: adr = Rbv + dif; break; 1728 case 0x0f: adr = (Rbv + dif) & 0xFFFFFFFFFFFFFFF8llu; break; 1729 case 0x27: adr = Rbv + dif; break; 1730 case 0x23: adr = Rbv + dif; break; 1731 case 0x22: adr = Rbv + dif; break; 1732 case 0x26: adr = Rbv + dif; break; 1733 case 0x0a: adr = Rbv + dif; break; 1734 case 0x0e: adr = Rbv + dif; break; 1735 case 0x0d: adr = Rbv + dif; break; /* STW */ 1736 } 1737 return adr; 1738 } 1739 /* mem_init.cc This is a part of SimuAlpha Version 2.2a 1740 * Copyright (c) 1999,2000,2001, Kenji KISE 1741 ***************************************************************/ 1742 #include 1743 #include 1744 #include 1745 #include "define.h" 1746 1747 extern class architecture_state as; 1748 extern struct machine_setting ms; 1749 extern Imemory Imem; 1750 extern Dmemory Dmem; 1751 1752 ADDR_TYPE mem_init_instruction(char *program_name){ 1753 ADDR_TYPE ibuffer_min_adr; /* minimun address of Ibuffer */ 1754 ADDR_TYPE ibuffer_max_adr; /* maximun address of Ibuffer */ 1755 FILE *fp; 1756 FILE *fp_tmp; 1757 int i,j; 1758 struct FF_filehdr hdr; 1759 struct FF_aouthdr aout; 1760 struct FF_scnhdr st; 1761 unsigned int *data; 1762 1763 if((fp = fopen(program_name, "r")) == NULL) { 1764 fprintf(stderr, "Bad file name: %s\n", program_name); 1765 exit(0); 1766 } 1767 fp_tmp = fopen(program_name, "r"); 1768 1769 /* read header */ 1770 fread(&hdr, sizeof(hdr), 1, fp); 1771 fread(&aout,sizeof(aout),1, fp); 1772 if(hdr.f_magic!=387){ 1773 printf("%s not executable.\n", program_name); exit(0);} 1774 1775 for(i=0; ipc = mem_init_instruction(program_name);/* Set Instr. */ 1835 1836 if(ms.current_argp_flag==0) argp = argp_sample; 1837 else argp = argpt; 1838 1839 if((fp = fopen(program_name, "r")) == NULL) { 1840 fprintf(stderr, "Bad file name: %s\n", program_name); 1841 exit(1); 1842 } 1843 fp_tmp = fopen(program_name, "r"); 1844 1845 /* read header */ 1846 fread(&hdr, sizeof(hdr), 1, fp); 1847 fread(&aout,sizeof(aout),1, fp); 1848 1849 if(hdr.f_magic!=387){ 1850 printf("%s is not an executable file.\n", program_name); 1851 exit(0); 1852 } 1853 1854 dbuffer_min=0x140000000llu; 1855 dbuffer_max= aout.bsize + aout.bbs_start; /* 0x150000000llu; */ 1856 Dmem.set_dbuffer(dbuffer_min, dbuffer_max); 1857 sbuffer_min=0x110000000llu; 1858 sbuffer_max=0x110000000llu; 1859 Dmem.set_sbuffer(sbuffer_min, sbuffer_max); 1860 1861 for(i=0; isbuffer_max){ 1874 sbuffer_max = st.s_paddr+st.s_size; 1875 Dmem.set_sbuffer(sbuffer_min, sbuffer_max); 1876 } 1877 } 1878 if((st.s_size%4)!=0) 1879 printf("st.s_size is not devided by 4.\n"); 1880 1881 data = (unsigned int *)malloc(st.s_size); 1882 fseek(fp_tmp, st.s_scnptr, SEEK_SET); 1883 fread(data, st.s_size, 1, fp_tmp); 1884 for(j=0; j<(st.s_size)/4; j++){ 1885 Dmem.store_4byte(st.s_paddr + j*4, data[j]); 1886 } 1887 free(data); 1888 } 1889 } 1890 1891 /*** memory setting, SP, ARGV, ARGC etc. ***/ 1892 for(argp_count=0; 1; argp_count++) 1893 if(argp[argp_count]==NULL) break; 1894 1895 /* Decide the value of SP, this value has no special meaning. 1896 you can decide appropriate address. */ 1897 if(ms.current_argp_flag==0) ptr = as->r[30] = 0x11ffff000ull; 1898 else ptr = as->r[30] = ms.current_argp_flag; 1899 1900 str_ptr = as->r[30] + (1 + argc + 1 + argp_count + 5)*8; 1901 Dmem.store_8byte(ptr, argc); /* write argc to the memory */ 1902 ptr+=8; 1903 1904 for(i=0; i 1935 #include 1936 #include 1937 #include "define.h" 1938 1939 extern struct evaluate e; 1940 1941 void Imemory::Imemory_init(int size, ADDR_TYPE min, ADDR_TYPE max){ 1942 ibuffer = (unsigned int *)malloc(size); 1943 ibuffer_min_adr=min; 1944 ibuffer_max_adr=max; 1945 } 1946 unsigned int Imemory::instruction_load(ADDR_TYPE adr){ 1947 if(adribuffer_max_adr){ 1948 return 0; 1949 } 1950 return ibuffer[(adr - ibuffer_min_adr)/4]; 1951 } 1952 void Imemory::instruction_store(ADDR_TYPE adr, unsigned int data){ 1953 if(adribuffer_max_adr){ 1954 printf("Error: Instruction_store as->pc is out of range.\n"); 1955 exit(1); 1956 } 1957 ibuffer[(adr-ibuffer_min_adr)/4] = data; 1958 } 1959 /**************************************************/ 1960 void Dmemory::set_dbuffer(ADDR_TYPE min, ADDR_TYPE max){ 1961 dbuffer_min = min; 1962 dbuffer_max = max; 1963 } 1964 1965 /* Systemcall obreak use the function */ 1966 void Dmemory::set_dbuffer(ADDR_TYPE max){ 1967 dbuffer_max = max; 1968 } 1969 1970 void Dmemory::set_sbuffer(ADDR_TYPE min, ADDR_TYPE max){ 1971 sbuffer_min = min; 1972 sbuffer_max = max; 1973 } 1974 1975 /* 1976 * Translation from a logical address to a phisical address. 1977 **********************************************************/ 1978 char* Dmemory::adr_translate(ADDR_TYPE adr){ 1979 ADDR_TYPE index; 1980 ADDR_TYPE offset; 1981 int i; 1982 1983 if(adrdbuffer_max || 1984 (adr>sbuffer_max && adr> PAGE_BIT; 1990 offset = adr & PAGE_MASK; /* page offset */ 1991 1992 for(i=0; i=MEM_PAGE_SIZE) { 2033 // printf("Warning: In memory.c, load_4byte, offset+3>=PAGE.\n"); 2034 ret=0; 2035 dat = load_byte(adr+3); ret |= (dat & 0xFF); ret = ret << 8; 2036 dat = load_byte(adr+2); ret |= (dat & 0xFF); ret = ret << 8; 2037 dat = load_byte(adr+1); ret |= (dat & 0xFF); ret = ret << 8; 2038 dat = load_byte(adr+0); ret |= (dat & 0xFF); 2039 return ret; 2040 } 2041 ptr = adr_translate(adr); 2042 if(ptr==NULL) return 0; 2043 memcpy(&ret, &ptr[offset], 4); 2044 return ret; 2045 } 2046 2047 DATA_TYPE Dmemory::load_8byte(ADDR_TYPE adr){ 2048 ADDR_TYPE offset; 2049 DATA_TYPE ret; 2050 char *ptr; 2051 int dat; 2052 2053 offset = adr & PAGE_MASK; /* page offset */ 2054 if((offset+7)>=MEM_PAGE_SIZE){ 2055 // printf("Warning: adr 0x%qx In memory.c, load_8byte, offset+7>=PAGE.\n",adr); 2056 ret=0; 2057 dat = load_byte(adr+7); ret |= (dat & 0xFF); ret = ret << 8; 2058 dat = load_byte(adr+6); ret |= (dat & 0xFF); ret = ret << 8; 2059 dat = load_byte(adr+5); ret |= (dat & 0xFF); ret = ret << 8; 2060 dat = load_byte(adr+4); ret |= (dat & 0xFF); ret = ret << 8; 2061 dat = load_byte(adr+3); ret |= (dat & 0xFF); ret = ret << 8; 2062 dat = load_byte(adr+2); ret |= (dat & 0xFF); ret = ret << 8; 2063 dat = load_byte(adr+1); ret |= (dat & 0xFF); ret = ret << 8; 2064 dat = load_byte(adr+0); ret |= (dat & 0xFF); 2065 return ret; 2066 } 2067 ptr = adr_translate(adr); 2068 if(ptr==NULL) return 0; 2069 memcpy(&ret, &ptr[offset], 8); 2070 return ret; 2071 } 2072 2073 DATA_TYPE Dmemory::load(int byte, ADDR_TYPE adr){ 2074 if(byte==4) return load_4byte(adr); 2075 if(byte==8) return load_8byte(adr); 2076 cout << "Warning: Dmemory::load, byte is not 4 and 8.\n"; 2077 return 0; 2078 } 2079 2080 /************************************************************/ 2081 void Dmemory::store_byte(ADDR_TYPE adr, char data){ 2082 unsigned int offset; 2083 char *ptr; 2084 2085 offset = adr & PAGE_MASK; /* page offset */ 2086 ptr = adr_translate(adr); 2087 if(ptr==NULL){ cout << "Store Adr Error.\n"; exit(1);} 2088 ptr[offset]=data; 2089 } 2090 2091 void Dmemory::store_4byte(ADDR_TYPE adr, unsigned int data){ 2092 unsigned int offset; 2093 char *ptr; 2094 2095 offset = adr & PAGE_MASK; /* page offset */ 2096 if((offset+3)>=MEM_PAGE_SIZE) { 2097 printf("In memory.c, store_4byte Unimplemented Error.\n"); 2098 } 2099 ptr = adr_translate(adr); 2100 if(ptr==NULL){ cout << "Store Adr Error.\n"; exit(1);} 2101 memcpy(&ptr[offset], &data, 4); 2102 } 2103 2104 void Dmemory::store_8byte(ADDR_TYPE adr, DATA_TYPE data){ 2105 ADDR_TYPE offset; 2106 char *ptr; 2107 2108 offset = adr & PAGE_MASK; /* page offset */ 2109 if((offset+7)>=MEM_PAGE_SIZE) { 2110 printf("In memory.c, store_8byte Unimplemented Error.\n"); 2111 } 2112 ptr = adr_translate(adr); 2113 if(ptr==NULL){ cout << "Store Adr Error.\n"; exit(1);} 2114 memcpy(&ptr[offset], &data, 8); 2115 } 2116 2117 void Dmemory::store(int byte, ADDR_TYPE adr, DATA_TYPE data){ 2118 if(byte==4){ 2119 store_4byte(adr, (unsigned int)(data & MASK32)); return; } 2120 if(byte==8){ 2121 store_8byte(adr, data); return; } 2122 cout << "Warning: Dmemory::store, byte is not 4 and 8.\n"; 2123 } 2124 /* simu.cc This is a part of SimuAlpha Version 2.2a 2125 * Copyright (c) 1999,2000,2001, Kenji KISE 2126 ***************************************************************/ 2127 #include 2128 #include 2129 #include 2130 #include 2131 #include "define.h" 2132 2133 static char UsageMessage[] = 2134 "SimuAlpha version 2.2a last updated 2001.01.25\n\ 2135 Usage: SimuAlpha [-option] command\n\ 2136 -d: debug mode(set ms.debug_flag).\n\ 2137 -s: print trace of systemcall(set ms.syscall_flag).\n\ 2138 -e[num][m]: specify end_tc. m stands for million. \n\ 2139 -p[SP]: use argp of the current system. Debugging option.\n\ 2140 -V[num]: verbose mode. prints '.' by VERBOSE_INTERVAL .\n\ 2141 "; 2142 2143 class architecture_state as; 2144 struct machine_setting ms; 2145 struct evaluate e; 2146 2147 Imemory Imem; // Instruction Memory 2148 Dmemory Dmem; // Data Buffer 2149 2150 void print_result(ostream& out){ 2151 out << "Program exited normally. "; 2152 out << dec << e.retired_inst; 2153 out << " code executed. " << e.used_memory << "MB used.\n"; 2154 } 2155 2156 void construct_data(int argc, char **argv, char **argp){ 2157 int i; 2158 char *buf; 2159 buf = (char *)malloc(1024); 2160 2161 memset(&as, 0, sizeof(as)); 2162 memset(&ms, 0, sizeof(ms)); 2163 memset(&e, 0, sizeof(e) ); 2164 if(argc>1){ 2165 for(i=0; i<10; i++){ 2166 if(argc==1) break; 2167 if((*(char *)(argv[1]))=='-'){ 2168 switch( *((char *)(argv[1]) +1) ) 2169 { 2170 case 'h': cout << UsageMessage; exit(0); 2171 case 'd': ms.debug_flag = 1; break; 2172 case 's': ms.syscall_flag = 1; break; 2173 case 't': ms.distrib_flag = 1; break; 2174 case 'V': 2175 ms.verbose_interval =atoi((char *)(argv[1])+2); 2176 if(ms.verbose_interval==0) ms.verbose_interval=100000; 2177 if(*((char *)(argv[1])+strlen(argv[1])-1)=='m') 2178 ms.verbose_interval *=1000000; 2179 cout << "verbose interval:" 2180 <Fetch(as.pc); as.pc+=4; 2226 p->Decode(); 2227 p->Rename(); 2228 p->RegisterRead(); 2229 p->Execute(); 2230 p->Memory(); 2231 p->WriteBack(); 2232 if(p->iclass==EX_PAL) as.pc = p->t_pc; 2233 e.retired_inst++; 2234 2235 if(ms.verbose_interval && 2236 (e.retired_inst%ms.verbose_interval)==0){ 2237 fprintf(stdout, "."); fflush(stdout); 2238 } 2239 if(ms.end_tc!=0 && e.retired_inst>=ms.end_tc) 2240 destruct_simulator(); 2241 if(ms.end_flag==1) destruct_simulator(); 2242 } 2243 } 2244 2245 int main(int argc, char **argv, char **argp){ 2246 construct_data(argc, argv, argp); 2247 main_loop(); 2248 return 0; 2249 } 2250 /* syscall.cc This is a part of SimuAlpha Version 2.2a 2251 * Copyright (c) 1999,2000,2001, Kenji KISE 2252 ***************************************************************/ 2253 #define SYS_sigreturn 103 2254 #define SYS_sigprocmask 48 2255 #define SYS_obreak 17 2256 #define SYS_getrlimit 144 2257 #define SYS_setrlimit 145 2258 #define SYS_stat 67 2259 #define SYS_fstat 91 2260 #define SYS_ioctl 54 2261 #define SYS_sigaction 156 2262 #define SYS_close 6 2263 #define SYS_read 3 2264 #define SYS_write 4 2265 #define SYS_open 45 2266 #define SYS_unlink 10 2267 #define SYS_getpagesize 64 2268 #define SYS_gettimeofday 116 2269 #define SYS_getrusage 117 2270 #define SYS_lseek 19 2271 #define SYS_getuid 24 2272 2273 #include "memory.h" 2274 #include "define.h" 2275 #include 2276 #include 2277 #include 2278 #include 2279 2280 #if defined(__i386) 2281 #include 2282 #endif 2283 2284 #include 2285 #include 2286 #include 2287 #include 2288 #include 2289 #include "code.h" 2290 2291 extern Dmemory Dmem; 2292 2293 extern class architecture_state as; 2294 extern struct machine_setting ms; 2295 extern struct evaluate e; 2296 2297 extern void destruct_simulator(); 2298 2299 /************************************************************/ 2300 void syscall(instruction *p){ 2301 char buf[8192*10]; 2302 char buf2[8192]; 2303 char name[20]; 2304 long long ret=0; 2305 long long i; 2306 2307 p->t_pc = p->cpc+4; 2308 2309 p->cache_flush = 0; 2310 switch(as.r[0]){ 2311 2312 case SYS_sigreturn: 2313 { 2314 int i; 2315 unsigned long long buf[35+1+48]; 2316 2317 ret = as.r[17]; 2318 for(i=0; i<84; i++) buf[i] = Dmem.load_8byte(as.r[16]+i*8); 2319 for(i=0; i<31; i++) as.r[i] = buf[i+4]; 2320 /* for(i=0; i<31; i++){as.f[i] = buf[i+39]; } */ 2321 2322 p->t_pc = buf[2]; 2323 2324 // as.sigreturn_pc = buf[2]; 2325 strcpy(name, "sigreturn"); 2326 p->cache_flush = 1; 2327 if(ms.debug_flag){ 2328 cout << "Sigreturn: return Adr: " << hex << p->t_pc << "\n"; 2329 } 2330 break; 2331 } 2332 2333 case SYS_sigprocmask: 2334 ret = 0; 2335 strcpy(name, "sigprocmask"); 2336 if(as.r[17] == 0xfffffffffffff137ull){/* I don't know why. GDB say so. */ 2337 ms.end_flag = 1; 2338 } 2339 break; 2340 2341 case SYS_obreak: 2342 ret = 0; 2343 { /* I am not sure, true? */ 2344 unsigned long long max = as.r[16] + as.r[18]; 2345 Dmem.set_dbuffer(max); 2346 } 2347 strcpy(name, "obreak"); 2348 break; 2349 2350 case SYS_getrlimit: 2351 for(i=0; icache_flush = 1; 2359 break; 2360 2361 case SYS_setrlimit: 2362 /* Do nothing. */ 2363 /* for(i=0; icache_flush = 1; 2381 break; 2382 2383 case SYS_fstat: 2384 { 2385 char buf[256]; 2386 ret = fstat(as.r[16], (struct stat *)buf); 2387 2388 /**** fstat set 0, bcause FreeBSD and Degital Unix's 2389 implementations are different. >> Store 0 ****/ 2390 2391 for(i=0; i<10; i++) Dmem.store_8byte(as.r[17]+i*8, 0); 2392 2393 /* for(i=0; icache_flush = 1; 2400 break; 2401 } 2402 2403 case SYS_ioctl: 2404 /* ret = ioctl(as.r[16], as.r[17], */ 2405 strcpy(name, "ioctl"); 2406 ret = 0; 2407 break; 2408 2409 case SYS_sigaction: 2410 ret = 0; 2411 /* ret = sigaction(as.r[16], as.r[17], as.r[18]); */ 2412 strcpy(name, "sigaction"); 2413 break; 2414 2415 case SYS_close: 2416 if(as.r[16]>2) ret = close(as.r[16]); else ret=0; 2417 strcpy(name, "close"); 2418 break; 2419 2420 case SYS_read: 2421 ret = read((int)as.r[16], (void *)buf, (size_t)as.r[18]); 2422 for(i=0; i<(long long)ret; i++){ 2423 Dmem.store_byte(as.r[17]+i, buf[i]); 2424 } 2425 p->cache_flush = 1; 2426 strcpy(name, "read"); 2427 break; 2428 2429 case SYS_lseek: 2430 ret = lseek(as.r[16], as.r[17], as.r[18]); 2431 strcpy(name, "lseek"); 2432 break; 2433 2434 case SYS_write: 2435 for(i=0; i<(long long)as.r[18]; i++){ 2436 buf[i] = Dmem.load_byte(as.r[17]+i); 2437 } 2438 ret = write((long)as.r[16], (void *)buf, (long)as.r[18]); 2439 p->cache_flush = 1; 2440 strcpy(name, "write"); 2441 if(ret==-1){ printf("Syscall Write Error!\n"); exit(1);} 2442 break; 2443 2444 case SYS_open: 2445 for(i=0; i<1024; i++){ 2446 buf[i] = Dmem.load_byte(as.r[16]+i); 2447 } 2448 ret = open(buf, as.r[17], as.r[18]); 2449 strcpy(name, "open"); 2450 break; 2451 2452 case SYS_unlink: 2453 for(i=0; i<1024; i++){ 2454 buf[i] = Dmem.load_byte(as.r[16]+i); 2455 } 2456 ret = unlink(buf); 2457 p->cache_flush = 1; 2458 strcpy(name, "unlink"); 2459 break; 2460 2461 2462 case SYS_getuid: 2463 ret = getuid(); 2464 strcpy(name, "getuid"); 2465 break; 2466 2467 case SYS_getpagesize: 2468 ret = 8192; /* getpagesize(); */ 2469 strcpy(name, "getpagesize"); 2470 break; 2471 2472 case SYS_gettimeofday: 2473 { 2474 struct timeval tv; 2475 struct timezone tz; 2476 2477 ret = gettimeofday(&tv, &tz); 2478 memcpy(buf, &tv, sizeof(tv)); 2479 for(i=0; icache_flush = 1; 2483 strcpy(name, "gettimeofday"); 2484 break; 2485 } 2486 2487 case SYS_getrusage: 2488 { 2489 struct rusage ru; 2490 ret = getrusage((enum __rusage_who)as.r[16], &ru); 2491 // ret = getrusage(as.r[16], &ru); 2492 memcpy(buf, &ru, sizeof(ru)); 2493 for(i=0; icache_flush = 1; 2497 strcpy(name, "getrusage"); 2498 break; 2499 } 2500 2501 default: 2502 cout << "TC:" << e.retired_inst; 2503 cout << " Syscall.c Default Error!!\n"; 2504 cout << "Syscall No:" << as.r[0]; 2505 cout << " Not implemented.\n"; 2506 destruct_simulator(); 2507 } 2508 2509 if(ms.syscall_flag){ 2510 cout << "TC " << setw(9) << dec << e.retired_inst; 2511 cout << ": " << name; 2512 cout << " " << hex << as.r[16]; 2513 cout << ", " << hex << as.r[17]; 2514 cout << ", " << hex << as.r[18]; 2515 cout << " >> " << hex << ret << "\n"; 2516 } 2517 fflush(stdout); 2518 2519 as.r[1]=as.r[2]=as.r[3]=as.r[4]=as.r[5]=as.r[6]=as.r[7]=as.r[8]=0; 2520 as.r[19]=as.r[20]=as.r[22]=as.r[24]= as.r[25]=as.r[28]=0; 2521 as.r[0] = ret; 2522 as.r[23]= p->t_pc; 2523 } 2524 2525 2526 /************************************************************/ 2527 void execute_pal(instruction *p){ 2528 p->t_pc = p->cpc+4; 2529 switch(func26(p->ir) & 0xffff) 2530 { 2531 case 0x0000: 2532 cout << "TC:" << dec << e.retired_inst << "pal_halt\n"; exit(1); 2533 case 0x0086: cout << "imb\n"; exit(1); 2534 case 0x0083: syscall(p); break; 2535 default: 2536 if(ms.syscall_flag) 2537 cout << "TC " << setw(9) << dec << e.retired_inst 2538 << ": Warning: in execute_pal default.\n"; 2539 } 2540 } 2541 /* 2542 * Instruction Definition of the Alpha AXP. 2543 * Defined and Written by Kenji Kise, 1999 2544 *******************************************************/ 2545 2546 /***** Control Transfer instructions (int and float) *****/ 2547 #define __BR 1 /* Unconditional Branch */ 2548 #define __BSR 2 /* Branch to Subroutine */ 2549 #define __BEQ 3 /* Branch if Register Equal to Zero */ 2550 #define __BGE 4 /* Branch if Register Greater Than or Equal to Zero */ 2551 #define __BGT 5 /* Branch if Register Greater Than Zero */ 2552 #define __BLBC 6 /* Branch if Register Low Bit Is Clear */ 2553 #define __BLBS 7 /* Branch if Register Low Bit Is Set */ 2554 #define __BLE 8 /* Branch if Register Less Than or Equal to Zero */ 2555 #define __BLT 9 /* Branch if Register Less Than Zero */ 2556 #define __BNE 10 /* Branch if Register Not Equal to Zero */ 2557 #define __JMP 11 /* Jump */ 2558 #define __JSR 12 2559 #define __RET 13 /* Return from Subroutine */ 2560 #define __JSR_COROUTINE 14 /* Jump to Subroutine Return */ 2561 #define __FBEQ 15 2562 #define __FBGE 16 2563 #define __FBGT 17 2564 #define __FBLE 18 2565 #define __FBLT 19 2566 #define __FBNE 20 2567 /***** Memory Access Instructions (int and float) *****/ 2568 #define __LDL 30 /* Load Sign-Extended Longword from Memory to Register */ 2569 #define __LDQ 31 /* Load Quadword from Memory to Register */ 2570 #define __LDQ_U 32 /* Load Unaligned Quadword from Memory to Register */ 2571 #define __LDL_L 33 /* Load Sign-Extended Longword from Memory to Register Locked*/ 2572 #define __LDQ_L 34 /* Load Quadword from Memory to Register Locked */ 2573 #define __STL_C 35 /* Store Longword from Register to Memory Conditional */ 2574 #define __STQ_C 36 /* Store Quadword from Register to Memory Conditional */ 2575 #define __STL 37 /* Store Longword from Register to Memory */ 2576 #define __STQ 38 /* Store Quadword from Register to Memory */ 2577 #define __STQ_U 39 /* Store Unaligned Quadword from Register to Memory */ 2578 #define __LDF 41 2579 #define __LDG 42 2580 #define __LDS 43 2581 #define __LDT 44 2582 #define __STF 45 2583 #define __STG 46 2584 #define __STS 47 2585 #define __STT 48 2586 #define __FETCH 50 2587 #define __FETCH_M 51 2588 #define __MB 52 2589 #define __RC 53 2590 #define __RPCC 54 2591 #define __RS 55 2592 #define __TRAPB 56 2593 2594 /***** Arithmetic instructions (int and float) *****/ 2595 /* code 0x10 */ 2596 #define __LDA 60 /* Load Address */ 2597 #define __LDAH 61 /* Load Address High */ 2598 #define __ADDL 62 /* Add Longword */ 2599 #define __ADDL_V 63 /* Add Longword */ 2600 #define __ADDQ 64 /* Add Quadword */ 2601 #define __ADDQ_V 65 /* Add Quadword */ 2602 #define __S4ADDL 66 /* Scaled Add Longword by 4 */ 2603 #define __S8ADDL 67 /* Scaled Add Longword by 8 */ 2604 #define __S4ADDQ 68 /* Scaled Add Quadword by 4 */ 2605 #define __S8ADDQ 69 /* Scaled Add Quadword by 8 */ 2606 #define __CMPEQ 70 /* Compare Signed Quadword Equal */ 2607 #define __CMPLE 71 /* Compare Signed Quadword Less Than or Equal */ 2608 #define __CMPLT 72 /* Compare Signed Quadword Less Than */ 2609 #define __CMPULE 73 /* Compare Unsigned Quadword Less Than or Equal */ 2610 #define __CMPULT 74 /* Compare Unsigned Quadword Less Than */ 2611 #define __CMPBGE 75 /* Compare Byte */ 2612 #define __SUBL 76 /* Subtract Longword */ 2613 #define __SUBL_V 77 /* Subtract Longword */ 2614 #define __S4SUBL 78 /* Scaled Subtract Longword by 4 */ 2615 #define __S8SUBL 79 /* Scaled Subtract Longword by 8 */ 2616 #define __SUBQ 80 /* Scaled Quadword */ 2617 #define __SUBQ_V 81 /* Scaled Quadword */ 2618 #define __S4SUBQ 82 /* Scaled Subtract Quadword by 4 */ 2619 #define __S8SUBQ 83 /* Scaled Subtract Quadword by 8 */ 2620 /* code 0x11 */ 2621 #define __AND 84 /* Logical Product */ 2622 #define __BIC 85 /* Logical Product with Complement */ 2623 #define __BIS 86 /* Logical Sum (OR) */ 2624 #define __EQV 87 /* Logical Equivalence (XORNOT) */ 2625 #define __ORNOT 88 /* Logical Sum with Complement */ 2626 #define __XOR 89 /* Logical Difference */ 2627 #define __CMOVEQ 90 /* CMOVE if Register Equal to Zero */ 2628 #define __CMOVGE 91 /* CMOVE if Register Greater than or Equal to Zero */ 2629 #define __CMOVGT 92 /* CMOVE if Register Greater than Zero */ 2630 #define __CMOVLBC 93 /* CMOVE if Register Low Bit Clear */ 2631 #define __CMOVLBS 94 /* CMOVE if Register Low Bit Set */ 2632 #define __CMOVLE 95 /* CMOVE if Register Less than or Equal to Zero */ 2633 #define __CMOVLT 96 /* CMOVE if Register Less than Zero */ 2634 #define __CMOVNE 97 /* CMOVE if Register Not Equal to Zero */ 2635 2636 /* code 0x12 */ 2637 #define __SLL 98 /* Shift Left Logical */ 2638 #define __SRL 99 /* Shift Right Logical */ 2639 #define __SRA 100 /* Shift Right Arithmetic */ 2640 #define __EXTBL 101 /* Extract Byte Low */ 2641 #define __EXTWL 102 /* Extract Word Low */ 2642 #define __EXTLL 103 /* Extract Longword Low */ 2643 #define __EXTQL 104 /* Extract Quadword Low */ 2644 #define __EXTWH 105 /* Extract Word High */ 2645 #define __EXTLH 106 /* Extract Longword High */ 2646 #define __EXTQH 107 /* Extract Quadword High */ 2647 #define __INSBL 108 /* Insert Byte Low */ 2648 #define __INSWL 109 /* Insert Word Low */ 2649 #define __INSLL 110 /* Insert Longword Low */ 2650 #define __INSQL 111 /* Insert Quadword Low */ 2651 #define __INSWH 112 /* Insert Word High */ 2652 #define __INSLH 113 /* Insert Longword High */ 2653 #define __INSQH 114 /* Insert Quadword High */ 2654 #define __MSKBL 115 /* Mask Byte Low */ 2655 #define __MSKWL 116 /* Mask Word Low */ 2656 #define __MSKLL 117 /* Mask Longword Low */ 2657 #define __MSKQL 118 /* Mask Quadword Low */ 2658 #define __MSKWH 119 /* Mask Word High */ 2659 #define __MSKLH 120 /* Mask Longword High */ 2660 #define __MSKQH 121 /* Mask Quadword High */ 2661 #define __ZAP 122 /* Zero Byte */ 2662 #define __ZAPNOT 123 /* Zero Byte Not */ 2663 /* code 0x13 */ 2664 #define __MULL 124 /* Multiply Longword */ 2665 #define __MULL_V 125 /* Multiply Longword */ 2666 #define __MULQ 126 /* Multiply Quadword */ 2667 #define __MULQ_V 127 /* Multiply Quadword */ 2668 #define __UMULH 128 2669 /* 2670 * PAL 2671 **********************************************************/ 2672 #define __HALT 130 2673 #define __IMB 131 2674 #define __CALLSYS 132 2675 #define __PAL19 133 2676 #define __PAL1B 134 2677 #define __PAL1D 135 2678 #define __PAL1E 136 2679 #define __PAL1F 137 2680 #define __CALLPAL 138 2681 /* 2682 * Floating Point 2683 **********************************************************/ 2684 /* code 0x17 */ 2685 #define __CPYS 140 2686 #define __CPYSN 141 2687 #define __CPYSE 142 2688 #define __MF_FPCR 143 2689 #define __MT_FPCR 144 2690 #define __CVTQL_SV 145 2691 #define __CVTLQ 146 2692 #define __CVTQL 147 2693 #define __CVTQL_V 148 2694 #define __FCMOVEQ 149 2695 #define __FCMOVLT 150 2696 #define __FCMOVLE 151 2697 #define __FCMOVNE 152 2698 #define __FCMOVGE 153 2699 #define __FCMOVGT 154 2700 /* code 0x16 */ 2701 #define __ADDS 160 2702 #define __ADDT 161 2703 #define __CMPTEQ 162 2704 #define __CMPTLT 163 2705 #define __CMPTLE 164 2706 #define __CMPTUN 165 2707 #define __CVTQS 166 2708 #define __CVTQT 167 2709 #define __CVTTS 168 2710 #define __DIVS 169 2711 #define __DIVT 170 2712 #define __MULS 171 2713 #define __MULT 172 2714 #define __SUBS 173 2715 #define __SUBT 174 2716 #define __CVTTQ 175 2717 #define __LDBU 200 2718 #define __STB 201 2719 #define __STW 202 2720 typedef unsigned long long ULL; 2721 typedef unsigned long long DATA_TYPE; 2722 typedef unsigned long long ADDR_TYPE; 2723 2724 #define func26(x) (x & 0x3FFFFFF) 2725 #define func11(x) ((x >> 5) & 0x7FF) 2726 #define ra(x) ((x >> 21) & 0x1F) 2727 #define rb(x) ((x >> 16) & 0x1F) 2728 #define rc(x) (x & 0x1F) 2729 #define fa(x) (((x >> 21) & 0x1F)+32) 2730 #define fb(x) (((x >> 16) & 0x1F)+32) 2731 #define fc(x) ((x & 0x1F)+32) 2732 #define lit8(x) ((x >> 13) & 0xFF) 2733 #define code(x) ((x >> 26) & 0x3F) 2734 2735 #define BIT0 0x0000000000000001ull 2736 #define BIT1 0x0000000000000002ull 2737 #define BIT2 0x0000000000000004ull 2738 #define BIT3 0x0000000000000008ull 2739 #define BIT4 0x0000000000000010ull 2740 #define BIT5 0x0000000000000020ull 2741 #define BIT6 0x0000000000000040ull 2742 #define BIT7 0x0000000000000080ull 2743 #define BIT8 0x0000000000000100ull 2744 #define BIT9 0x0000000000000200ull 2745 #define BIT10 0x0000000000000400ull 2746 #define BIT11 0x0000000000000800ull 2747 #define BIT12 0x0000000000001000ull 2748 #define BIT15 0x0000000000008000ull 2749 #define BIT20 0x100000ull 2750 #define BIT31 0x80000000ull 2751 #define BIT63 0x8000000000000000ull 2752 2753 #define EXTND16 0xffffffffffff0000ull 2754 #define EXTND21 0xffffffffffe00000ull 2755 #define EXTND32 0xffffffff00000000ull 2756 #define MASK16 0xFFFFull 2757 #define MASK21 0x1FFFFFull 2758 #define MASK32 0x00000000FFFFFFFFull 2759 2760 #define ZAP0 0xFFFFFFFFFFFFFF00ull 2761 #define ZAP1 0xFFFFFFFFFFFF00FFull 2762 #define ZAP2 0xFFFFFFFFFF00FFFFull 2763 #define ZAP3 0xFFFFFFFF00FFFFFFull 2764 #define ZAP4 0xFFFFFF00FFFFFFFFull 2765 #define ZAP5 0xFFFF00FFFFFFFFFFull 2766 #define ZAP6 0xFF00FFFFFFFFFFFFull 2767 #define ZAP7 0x00FFFFFFFFFFFFFFull 2768 2769 /**** For get_iclass in decoder.c ***/ 2770 #define EX_OPM 1 /* Optimize Memory, Prefetch etc. */ 2771 #define EX_PAL 2 /* PAL code. */ 2772 #define EX_JMP 3 /* JUMP, Register Addressing Branch */ 2773 #define EX_BRA 4 /* Unconditional Branch */ 2774 #define EX_CBI 5 /* Conditional Branch Integer */ 2775 #define EX_CBF 6 /* Conditional Branch Floating */ 2776 #define EX_ARI 7 /* Logic and Arithmetic */ 2777 #define EX_ADR 8 /* Address calculation , NOT load and store */ 2778 #define EX_LDI 9 /* Load to Integer Reg */ 2779 #define EX_LDF 10 /* Load to Floating Reg */ 2780 #define EX_STI 11 /* Store Integer Value */ 2781 #define EX_STF 12 /* Store Floating Value */ 2782 #define EX_FLO 13 /* Floating Arithmetic and Logic */ 2783 #define EX_CMI 14 /* Conditional Move Int. */ 2784 #define EX_CMF 15 /* Conditional Move Float. */ 2785 2786 #define MEM_PAGE_SIZE 1024*1024 /* 1 Mbyte */ 2787 #define PAGE_MASK 0xFFFFF 2788 #define PAGE_BIT 20 2789 #define TLB_ENTRY 512 2790 #define PAGE_SIZE 8192 /* 8KB page size */ 2791 2792 /************************************************************/ 2793 typedef class architecture_state{ 2794 public: 2795 ADDR_TYPE pc; /* program counter 64-bit width. */ 2796 DATA_TYPE r[32]; /* general purpose 64-bit integer Regs */ 2797 DATA_TYPE f[32]; /* 64-bit width floating point Regs */ 2798 } ARCH_STATE; 2799 2800 struct machine_setting{ 2801 ULL current_argp_flag; 2802 int end_flag; /* If set, the simulation ends. */ 2803 int debug_flag; 2804 int distrib_flag; 2805 int syscall_flag; 2806 int print_state_flag; 2807 int control_trace_flag; 2808 int memory_trace_flag; 2809 int state_trace_flag; 2810 int state_trace_interval; 2811 ULL trace_start; 2812 int dcache_entry_bit; 2813 int dcache_line_bit; 2814 int verbose_interval; 2815 ULL end_tc; 2816 }; 2817 struct evaluate{ 2818 int used_memory; 2819 ULL retired_inst; 2820 }; 2821 2822 class instruction{ 2823 public: 2824 int cache_flush; /* set if syscall chenges the memory */ 2825 ULL tag; /* Tag, asigned in IF stage */ 2826 ADDR_TYPE cpc; /* PC of the instruction */ 2827 ADDR_TYPE t_pc; /* Calculated True Branch Target PC */ 2828 unsigned int ir; /* 32bit instruction code */ 2829 int iclass; /* the class of the instruction */ 2830 int LR1, LR2, LR3, LW; /* Logical Reg No. */ 2831 ULL R1, R2, R3, W; /* Renamed (phisical) Reg No. */ 2832 int isort; /* the sort of the instruction */ 2833 int mem_byte; /* Used for LD/ST instruction */ 2834 ADDR_TYPE Adr; /* LD/ST Memory Address */ 2835 DATA_TYPE Rav; /* The value of Ra */ 2836 DATA_TYPE Rbv; /* The value of Rb */ 2837 DATA_TYPE Rmv; /* The value of Rc */ 2838 DATA_TYPE Rcv; /* The value of Rc */ 2839 /***** Methods *****/ 2840 instruction(); 2841 void Fetch(unsigned long long pc); 2842 void Decode(); 2843 void Rename(); 2844 void RegisterRead(); 2845 void Execute(); 2846 void Memory(); 2847 void WriteBack(); 2848 }; 2849 2850 2851 /* Header File to define the Alpha object code format 2852 * DIGITAL Unix (Alpha AXP), Arranged by Kenji Kise 1999.5 2853 * 2854 * Alpha AXP Type Definitions 2855 * char 1byte 2856 * int 4byte 2857 * long 8byte 2858 * long long 8byte 2859 * float 4 2860 * double 8 2861 * short 2byte 2862 *****************************************************/ 2863 struct FF_filehdr { 2864 unsigned short f_magic; 2865 unsigned short f_nscns; /* use this */ 2866 int f_timdat; 2867 long long f_symptr; 2868 int f_nsyms; 2869 unsigned short f_opthdr; 2870 unsigned short f_flags; 2871 }; 2872 2873 struct FF_aouthdr { 2874 short magic; 2875 short vstamp; 2876 short bldrev; 2877 short padcell; 2878 long long tsize; /* use this */ 2879 long long dsize; /* use this */ 2880 long long bsize; 2881 long long entry; /* use this */ 2882 long long text_start; 2883 long long data_start; 2884 long long bbs_start; 2885 int gprmask; 2886 int fprmask; 2887 long long gp_value; 2888 }; 2889 2890 struct FF_scnhdr { 2891 char s_name[8]; /* use this */ 2892 long long s_paddr; /* use this */ 2893 long long s_vaddr; 2894 long long s_size; /* use this */ 2895 long long s_scnptr; /* use this */ 2896 long long s_relptr; 2897 long long s_lnnoptr; 2898 unsigned short s_nreloc; 2899 unsigned short s_nlnno; 2900 int s_flags; 2901 }; 2902 2903 /************************************************************/ 2904 struct tlb_entry{ 2905 int valid; 2906 unsigned long long adr; 2907 char *ptr; 2908 }; 2909 2910 class Imemory{ 2911 unsigned int *ibuffer; 2912 ADDR_TYPE ibuffer_min_adr; // minimun address of Ibuffer 2913 ADDR_TYPE ibuffer_max_adr; // maximun address of Ibuffer 2914 public: 2915 void Imemory_init(int size, ADDR_TYPE, ADDR_TYPE); 2916 unsigned int instruction_load(ADDR_TYPE); 2917 void instruction_store(ADDR_TYPE, unsigned int data); 2918 }; 2919 2920 class Dmemory{ 2921 struct tlb_entry tlb[TLB_ENTRY]; 2922 DATA_TYPE sbuffer_min; /* Minimun Address of Stack */ 2923 ADDR_TYPE sbuffer_max; /* Maximun Address of Stack */ 2924 ADDR_TYPE dbuffer_min; /* Minimun Address of Data */ 2925 ADDR_TYPE dbuffer_max; /* Maximun Address of Data */ 2926 public: 2927 char *adr_translate(unsigned long long adr); 2928 void set_dbuffer(ADDR_TYPE); 2929 void set_dbuffer(ADDR_TYPE, ADDR_TYPE); 2930 void set_sbuffer(ADDR_TYPE, ADDR_TYPE); 2931 2932 char load_byte( ADDR_TYPE); 2933 unsigned int load_4byte(ADDR_TYPE); 2934 DATA_TYPE load_8byte(ADDR_TYPE); 2935 2936 void store_byte( ADDR_TYPE, char); 2937 void store_4byte(ADDR_TYPE, unsigned int); 2938 void store_8byte(ADDR_TYPE, DATA_TYPE); 2939 2940 DATA_TYPE load(int byte, ADDR_TYPE); 2941 void store(int byte, ADDR_TYPE, DATA_TYPE); 2942 }; 2943 2944 2945 /**** Extern Functions ****/ 2946 extern void debugmode(); 2947 extern void mem_init(struct architecture_state *, 2948 int, char **, char **); 2949 extern ULL get_hex(char *); 2950 extern int get_iclass(DATA_TYPE); 2951 extern int get_isort(unsigned int ir); 2952 extern DATA_TYPE get_store_data(int, DATA_TYPE); 2953 extern DATA_TYPE get_load_data(int, DATA_TYPE); 2954 extern DATA_TYPE execute_branch(unsigned long long *pc, 2955 unsigned long long diff21); 2956 extern DATA_TYPE ex_arith(int code, 2957 unsigned int func11, 2958 DATA_TYPE Rav, 2959 DATA_TYPE Rbv); 2960 extern DATA_TYPE ex_cmov(int code, 2961 unsigned int func11, 2962 DATA_TYPE Rav, 2963 DATA_TYPE Rbv, 2964 DATA_TYPE Rmv); 2965 extern DATA_TYPE execute_jmp(ADDR_TYPE *pc, DATA_TYPE Rbv); 2966 extern DATA_TYPE calculate_adr(int code, DATA_TYPE Rbv, 2967 DATA_TYPE diff16); 2968 extern void execute_pal(instruction *); 2969 extern void ex_branch(int, ADDR_TYPE*, DATA_TYPE, DATA_TYPE);