1 ------------------------------------------------------------ 2 file name: sim.cc 3 0001 /*** Yet Another Alpha Processor Simulator ***/ 4 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 5 0003 /************************************************/ 6 0004 #include "define.h" 7 0005 8 0006 /************************************************/ 9 0007 int main(int argc, char **argv){ 10 0008 printf("%s %s\n", NAME, VER); 11 0009 if(argc==1) usage(); 12 0010 char *p = argv[argc-1]; /* program name */ 13 0011 char **opt = argv; /* options */ 14 0012 15 0013 simple_chip *c = new simple_chip(p, opt); 16 0014 c->loop(); 17 0015 delete c; 18 0016 19 0017 return 0; 20 0018 } 21 0019 /************************************************/ 22 ------------------------------------------------------------ 23 file name: chip.cc 24 0001 /*** Yet Another Alpha Processor Simulator ***/ 25 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 26 0003 /************************************************/ 27 0004 #include "define.h" 28 0005 29 0006 /************************************************/ 30 0007 simple_chip::simple_chip(char *prog, char **opt){ 31 0008 ev = new Env(); 32 0009 ev->sc = new system_config(prog, opt); 33 0010 ev->e = new evaluation_result(); 34 0011 ev->as = new architecture_state(ev); 35 0012 ev->mem = new memory_system(ev); 36 0013 ev->deb = new debug(ev); 37 0014 ev->sys = new system_manager(ev); 38 0015 p = new instruction(ev); 39 0016 } 40 0017 41 0018 /************************************************/ 42 0019 simple_chip::~simple_chip(){ /** destructor **/ 43 0020 print_evaluation_result(ev); 44 0021 } 45 0022 46 0023 /************************************************/ 47 0024 int simple_chip::step(){ 48 0025 p->Fetch(&ev->as->pc); /* pipeline stage 0 */ 49 0026 p->Slot(); /* pipeline stage 1 */ 50 0027 p->Issue(); /* pipeline stage 3 */ 51 0028 p->RegisterRead(); /* pipeline stage 4 */ 52 0029 p->Execute(); /* pipeline stage 5 */ 53 0030 p->Memory(); /* pipeline stage 6 */ 54 0031 p->WriteBack(); 55 0032 56 0033 ev->e->retired_inst++; 57 0034 house_keeper(p); 58 0035 59 0036 return ev->sys->running; 60 0037 } 61 0038 62 0039 #define IB_MSK 0x0ffff /* mask of inst_buf */ 63 0040 /** main loop of the optimized version **/ 64 0041 /************************************************/ 65 0042 void simple_chip::loop(){ 66 0043 instruction **ib = new instruction*[IB_MSK+1]; 67 0044 for(int i=0; isys->running){ 72 0049 int index = (ev->as->pc>>2) & IB_MSK; 73 0050 instruction *pt = ib[index]; 74 0051 75 0052 if(pt->Cpc!=ev->as->pc){ 76 0053 pt->Fetch(&ev->as->pc); 77 0054 pt->Slot(); 78 0055 pt->Issue(); 79 0056 } 80 0057 pt->BackEnd(); 81 0058 82 0059 ev->e->retired_inst++; 83 0060 if(ev->sc->slow_mode) house_keeper(pt); 84 0061 } 85 0062 } 86 0063 /************************************************/ 87 ------------------------------------------------------------ 88 file name: instruction.cc 89 0001 /*** Yet Another Alpha Processor Simulator ***/ 90 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 91 0003 /************************************************/ 92 0004 #include "define.h" 93 0005 #define R_ZERO 31 /** Index of zero register **/ 94 0006 95 0007 /************************************************/ 96 0008 int INTx_OP(int Op){/* 0x10-0x14 OP_INTx */ 97 0009 return ((Op&MSK2)==0x10); 98 0010 } 99 0011 100 0012 /* return 1 if data is written to integer reg. */ 101 0013 /************************************************/ 102 0014 int WR(int Op){ 103 0015 return !((Op&MSK2)==0x14 || (Op&MSK2)==0x20); 104 0016 } 105 0017 106 0018 /************************************************/ 107 0019 int LDAx(int CI){ 108 0020 return (CI==_LDA___ || CI==_LDAH__); 109 0021 } 110 0022 111 0023 /************************************************/ 112 0024 instruction::instruction(Env *ev_t){ 113 0025 ev = ev_t; 114 0026 } 115 0027 116 0028 /************************************************/ 117 0029 void instruction::Fetch(data_t *pc){ 118 0030 ev->mem->ld_inst(pc, &ir); 119 0031 Cpc = *pc; 120 0032 Npc = *pc + 4; 121 0033 } 122 0034 123 0035 /** decode the instruction **/ 124 0036 /************************************************/ 125 0037 void instruction::Slot(){ 126 0038 CI = get_code(ir); /* Code ID */ 127 0039 Op = (ir>>26) & 0x3f; /* Op field */ 128 0040 CM = cmov_ir(ir); /* set if CMOV */ 129 0041 BR = ((Op&MSK4)==0x30); /* 0x30-0x3f branch */ 130 0042 LD = ld_bytes(CI); /* not 0 if load */ 131 0043 ST = st_bytes(CI); /* not 0 if store */ 132 0044 133 0045 int Rc = ir & 0x1f; /* Rc field */ 134 0046 int Ra = (ir>>21)&0x1f; /* Ra field */ 135 0047 int Rb = (ir>>16)&0x1f; /* Rb field */ 136 0048 int Misc = (Op==OP_MISC || Op==OP_PAL); 137 0049 /***************** Rav ********************/ 138 0050 Ai = LDAx(CI); 139 0051 RA = (Ai || LD || Misc) ? R_ZERO : Ra; 140 0052 Ar = !Ai & 141 0053 !(Op==OP_FLTV || Op==OP_FLTI || 142 0054 Op==OP_FLTL || Op==OP_FPTI || 143 0055 (Op&MSK2)==0x24 || /* 0x24-27 STfloat */ 144 0056 (Op&MSK3)==0x30); /* 0x30-37 BR & FBR */ 145 0057 146 0058 /***************** Rbv ********************/ 147 0059 Bi = BR || (INTx_OP(Op) && (ir & BIT12)); 148 0060 RB = (Bi || Misc) ? R_ZERO : Rb; 149 0061 Br = !Bi && !((Op&MSK2)==0x14); /* 0x14-17 */ 150 0062 151 0063 /***************** WriteBack index ********/ 152 0064 WB = (LD || LDAx(CI) || Op==OP_JSR || 153 0065 CI==_BR__ || CI==_BSR_) ? Ra : 154 0066 ((Op&MSK3)==0x10 || /* 0x10-0x17 */ 155 0067 Op==OP_FPTI) ? Rc : R_ZERO; 156 0068 } 157 0069 158 0070 /************************************************/ 159 0071 void instruction::Rename(){ } 160 0072 161 0073 /** genarate the immediate data Imm **/ 162 0074 /************************************************/ 163 0075 void instruction::Issue(){ 164 0076 DATA_TYPE Lit = (ir >> 13) & MASK08; 165 0077 DATA_TYPE D21 = sext21(ir) << 2; 166 0078 DATA_TYPE D16 = (Op!=OP_LDAH) ? sext16(ir) : 167 0079 sext16(ir) << 16; 168 0080 169 0081 Imm = (LD || ST || LDAx(CI)) ? D16 : 170 0082 (BR) ? D21 : (Bi) ? Lit : 0; 171 0083 } 172 0084 173 0085 /** copy data to Rav and Rbv **/ 174 0086 /************************************************/ 175 0087 void instruction::RegisterRead(){ 176 0088 Rav = Ar ? ev->as->r[RA] : Ai ? Imm : 177 0089 ev->as->f[RA]; 178 0090 Rbv = Br ? ev->as->r[RB] : Bi ? Imm : 179 0091 ev->as->f[RB]; 180 0092 if(CM){ 181 0093 Adr = WR(Op) ? ev->as->r[WB] : ev->as->f[WB]; 182 0094 } 183 0095 } 184 0096 185 0097 /** update Rcv, Adr and Npc **/ 186 0098 /************************************************/ 187 0099 void instruction::Execute(){ 188 0100 if(LD || ST){ 189 0101 Adr = (CI==_LDQ_U_ || CI==_STQ_U_) ? 190 0102 (Rbv + Imm) & ~7 : Rbv + Imm; 191 0103 } 192 0104 else if(BR){ 193 0105 Rcv = Cpc+4; 194 0106 Npc = Btaken(CI, Rav) ? Cpc+4+Rbv : Cpc+4; 195 0107 } 196 0108 else if(CM){ /** Conditional move inst. **/ 197 0109 int cm=0; 198 0110 CmovUnit(CI, Rav, &cm); 199 0111 Rcv = (cm) ? Rbv : Adr; 200 0112 } 201 0113 else{ 202 0114 switch(Op){ 203 0115 case OP_JSR : 204 0116 Npc = Rbv & ~3ull; 205 0117 Rcv = Cpc + 4; 206 0118 break; 207 0119 case OP_LDA : Rcv = Rav + Rbv; break; 208 0120 case OP_LDAH: Rcv = Rav + Rbv; break; 209 0121 case OP_INTA: UnitA(CI, Rav, Rbv, &Rcv);break; 210 0122 case OP_INTL: UnitL(CI, Rav, Rbv, &Rcv);break; 211 0123 case OP_INTS: UnitS(CI, Rav, Rbv, &Rcv);break; 212 0124 case OP_INTM: UnitM(CI, Rav, Rbv, &Rcv);break; 213 0125 case OP_ITFP: FuITFP(ir,Rav, Rbv, &Rcv);break; 214 0126 case OP_FLTL: FuFLTL(ir,Rav, Rbv, &Rcv);break; 215 0127 case OP_FPTI: FuFPTI(ir,Rav, Rbv, &Rcv);break; 216 0128 case OP_FLTI: FuFLTI(ir,Rav, Rbv, &Rcv);break; 217 0129 case OP_PAL : Rcv=0; break; 218 0130 case OP_MISC: Rcv=0; break; 219 0131 default: printf("** ExeUnit_def: %x", CI); 220 0132 } 221 0133 } 222 0134 ev->as->pc = Npc; 223 0135 } 224 0136 225 0137 /** store Rav to mem or load to Rcv **/ 226 0138 /************************************************/ 227 0139 void instruction::Memory(){ 228 0140 if(LD){ 229 0141 data_t tmp; 230 0142 ev->mem->mm->ld_8byte(&Adr, &tmp); 231 0143 set_ld_data(CI, LD, &Adr, &tmp, &Rcv); 232 0144 } 233 0145 else if(ST){ 234 0146 data_t tmp; 235 0147 DATA_TYPE mask; 236 0148 set_st_data(CI, ST, &Adr, &Rav, &tmp, &mask); 237 0149 ev->mem->mm->st_8byte(&Adr, &tmp, mask); 238 0150 } 239 0151 } 240 0152 241 0153 /** PAL or copy Rcv into the regfile **/ 242 0154 /************************************************/ 243 0155 void instruction::WriteBack(){ 244 0156 if(Op==OP_PAL) ev->sys->execute_pal(this); 245 0157 if(WB!=R_ZERO){ 246 0158 if(WR(Op)) ev->as->r[WB] = Rcv; 247 0159 else ev->as->f[WB] = Rcv; 248 0160 } 249 0161 } 250 0162 251 0163 /** back-end stages for the optimized version **/ 252 0164 /************************************************/ 253 0165 void instruction::BackEnd(){ 254 0166 /***** RegisterRead **************************/ 255 0167 Rav = Ar ? ev->as->r[RA] : Ai ? Imm : 256 0168 ev->as->f[RA]; 257 0169 Rbv = Br ? ev->as->r[RB] : Bi ? Imm : 258 0170 ev->as->f[RB]; 259 0171 if(CM){ 260 0172 Adr = WR(Op) ? ev->as->r[WB] : ev->as->f[WB]; 261 0173 } 262 0174 263 0175 /***** Execute ********************************/ 264 0176 if(LD || ST){ 265 0177 Adr = (CI==_LDQ_U_ || CI==_STQ_U_) ? 266 0178 (Imm+Rbv) & ~7 : Imm+Rbv; 267 0179 } 268 0180 else if(BR){ 269 0181 Rcv = Cpc+4; 270 0182 Npc = Btaken(CI, Rav) ? Cpc+4+Rbv : Cpc+4; 271 0183 } 272 0184 else if(CM){ /** Conditional move inst. **/ 273 0185 int cm=0; 274 0186 CmovUnit(CI, Rav, &cm); 275 0187 Rcv = (cm) ? Rbv : Adr; 276 0188 } 277 0189 else{ 278 0190 switch(Op){ 279 0191 case OP_JSR : 280 0192 Npc = Rbv & ~3ull; 281 0193 Rcv = Cpc + 4; 282 0194 break; 283 0195 case OP_LDA : Rcv = Rav + Rbv; break; 284 0196 case OP_LDAH: Rcv = Rav + Rbv; break; 285 0197 case OP_INTA: UnitA(CI, Rav, Rbv, &Rcv);break; 286 0198 case OP_INTL: UnitL(CI, Rav, Rbv, &Rcv);break; 287 0199 case OP_INTS: UnitS(CI, Rav, Rbv, &Rcv);break; 288 0200 case OP_INTM: UnitM(CI, Rav, Rbv, &Rcv);break; 289 0201 case OP_ITFP: FuITFP(ir,Rav, Rbv, &Rcv);break; 290 0202 case OP_FLTL: FuFLTL(ir,Rav, Rbv, &Rcv);break; 291 0203 case OP_FPTI: FuFPTI(ir,Rav, Rbv, &Rcv);break; 292 0204 case OP_FLTI: FuFLTI(ir,Rav, Rbv, &Rcv);break; 293 0205 case OP_PAL : Rcv=0; break; 294 0206 case OP_MISC: Rcv=0; break; 295 0207 default: printf("** ExeUnit_def: %x", CI); 296 0208 } 297 0209 } 298 0210 ev->as->pc = Npc; 299 0211 300 0212 /***** Memory *********************************/ 301 0213 if(LD){ 302 0214 data_t tmp; 303 0215 ev->mem->mm->ld_8byte(&Adr, &tmp); 304 0216 set_ld_data(CI, LD, &Adr, &tmp, &Rcv); 305 0217 } 306 0218 else if(ST){ 307 0219 data_t tmp; 308 0220 DATA_TYPE mask; 309 0221 set_st_data(CI, ST, &Adr, &Rav, &tmp, &mask); 310 0222 ev->mem->mm->st_8byte(&Adr, &tmp, mask); 311 0223 } 312 0224 313 0225 /***** WriteBack ******************************/ 314 0226 if(Op==OP_PAL) ev->sys->execute_pal(this); 315 0227 if(WB!=R_ZERO){ 316 0228 if(WR(Op)) ev->as->r[WB]=Rcv; 317 0229 else ev->as->f[WB]=Rcv; 318 0230 } 319 0231 } 320 0232 /************************************************/ 321 ------------------------------------------------------------ 322 file name: memory.cc 323 0001 /*** Yet Another Alpha Processor Simulator ***/ 324 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 325 0003 /************************************************/ 326 0004 #include "define.h" 327 0005 328 0006 /************************************************/ 329 0007 int ld_bytes(int CI){ 330 0008 switch(CI){ 331 0009 case _LDQ___: return 8; 332 0010 case _LDQ_L_: return 8; 333 0011 case _LDQ_U_: return 8; 334 0012 case _LDG___: return 8; 335 0013 case _LDT___: return 8; 336 0014 case _LDF___: return 8; 337 0015 case _LDL___: return 4; 338 0016 case _LDS___: return 4; 339 0017 case _LDL_L_: return 4; 340 0018 case _OPC0C_: return 2; 341 0019 case _OPC0A_: return 1; 342 0020 } 343 0021 return 0; 344 0022 } 345 0023 346 0024 /************************************************/ 347 0025 int st_bytes(int CI){ 348 0026 switch(CI){ 349 0027 case _STQ___: return 8; 350 0028 case _STQ_C_: return 8; 351 0029 case _STQ_U_: return 8; 352 0030 case _STG___: return 8; 353 0031 case _STT___: return 8; 354 0032 case _STF___: return 8; 355 0033 case _STL___: return 4; 356 0034 case _STS___: return 4; 357 0035 case _STL_C_: return 4; 358 0036 case _OPC0D_: return 2; 359 0037 case _OPC0E_: return 1; 360 0038 } 361 0039 return 0; 362 0040 } 363 0041 364 0042 /************************************************/ 365 0043 void set_ld_data(int CI, int n, data_t *adr, 366 0044 data_t *in, data_t *out){ 367 0045 int off8 = (*adr & 7) << 3; 368 0046 switch(n){ 369 0047 case 4: 370 0048 if(CI==_LDL___ || CI==_LDL_L_){ 371 0049 *out = sext((*in >> off8) & MASK32); 372 0050 } 373 0051 else if(CI==_LDS___){ 374 0052 DATA_TYPE tmp = (*in >> off8) & MASK32; 375 0053 DATA_TYPE rt = tmp; 376 0054 rt = (tmp >> 31) & 0x1ull; 377 0055 rt = (rt << 11) | (map_s(tmp) & 0x7ffull); 378 0056 rt = (rt << 23) | (tmp & 0x7FFFFFull); 379 0057 rt = rt << 29; 380 0058 *out = rt; 381 0059 } 382 0060 break; 383 0061 case 8: *out = *in; break; 384 0062 case 2: *out = (*in >> off8) & MASK16; break; 385 0063 case 1: *out = (*in >> off8) & MASK08; break; 386 0064 } 387 0065 } 388 0066 389 0067 /************************************************/ 390 0068 void set_st_data(int CI, int n, data_t *adr, 391 0069 data_t *in, data_t *out, 392 0070 DATA_TYPE *msk){ 393 0071 int off8 = (*adr & 7) << 3; 394 0072 if(CI==_STS___){ 395 0073 DATA_TYPE tmp; 396 0074 uint_32t intt = 0; 397 0075 intt |= ((*in >> 29) & 0x3FFFFFFFul); 398 0076 intt |= ((*in >> 32) & 0xc0000000ul); 399 0077 memcpy(&tmp, &intt, 4); 400 0078 *out = (tmp & MASK32) << off8; 401 0079 *msk = ~(MASK32 << off8); 402 0080 } 403 0081 else{ 404 0082 switch(n){ 405 0083 case 4: 406 0084 *out = (*in & MASK32) << off8; 407 0085 *msk = ~(MASK32 << off8); 408 0086 break; 409 0087 case 8: 410 0088 *out = *in; 411 0089 *msk = 0; 412 0090 break; 413 0091 case 2: 414 0092 *out = (*in & MASK16) << off8; 415 0093 *msk = ~(MASK16 << off8); 416 0094 break; 417 0095 case 1: 418 0096 *out = (*in & MASK08) << off8; 419 0097 *msk = ~(MASK08 << off8); 420 0098 break; 421 0099 } 422 0100 } 423 0101 } 424 0102 425 0103 /************************************************/ 426 0104 inline uint_32t gen_tag(uint_32t adr){ 427 0105 return (adr & 0xffffffc0); 428 0106 } 429 0107 430 0108 /************************************************/ 431 0109 void memory_system::ld_inst(data_t *a, 432 0110 INST_TYPE *ir){ 433 0111 data_t d; 434 0112 mm->ld_8byte(a, &d); 435 0113 if(*a%8==0) *ir = d & MASK32; 436 0114 if(*a%8==4) *ir = (d>>32) & MASK32; 437 0115 } 438 0116 439 0117 /************************************************/ 440 0118 void memory_system::ld_8byte(data_t *a, data_t *d){ 441 0119 mm->ld_8byte(a, d); 442 0120 } 443 0121 444 0122 void memory_system::st_8byte(data_t *a, data_t *d, 445 0123 DATA_TYPE msk){ 446 0124 mm->st_8byte(a, d, msk); 447 0125 } 448 0126 449 0127 /************************************************/ 450 0128 memory_system::~memory_system(){} 451 0129 452 0130 /************************************************/ 453 0131 memory_system::memory_system(Env *ev_t){ 454 0132 ev = ev_t; 455 0133 mm = new main_memory(ev); 456 0134 457 0135 char *prog_name = ev->sc->program_name; 458 0136 459 0137 /*** Read memory image from the file ***/ 460 0138 FILE *fp; 461 0139 if((fp = fopen(prog_name, "r")) == NULL) { 462 0140 fprintf(stderr, "Bad file name: %s\n", 463 0141 prog_name); 464 0142 exit(1); 465 0143 } 466 0144 char buf[4096]; 467 0145 fgets(buf, 4096, fp); /** File Format Check **/ 468 0146 if(strncmp(buf+3, "SimAlpha", 8)){ 469 0147 fprintf(stderr, "%s: Not a SimAlpha file.\n", 470 0148 prog_name); 471 0149 exit(1); 472 0150 } 473 0151 while(!feof(fp)){ 474 0152 fgets(buf, 4096, fp); 475 0153 if(*buf=='@'){ 476 0154 477 0155 int ost=0; /* find the offset of dat */ 478 0156 for(int i=0; i<32; i++){ 479 0157 if(*(buf+i)==' '){ ost=i; break; } 480 0158 } 481 0159 482 0160 ADDR_TYPE adr = get_hex(buf+1); 483 0161 DATA_TYPE dat = get_hex(buf+ost+1); 484 0162 data_t a,d; 485 0163 a = adr; 486 0164 d = dat; 487 0165 mm->st_8byte(&a, &d, 0); 488 0166 } 489 0167 } 490 0168 fclose(fp); 491 0169 } 492 0170 493 0171 /************************************************/ 494 0172 void memory_system::ld_nbyte(int n, data_t *a, 495 0173 data_t *d){ 496 0174 if(*a%n!=0) 497 0175 printf("*** ld_nbyte %d miss-align.\n", n); 498 0176 if(n!=1 && n!=2 && n!=4 && n!=8) 499 0177 printf("*** Error in ld_nbyte %d.\n", n); 500 0178 501 0179 ld_8byte(a, d); /** Type Conversion **/ 502 0180 if(n==8) return; 503 0181 504 0182 int offset = *a & 7; 505 0183 if(n==4){ 506 0184 DATA_TYPE dt = (*d>>(offset*8))&MASK32; 507 0185 *d=dt; 508 0186 } 509 0187 else if(n==2){ 510 0188 DATA_TYPE dt = (*d>>(offset*8))&MASK16; 511 0189 *d=dt; 512 0190 } 513 0191 else if(n==1){ 514 0192 DATA_TYPE dt = (*d>>(offset*8))&MASK08; 515 0193 *d=dt; 516 0194 } 517 0195 } 518 0196 519 0197 /************************************************/ 520 0198 void memory_system::st_nbyte(int n, data_t *a, 521 0199 data_t *d){ 522 0200 if(*a%n!=0) 523 0201 printf("*** st_nbyte %d miss-alig.\n", n); 524 0202 if(n!=1 && n!=2 && n!=4 && n!=8) 525 0203 printf("*** Error in st_nbyte %d.\n", n); 526 0204 527 0205 int offset = *a & 7; 528 0206 DATA_TYPE mask=0; 529 0207 530 0208 if(n==4){ 531 0209 mask = ~(MASK32 << offset*8); 532 0210 DATA_TYPE dt = (*d&MASK32)<> BLOCK_MASK_BIT); 553 0231 } 554 0232 555 0233 /************************************************/ 556 0234 main_memory::main_memory(Env *ev_t){ 557 0235 ev = ev_t; 558 0236 for(int i=0; ie->used_memory_block++; 575 0253 return ret; 576 0254 } 577 0255 578 0256 /************************************************/ 579 0257 void main_memory::ld_8byte(data_t *a, data_t *d){ 580 0258 uint_32t adr = *a; 581 0259 data_t *tt = block_table[mm_index(adr)]; 582 0260 data_t *ptr = (tt!=NULL) ? tt : allocblock(a); 583 0261 int offset = (adr & BLOCK_MASK)>>DATA_T_BIT; 584 0262 *d = ptr[offset]; 585 0263 } 586 0264 587 0265 /************************************************/ 588 0266 void main_memory::st_8byte(data_t *a, data_t *d, 589 0267 DATA_TYPE msk){ 590 0268 uint_32t adr = *a; 591 0269 data_t *tt = block_table[mm_index(adr)]; 592 0270 data_t *ptr = (tt!=NULL) ? tt : allocblock(a); 593 0271 int offset = (adr & BLOCK_MASK)>>DATA_T_BIT; 594 0272 ptr[offset] = (msk==0) ? *d : 595 0273 (ptr[offset] & msk) | *d; 596 0274 } 597 0275 /************************************************/ 598 ------------------------------------------------------------ 599 file name: arithmetic.cc 600 0001 /*** Yet Another Alpha Processor Simulator ***/ 601 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 602 0003 /************************************************/ 603 0004 #include "define.h" 604 0005 605 0006 /** sign extentions **/ 606 0007 /************************************************/ 607 0008 DATA_TYPE sext(DATA_TYPE d){ 608 0009 return (d & BIT31) ? d | EXTND32 : d & MASK32; 609 0010 } 610 0011 /************************************************/ 611 0012 DATA_TYPE sext16(DATA_TYPE d){ 612 0013 return (d & BIT15) ? d | EXTND16 : d & MASK16; 613 0014 } 614 0015 /************************************************/ 615 0016 DATA_TYPE sext21(DATA_TYPE d){ 616 0017 return (d & BIT20) ? d | EXTND21 : d & MASK21; 617 0018 } 618 0019 619 0020 /************************************************/ 620 0021 uint_64t bzap(uint_64t Rav, int byte_mask){ 621 0022 if(byte_mask & BIT0) Rav &= ZAP0; 622 0023 if(byte_mask & BIT1) Rav &= ZAP1; 623 0024 if(byte_mask & BIT2) Rav &= ZAP2; 624 0025 if(byte_mask & BIT3) Rav &= ZAP3; 625 0026 if(byte_mask & BIT4) Rav &= ZAP4; 626 0027 if(byte_mask & BIT5) Rav &= ZAP5; 627 0028 if(byte_mask & BIT6) Rav &= ZAP6; 628 0029 if(byte_mask & BIT7) Rav &= ZAP7; 629 0030 return Rav; 630 0031 } 631 0032 632 0033 /** 0x16 IEEE floating-point instruction **/ 633 0034 /************************************************/ 634 0035 void FuFLTI(INST_TYPE ir, DATA_TYPE Rav, 635 0036 DATA_TYPE Rbv, DATA_TYPE *w){ 636 0037 int CI= get_code(ir); 637 0038 DATA_TYPE Rcv=0; 638 0039 int func4 = (ir>>5) & 0xF; 639 0040 int func11 = (ir>>5) & 0x7FF; 640 0041 double Fav=0.0, Fbv=0.0, Fcv=0.0; 641 0042 memcpy(&Fav, &Rav, 8); 642 0043 memcpy(&Fbv, &Rbv, 8); 643 0044 644 0045 switch(func4){ 645 0046 case 0x0: Fcv=Fav + Fbv; break; 646 0047 case 0x1: Fcv=Fav - Fbv; break; 647 0048 case 0x2: Fcv=Fav * Fbv; break; 648 0049 case 0x5: Fcv=(Fav==Fbv) ? 2.0 : 0.0; break; 649 0050 case 0x6: Fcv=(Fav< Fbv) ? 2.0 : 0.0; break; 650 0051 case 0x7: Fcv=(Fav<=Fbv) ? 2.0 : 0.0; break; 651 0052 case 0xe: Fcv=(double)(int_64t)Rbv; break; 652 0053 case 0x4: 653 0054 Fcv=(isnan(Fav) || isnan(Fbv)) ? 2.0 : 0.0; 654 0055 break; 655 0056 case 0xc: { // CVTTS 656 0057 memcpy(&Fcv, &Rbv, 8); 657 0058 float tmp = (float)Fcv; 658 0059 Fcv = tmp; 659 0060 break; 660 0061 } 661 0062 case 0x3: // DIVT 662 0063 if(Fbv==0.0){ Fcv = 0.0; break; } 663 0064 Fcv = (double)(Fav / Fbv); 664 0065 break; 665 0066 case 0xf: { // CVTTQ 666 0067 int_64t tmp; 667 0068 tmp = (int_64t)Fbv; 668 0069 memcpy(&Fcv, &tmp, 8); 669 0070 break; 670 0071 } 671 0072 default: 672 0073 printf("** SimAlpha FuFLTI %x\n", CI); 673 0074 exit(1); 674 0075 } 675 0076 676 0077 switch(func11){ 677 0078 case 0x0bc: 678 0079 case 0x03c: 679 0080 case 0x07c: 680 0081 case 0x0fc: 681 0082 case 0x7bc: 682 0083 case 0x73c: 683 0084 case 0x77c: 684 0085 case 0x7fc: // CVTQS 685 0086 Fcv = (double)(int_64t)Rbv; 686 0087 break; 687 0088 } 688 0089 689 0090 memcpy(&Rcv, &Fcv, 8); 690 0091 *w = Rcv; 691 0092 } 692 0093 693 0094 /** 0x1c Floating-point to integer register **/ 694 0095 /************************************************/ 695 0096 void FuFPTI(INST_TYPE ir, DATA_TYPE Rav, 696 0097 DATA_TYPE Rbv, DATA_TYPE *w){ 697 0098 int CI= get_code(ir); 698 0099 DATA_TYPE Rcv=0; 699 0100 int func11 = (ir>>5) & 0x7FF; 700 0101 double Fav=0.0, Fbv=0.0; 701 0102 memcpy(&Fav, &Rav, 8); 702 0103 memcpy(&Fbv, &Rbv, 8); 703 0104 704 0105 switch(func11){ 705 0106 case 0x000: 706 0107 Rcv = (Rbv & BIT7) ? 707 0108 Rbv |= EXTND8 : (Rbv & 0xffull); 708 0109 break; 709 0110 case 0x001: // SEXTW(Sign Extend Word) 710 0111 Rcv = (Rbv & BIT15) ? 711 0112 Rbv |= EXTND16 : (Rbv & 0xffffull); 712 0113 break; 713 0114 case 0x070: // FTOIT: Rc <= Fav 714 0115 Rcv = Rav; 715 0116 break; 716 0117 case 0x078: // FTOIS: Rc <= Fav 717 0118 Rcv = ((Rav>>32) & 0xc0000000) 718 0119 | ((Rav >> 29) & 0x3fffffff); 719 0120 if(Rav & BIT63) Rcv |= EXTND32; 720 0121 break; 721 0122 722 0123 default: 723 0124 printf("** SimAlpha FuFPTI %x\n", CI); 724 0125 exit(1); 725 0126 } 726 0127 *w = Rcv; 727 0128 } 728 0129 729 0130 /** 0x17 Floating-point instruction **/ 730 0131 /************************************************/ 731 0132 void FuFLTL(INST_TYPE ir, DATA_TYPE Rav, 732 0133 DATA_TYPE Rbv, DATA_TYPE *w){ 733 0134 int CI= get_code(ir); 734 0135 DATA_TYPE Rcv=0; 735 0136 int func11 = (ir>>5) & 0x7FF; 736 0137 double Fav=0.0, Fbv=0.0, Fcv=0.0; 737 0138 memcpy(&Fav, &Rav, 8); 738 0139 memcpy(&Fbv, &Rbv, 8); 739 0140 740 0141 switch(func11){ 741 0142 case 0x020: { /*__CPYS; Copy Sign */ 742 0143 uint_64t tmp=0; 743 0144 tmp |= (Rav & BIT63); 744 0145 tmp |= (Rbv & ~BIT63); 745 0146 memcpy(&Fcv, &tmp, 8); 746 0147 break; 747 0148 } 748 0149 case 0x021: { /*__CPYSN; Copy Sign Negative */ 749 0150 uint_64t tmp=0; 750 0151 tmp |= (~Rav & BIT63); 751 0152 tmp |= ( Rbv & ~BIT63); 752 0153 memcpy(&Fcv, &tmp, 8); 753 0154 break; 754 0155 } 755 0156 /*__CPYSE; Copy Sign and Exponent */ 756 0157 case 0x022: { 757 0158 uint_64t tmp=0; 758 0159 tmp |= (Rav & 0xFFF0000000000000ull); 759 0160 tmp |= (Rbv & ~0xFFF0000000000000ull); 760 0161 memcpy(&Fcv, &tmp, 8); 761 0162 break; 762 0163 } 763 0164 case 0x010: { /*__CVTLQ; */ 764 0165 uint_64t tmp = 0; 765 0166 tmp = 0; 766 0167 tmp |= ((Rbv>>32) & 0xc0000000ull); 767 0168 tmp |= ((Rbv>>29) & 0x3fffffffull); 768 0169 if(tmp & BIT31) tmp |= EXTND32; 769 0170 memcpy(&Fcv, &tmp, 8); 770 0171 break; 771 0172 } 772 0173 case 0x030: { /*__CVTQL; */ 773 0174 DATA_TYPE tmp = 0; 774 0175 // SimpleScalar has a bug? 775 0176 tmp |= (((Rbv << 32) & 776 0177 0xc000000000000000ull)); 777 0178 tmp |= (((Rbv << 29) & 778 0179 0x07ffffffe0000000ull)); 779 0180 memcpy(&Fcv, &tmp, 8); 780 0181 break; 781 0182 } 782 0183 case 0x24: /* __MT_FPCR */ 783 0184 /* Move Fav to Floating-point 784 0185 Control Register 785 0186 Return 0.0 for the simplicity. 786 0187 */ 787 0188 Fcv=0.0; break; 788 0189 case 0x25: /* __MF_FPCR */ 789 0190 /* Move from Floating-point 790 0191 Control Register to Fa 791 0192 Return 0.0 for the simplicity. 792 0193 */ 793 0194 Fcv=0.0; break; 794 0195 default: 795 0196 printf("** SimAlpha FuFLTL %x\n", CI); 796 0197 exit(1); 797 0198 } 798 0199 memcpy(&Rcv, &Fcv, 8); 799 0200 *w = Rcv; 800 0201 } 801 0202 802 0203 /** 0x14 Integer to floating-point register **/ 803 0204 /************************************************/ 804 0205 void FuITFP(INST_TYPE ir, DATA_TYPE Rav, 805 0206 DATA_TYPE Rbv, DATA_TYPE *w){ 806 0207 int CI= get_code(ir); 807 0208 DATA_TYPE Rcv=0; 808 0209 int func11 = (ir>>5) & 0x7FF; 809 0210 double Fav=0.0, Fbv=0.0, Fcv=0.0; 810 0211 memcpy(&Fav, &Rav, 8); 811 0212 memcpy(&Fbv, &Rbv, 8); 812 0213 813 0214 switch(func11){ 814 0215 case 0x024: // ITOFT 815 0216 memcpy(&Fcv, &Rav, 8); 816 0217 break; 817 0218 818 0219 case 0x004: { // ITOFS 819 0220 DATA_TYPE tmp = 0; 820 0221 tmp = ((Rav & BIT31) << 32) | 821 0222 (map_s(Rav) << 52) | 822 0223 ((Rav & 0x7fffff) << 29); 823 0224 memcpy(&Fcv, &tmp, 8); 824 0225 break; 825 0226 } 826 0227 case 0x0ab: // SQRTT 827 0228 Fcv = sqrt(Fbv); 828 0229 break; 829 0230 830 0231 default: 831 0232 printf("** SimAlpha FuITFP %x\n", CI); 832 0233 exit(1); 833 0234 } 834 0235 memcpy(&Rcv, &Fcv, 8); 835 0236 *w = Rcv; 836 0237 } 837 0238 838 0239 /** Integer Logic Unit **/ 839 0240 /************************************************/ 840 0241 void UnitL(int CI, DATA_TYPE a, 841 0242 DATA_TYPE b, DATA_TYPE *c){ 842 0243 switch(CI){ 843 0244 case _BIS___: *c = a | b; break; 844 0245 case _AND___: *c = a & b; break; 845 0246 case _BIC___: *c = a & ~b; break; 846 0247 case _ORNOT_: *c = a | ~b; break; 847 0248 case _XOR___: *c = a ^ b; break; 848 0249 case _EQV___: *c = a ^ ~b; break; 849 0250 case _AMASK_: *c=b & ~CPU_FEATURE_MASK; break; 850 0251 case _IMPLVER:*c=IMPLEMENTATION_VERSION; break; 851 0252 default: 852 0253 printf("** SimAlpha AluLogi %x\n", CI); 853 0254 } 854 0255 } 855 0256 856 0257 /** Integer Arithmetic **/ 857 0258 /************************************************/ 858 0259 void UnitA(int CI, DATA_TYPE a, 859 0260 DATA_TYPE b, DATA_TYPE *c){ 860 0261 switch(CI){ 861 0262 case _S4ADDQ: *c = (a<<2) + b; break; 862 0263 case _ADDQ__: *c = a + b; break; 863 0264 case _SUBQ__: *c = a - b; break; 864 0265 case _ADDL__: *c = sext(a + b); break; 865 0266 case _S4ADDL: *c = sext((a<<2) + b); break; 866 0267 case _SUBL__: *c = sext(a - b); break; 867 0268 case _S4SUBL: *c = sext((a<<2) - b); break; 868 0269 case _S8ADDL: *c = sext((a<<3) + b); break; 869 0270 case _S8SUBL: *c = sext((a<<3) - b); break; 870 0271 case _CMPULT: *c = (a < b); break; 871 0272 case _S4SUBQ: *c = (a<<2) - b; break; 872 0273 case _S8ADDQ: *c = (a<<3) + b; break; 873 0274 case _S8SUBQ: *c = (a<<3) - b; break; 874 0275 case _CMPEQ_: *c=((int_64t)a==(int_64t)b);break; 875 0276 case _CMPULE: *c=(a <= b); break; 876 0277 case _CMPLT_: *c=((int_64t)a< (int_64t)b);break; 877 0278 case _CMPLE_: *c=((int_64t)a<=(int_64t)b);break; 878 0279 case _CMPBGE: 879 0280 *c=0; 880 0281 if((a & ~ZAP0)>=(b & ~ZAP0)) *c|=BIT0; 881 0282 if((a & ~ZAP1)>=(b & ~ZAP1)) *c|=BIT1; 882 0283 if((a & ~ZAP2)>=(b & ~ZAP2)) *c|=BIT2; 883 0284 if((a & ~ZAP3)>=(b & ~ZAP3)) *c|=BIT3; 884 0285 if((a & ~ZAP4)>=(b & ~ZAP4)) *c|=BIT4; 885 0286 if((a & ~ZAP5)>=(b & ~ZAP5)) *c|=BIT5; 886 0287 if((a & ~ZAP6)>=(b & ~ZAP6)) *c|=BIT6; 887 0288 if((a & ~ZAP7)>=(b & ~ZAP7)) *c|=BIT7; 888 0289 break; 889 0290 890 0291 default: 891 0292 printf("** SimAlpha AluUnit %x\n", CI); 892 0293 } 893 0294 } 894 0295 895 0296 /************************************************/ 896 0297 inline DATA_TYPE B4(DATA_TYPE b){ 897 0298 return ((b&0x7)==0) ? 0 : 64 - ((b&0x7)<<3); 898 0299 } 899 0300 900 0301 inline DATA_TYPE B3(DATA_TYPE b){ 901 0302 return (b & 0x7); 902 0303 } 903 0304 904 0305 inline DATA_TYPE B7(DATA_TYPE b){ 905 0306 return (b & 0x7)<<3; 906 0307 } 907 0308 908 0309 /************************************************/ 909 0310 void UnitS(int CI, DATA_TYPE a, 910 0311 DATA_TYPE b, DATA_TYPE *c){ 911 0312 uint_32t msk, loc; /* byte_mask, byte_loc */ 912 0313 switch(CI){ 913 0314 case _SLL___: *c = a<<(b & 0x3F); break; 914 0315 case _SRL___: *c = a>>(b & 0x3F); break; 915 0316 case _SRA___: *c =(int_64t)a>>(b & 0x3F); break; 916 0317 case _ZAPNOT: *c = bzap(a, (int)~b); break; 917 0318 case _ZAP___: *c = bzap(a, (int)b ); break; 918 0319 case _EXTBL_: *c = (a>>B7(b)) & MASK08; break; 919 0320 case _EXTWL_: *c = (a>>B7(b)) & MASK16; break; 920 0321 case _EXTLL_: *c = (a>>B7(b)) & MASK32; break; 921 0322 case _EXTQL_: *c = a>>B7(b); break; 922 0323 case _EXTWH_: *c = (a<>8); 930 0331 break; 931 0332 case _MSKLH_: *c = bzap(a, (0x0fu<>8); 932 0333 break; 933 0334 case _MSKQH_: *c = bzap(a, (0xffu<>8); 934 0335 break; 935 0336 case _INSBL_: 936 0337 *c =bzap(a<>8); 949 0350 loc = (uint_32t)(64 - ((b & 0x7)<<3)) & 0x3f; 950 0351 *c = bzap((a >> loc), ~msk); 951 0352 break; 952 0353 case _INSLH_: 953 0354 msk = (uint_32t)((0xFull << (b & 0x7))>>8); 954 0355 loc = (uint_32t)(64 - ((b & 0x7)<<3)) & 0x3f; 955 0356 *c = bzap((a >> loc), ~msk); 956 0357 break; 957 0358 case _INSQH_: 958 0359 msk = (uint_32t)((0xFFull << (b & 0x7))>>8); 959 0360 loc = (uint_32t)(64 - ((b & 0x7)<<3)) & 0x3f; 960 0361 *c = bzap((a >> loc), ~msk); 961 0362 break; 962 0363 default: 963 0364 printf("** SimAlpha ShiftUnit %x\n", CI); 964 0365 } 965 0366 } 966 0367 967 0368 /** Convert double to uint_64t **/ 968 0369 /************************************************/ 969 0370 double Fcv(DATA_TYPE a){ 970 0371 double Fav; 971 0372 memcpy(&Fav, &a, 8); 972 0373 return Fav; 973 0374 } 974 0375 975 0376 /** 64 bit multiply Input of A and B **/ 976 0377 /** output of High 64b and Low 64b **/ 977 0378 /************************************************/ 978 0379 void mul128(DATA_TYPE a, DATA_TYPE b, 979 0380 DATA_TYPE *rh, DATA_TYPE *rl){ 980 0381 DATA_TYPE ah,al, bh, bl; 981 0382 DATA_TYPE x,y,z; 982 0383 int carry=0; /* has a value of 0, 1 or 2 */ 983 0384 984 0385 ah = a >> 32; 985 0386 al = a & 0xFFFFFFFF; 986 0387 987 0388 bh = b >> 32; 988 0389 bl = b & 0xFFFFFFFF; 989 0390 990 0391 x = al*bl; 991 0392 y = (al*bh << 32); 992 0393 z = x + y; 993 0394 if(z> 32)+(ah*bl >> 32)+carry; 1001 0402 } 1002 0403 1003 0404 /************************************************/ 1004 0405 void UnitM(int CI, DATA_TYPE a, 1005 0406 DATA_TYPE b, DATA_TYPE *c){ 1006 0407 DATA_TYPE tmp2, tmp3; 1007 0408 switch(CI){ 1008 0409 case _MULL__: *c = sext(a*b); break; 1009 0410 case _MULQ__: mul128(a, b, &tmp2, c); break; 1010 0411 case _UMULH_: mul128(a, b, c, &tmp3); break; 1011 0412 default: 1012 0413 *c = 0; 1013 0414 printf("** SimAlpha MulUnit %x\n", CI); 1014 0415 } 1015 0416 } 1016 0417 1017 0418 /** Integer Arithmetic and Logic Unit **/ 1018 0419 /************************************************/ 1019 0420 void CmovUnit(int CI, DATA_TYPE a, int *cm){ 1020 0421 double Fav =0.0; 1021 0422 switch(CI){ 1022 0423 case _CMOVEQ : *cm=(a==0); break; 1023 0424 case _CMOVNE : *cm=(a!=0); break; 1024 0425 case _CMOVLT : *cm=((int_64t)a< 0); break; 1025 0426 case _CMOVGE : *cm=((int_64t)a>=0); break; 1026 0427 case _CMOVLE : *cm=((int_64t)a<=0); break; 1027 0428 case _CMOVGT : *cm=((int_64t)a> 0); break; 1028 0429 case _CMOVLBC: *cm=(!(a & 1)); break; 1029 0430 case _CMOVLBS: *cm=(int)(a & 1); break; 1030 0431 case _FCMOVEQ: 1031 0432 memcpy(&Fav, &a, 8); 1032 0433 *cm = (Fav==0.0); 1033 0434 break; 1034 0435 case _FCMOVNE: 1035 0436 memcpy(&Fav, &a, 8); 1036 0437 *cm = (Fav!=0.0); 1037 0438 break; 1038 0439 default: 1039 0440 printf("** SimAlpha CmovUnit %x\n", CI); 1040 0441 } 1041 0442 } 1042 0443 1043 0444 /** calculate branch condition : taken? **/ 1044 0445 /************************************************/ 1045 0446 int Btaken(int CI, DATA_TYPE a){ 1046 0447 int taken = 0; 1047 0448 switch(CI){ 1048 0449 case _BEQ_: taken = (a==0); break; 1049 0450 case _BNE_: taken = (a!=0); break; 1050 0451 case _BR__: taken = 1; break; 1051 0452 case _BSR_: taken = 1; break; 1052 0453 case _BLE_: taken = ((int_64t)a<=0); break; 1053 0454 case _BLT_: taken = ((int_64t)a< 0); break; 1054 0455 case _BGE_: taken = ((int_64t)a>=0); break; 1055 0456 case _BGT_: taken = ((int_64t)a> 0); break; 1056 0457 case _BLGC: taken = (!(a & 1)); break; 1057 0458 case _BLBS: taken = (int)(a & 1 ); break; 1058 0459 case _FBEQ: taken=(Fcv(a)==0.0); break; 1059 0460 case _FBLT: taken=(Fcv(a)< 0.0); break; 1060 0461 case _FBLE: taken=(Fcv(a)<=0.0); break; 1061 0462 case _FBNE: taken=(Fcv(a)!=0.0); break; 1062 0463 case _FBGE: taken=(Fcv(a)>=0.0); break; 1063 0464 case _FBGT: taken=(Fcv(a)> 0.0); break; 1064 0465 default: printf("** SimAlpha Btaken %x\n", CI); 1065 0466 } 1066 0467 return taken; 1067 0468 } 1068 0469 /************************************************/ 1069 ------------------------------------------------------------ 1070 file name: debug.cc 1071 0001 /*** Yet Another Alpha Processor Simulator ***/ 1072 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 1073 0003 /************************************************/ 1074 0004 #include "define.h" 1075 0005 1076 0006 /* convert hexadecimal value into decimal value */ 1077 0007 /************************************************/ 1078 0008 uint_64t get_hex(char *buf){ 1079 0009 static char hex_chars[] = { 1080 0010 '0', '1', '2', '3', '4', '5', '6', '7', 1081 0011 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 1082 0012 1083 0013 uint_64t sum = 0; 1084 0014 1085 0015 for(int i=0; i<16; i++){ 1086 0016 char t = buf[i]; 1087 0017 if(t==' ' || t=='\n' || t==0) break; 1088 0018 int num=0; 1089 0019 for(int j=0; j<16; j++){ 1090 0020 if(hex_chars[j]==t) num=j; 1091 0021 } 1092 0022 sum = sum * 16 + num; 1093 0023 } 1094 0024 return sum; 1095 0025 } 1096 0026 1097 0027 /************************************************/ 1098 0028 void print_register_name(int i){ 1099 0029 static char *alpha_reg_name[] = { 1100 0030 "v0", "t0", "t1", "t2", 1101 0031 "t3", "t4", "t5", "t6", 1102 0032 "t7", "s0", "s1", "s2", 1103 0033 "s3", "s4", "s5", "fp", 1104 0034 "a0", "a1", "a2", "a3", 1105 0035 "a4", "a5", "t8", "t9", 1106 0036 "t10", "t11", "ra", "t12", 1107 0037 "at", "gp", "sp", "zero", 1108 0038 "pc", "vfp " 1109 0039 }; 1110 0040 printf("%-5s", alpha_reg_name[i]); 1111 0041 } 1112 0042 1113 0043 /************************************************/ 1114 0044 void print_status(ADDR_TYPE pc, data_t *reg){ 1115 0045 for(int i=0; i<32; i++){ 1116 0046 print_register_name(i); 1117 0047 printf(" r%-2d ", i); 1118 0048 printf("0x%-6llx ", reg[i]); 1119 0049 printf("%-8lld\n", reg[i]); 1120 0050 } 1121 0051 printf("fpcr 0x0 0\n"); 1122 0052 printf("pc 0x%-6llx %-8lld\n", 1123 0053 pc, pc); 1124 0054 printf("vfp 0x0 0\n"); 1125 0055 } 1126 0056 1127 0057 1128 0058 /************************************************/ 1129 0059 debug::debug(Env *e){ 1130 0060 ev = e; 1131 0061 } 1132 0062 1133 0063 /************************************************/ 1134 0064 void debug::debugmode(instruction *p){ 1135 0065 1136 0066 if(ev->sc->debug_flag==2){ 1137 0067 static architecture_state as_t; 1138 0068 printf("\n"); 1139 0069 1140 0070 printf("TC:%lld ", ev->e->retired_inst); 1141 0071 printf("pc:%llx\n", ev->as->pc); 1142 0072 1143 0073 for(int i=0; i<32; i++){ 1144 0074 DATA_TYPE tmp1 = ev->as->r[i]; 1145 0075 DATA_TYPE tmp2 = ev->as->f[i]; 1146 0076 if(as_t.r[i] != tmp1){ 1147 0077 printf("r[%d] 0x%-6llx\n", i, tmp1); 1148 0078 } 1149 0079 if(as_t.f[i] != tmp2){ 1150 0080 printf("f[%d] 0x%-6llx\n", i, tmp2); 1151 0081 } 1152 0082 } 1153 0083 as_t = *ev->as; /* remember old state */ 1154 0084 return; 1155 0085 } 1156 0086 1157 0087 char t_buf[256]; 1158 0088 static int stop = 1; 1159 0089 1160 0090 char *buf; 1161 0091 1162 0092 static uint_64t stop_count = 0; 1163 0093 static ADDR_TYPE stop_address = 0; 1164 0094 ADDR_TYPE address; 1165 0095 1166 0096 buf = t_buf; 1167 0097 1168 0098 if(stop_count==ev->e->retired_inst){ stop=1; } 1169 0099 if(stop_address==ev->as->pc){ stop=1; } 1170 0100 if(stop==0) return; 1171 0101 1172 0102 if(stop==1){ 1173 0103 data_t ir_t; 1174 0104 ev->mem->ld_nbyte(4, &ev->as->pc, &ir_t); 1175 0105 printf("TC:%lld ", ev->e->retired_inst); 1176 0106 printf("pc:%llx ", p->Cpc); 1177 0107 printf("ir:%08x ", p->ir); 1178 0108 int id = get_code(p->ir); 1179 0109 printf("ID:%02x.%04x\n", id>>16, id & 0xffff); 1180 0110 1181 0111 print_status(ev->as->pc, ev->as->r); 1182 0112 1183 0113 printf("(db)"); 1184 0114 fgets(buf,256, stdin); 1185 0115 1186 0116 while(*buf != (char)NULL){ 1187 0117 if(!strncmp(buf,"quit",4)) exit(1); 1188 0118 if(!strncmp(buf,"h",1)){ /* help */ 1189 0119 printf(" command\n"); 1190 0120 printf(" c: stop specified tc.\n"); 1191 0121 printf(" s: stop specified address.\n"); 1192 0122 printf(" x: examine memory contents.\n"); 1193 0123 printf(" quit: quit simulate.\n"); 1194 0124 } 1195 0125 if(*(buf)=='\n') break; 1196 0126 1197 0127 if(*(buf)=='x'){ 1198 0128 buf++; 1199 0129 address = get_hex(buf); 1200 0130 address = (address & ~7ull); 1201 0131 1202 0132 for(int j=0; j<16; j++){ 1203 0133 data_t tmp; 1204 0134 printf("0x%09llx: ", address); 1205 0135 for(int i=0; i<2; i++){ 1206 0136 data_t adr; 1207 0137 adr = address; 1208 0138 ev->mem->ld_nbyte(8, &adr, &tmp); 1209 0139 printf("0x%016llx ", tmp); 1210 0140 address +=8; 1211 0141 } 1212 0142 printf("\n"); 1213 0143 } 1214 0144 } 1215 0145 1216 0146 if(*(buf)=='c'){ /* stop by count */ 1217 0147 buf++; 1218 0148 stop_count = atol(buf); 1219 0149 printf("stop_tc = %lld\n", stop_count); 1220 0150 stop=0; 1221 0151 break; 1222 0152 } 1223 0153 1224 0154 if(*(buf)=='s'){ /* stop by address */ 1225 0155 buf++; 1226 0156 stop_address = get_hex(buf); 1227 0157 stop_address = stop_address; 1228 0158 printf("stop_address = 0x%llx\n", 1229 0159 stop_address); 1230 0160 stop=0; 1231 0161 break; 1232 0162 } 1233 0163 1234 0164 printf("\n(db)"); 1235 0165 fgets(buf,256,stdin); 1236 0166 } 1237 0167 } 1238 0168 } 1239 0169 /************************************************/ 1240 ------------------------------------------------------------ 1241 file name: etc.cc 1242 0001 /*** Yet Another Alpha Processor Simulator ***/ 1243 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 1244 0003 /************************************************/ 1245 0004 #include "define.h" 1246 0005 #include 1247 0006 1248 0007 /************************************************/ 1249 0008 void usage(){ 1250 0009 char UsageMessage[] = "\ 1251 0010 Usage: SimAlpha [-option] command\n\ 1252 0011 -d: debug mode\n\ 1253 0012 -a: print simple evaluation result\n\ 1254 0013 -c: print systemcall trace\n\ 1255 0014 -v[num]: verbose mode, prints '.' \ 1256 0015 by VERBOSE_INTERVAL\n\ 1257 0016 -f[num]: set fd_adjust to verify simulation\n\ 1258 0017 -t[num][m]: print execution trace\n\ 1259 0018 -e[num][m]: end simulation at num code run. \ 1260 0019 m means million\n\ 1261 0020 -i[file_name]: file_name as STDIN input file\n\ 1262 0021 "; 1263 0022 printf("%s", UsageMessage); exit(0); 1264 0023 } 1265 0024 1266 0025 /** return 24bit unique instruction ID **/ 1267 0026 /************************************************/ 1268 0027 int get_code(INST_TYPE ir){ 1269 0028 int id=0; 1270 0029 int op6 = (ir>>26) & 0x003f; 1271 0030 int func7 = (ir>>5 ) & 0x007f; 1272 0031 int func11 = (ir>>5 ) & 0x07ff; 1273 0032 int jmp_op = (ir>>14) & 0x0003; 1274 0033 1275 0034 if(op6<=0x0f || op6>=0x1b){ 1276 0035 id = op6 << 16; 1277 0036 } 1278 0037 else{ 1279 0038 switch(op6){ 1280 0039 case 0x10: 1281 0040 case 0x11: 1282 0041 case 0x12: 1283 0042 case 0x13: id = (op6 << 16) | func7; break; 1284 0043 case 0x14: id = op6 << 16; break; 1285 0044 case 0x15: 1286 0045 case 0x16: 1287 0046 case 0x17: 1288 0047 case 0x18: id = (op6 << 16) | func11; break; 1289 0048 case 0x19: id = op6 << 16; break; 1290 0049 case 0x1a: id = (op6 << 16) | jmp_op; break; 1291 0050 default: 1292 0051 printf("*** get_code default %x\n", op6); 1293 0052 } 1294 0053 } 1295 0054 return id; 1296 0055 } 1297 0056 1298 0057 /* If IR is not the cmov, return 0. */ 1299 0058 /************************************************/ 1300 0059 int cmov_ir(INST_TYPE ir){ 1301 0060 int op = (ir>>26) & 0x3F; 1302 0061 if(op==OP_INTL || op==OP_FLTL){ 1303 0062 switch(get_code(ir)){ 1304 0063 case _CMOVLBS: 1305 0064 case _CMOVLBC: 1306 0065 case _CMOVEQ : 1307 0066 case _CMOVNE : 1308 0067 case _CMOVLT : 1309 0068 case _CMOVGE : 1310 0069 case _CMOVLE : 1311 0070 case _CMOVGT : 1312 0071 case _FCMOVEQ: 1313 0072 case _FCMOVNE: 1314 0073 case _FCMOVLT: 1315 0074 case _FCMOVGE: 1316 0075 case _FCMOVLE: 1317 0076 case _FCMOVGT: return 1; 1318 0077 } 1319 0078 } 1320 0079 return 0; 1321 0080 } 1322 0081 1323 0082 /************************************************/ 1324 0083 void house_keeper(instruction *p){ 1325 0084 Env *ev = p->ev; 1326 0085 if(ev->sc->trace_flag!=0 && 1327 0086 ev->sc->trace_flag<=ev->e->retired_inst){ 1328 0087 printf("TC:%lld ", ev->e->retired_inst); 1329 0088 printf("pc:%9llx ", p->Cpc); 1330 0089 printf("ir:%08x ", p->ir); 1331 0090 int id = get_code(p->ir); 1332 0091 printf("ID:%02x.%04x\n", id>>16, id&0xffff); 1333 0092 printf(" Rav: %016llx ", p->Rav); 1334 0093 printf("Rbv: %016llx\n", p->Rbv); 1335 0094 printf(" Imm: %016llx ", p->Imm); 1336 0095 printf("Adr: %016llx\n", p->Adr); 1337 0096 printf(" Rcv: %016llx\n", p->Rcv); 1338 0097 } 1339 0098 if(ev->sc->debug_flag) ev->deb->debugmode(p); 1340 0099 if(ev->sc->verbose_interval && 1341 0100 (ev->e->retired_inst % 1342 0101 ev->sc->verbose_interval)==0){ 1343 0102 write(1, ".", 1); 1344 0103 } 1345 0104 if(ev->sc->end_tc!=0 && 1346 0105 ev->e->retired_inst>=ev->sc->end_tc) 1347 0106 ev->sys->running = 0; 1348 0107 1349 0108 } 1350 0109 1351 0110 /************************************************/ 1352 0111 void option_from_file(char **opt, char *name){ 1353 0112 char *buf; 1354 0113 for(int i=0; iev->as->pc; 1381 0140 int running = chip->step(); 1382 0141 1383 0142 for(int i=0; i<31; i++) 1384 0143 *(p++)=chip->ev->as->r[i]; 1385 0144 for(int i=0; i<31; i++) 1386 0145 *(p++)=chip->ev->as->f[i]; 1387 0146 1388 0147 if(running==0) delete chip; 1389 0148 break; 1390 0149 } 1391 0150 default: 1392 0151 printf("Warning: %d siple_cpu.\n", job); 1393 0152 } 1394 0153 return 0; 1395 0154 } 1396 0155 1397 0156 /* map_s is used in LDS & ITOFS instruction */ 1398 0157 /* input of 8bit and output of 11bit */ 1399 0158 /************************************************/ 1400 0159 uint_64t map_s(DATA_TYPE in){ 1401 0160 uint_32t i8 = (uint_32t)((in >> 23) & 0xFF); 1402 0161 1403 0162 /** Next line should be valid, 1404 0163 SimpleScalar has a bug ? **/ 1405 0164 // if(i8==0xFF) return 0x00000000000007FFull; 1406 0165 if(i8==0x00) return 0x0000000000000000ull; 1407 0166 1408 0167 if(i8 & 0x80) return 0x400ull | (i8 & 0x7F); 1409 0168 else return 0x380ull | (i8 & 0x7F); 1410 0169 } 1411 0170 1412 0171 /************************************************/ 1413 0172 architecture_state::architecture_state(){ 1414 0173 for(int i=0; i<32; i++) r[i]=0; 1415 0174 for(int i=0; i<32; i++) f[i]=0; 1416 0175 } 1417 0176 1418 0177 /* 1419 0178 * Initialize the registers, data file format. 1420 0179 * Begin by "\@" to indicate the valid data. 1421 0180 * /@reg 28 0000000000000000 1422 0181 * /@reg 29 0000000140023e90 */ 1423 0182 /************************************************/ 1424 0183 architecture_state::architecture_state(Env *e){ 1425 0184 ev = e; 1426 0185 for(int i=0; i<32; i++) r[i]=0; 1427 0186 for(int i=0; i<32; i++) f[i]=0; 1428 0187 1429 0188 char *program_name = ev->sc->program_name; 1430 0189 FILE *fp = fp = fopen(program_name, "r"); 1431 0190 if(fp==NULL){ 1432 0191 printf("Bad file name: %s\n", 1433 0192 program_name); 1434 0193 exit(1); 1435 0194 } 1436 0195 1437 0196 /*** File Format Check ***/ 1438 0197 DATA_TYPE dat; 1439 0198 char buf[4096]; 1440 0199 fgets(buf, 4096, fp); 1441 0200 if(strncmp(buf+3, "SimAlpha", 8)){ 1442 0201 printf("%s: Not a SimAlpha data file.\n", 1443 0202 program_name); 1444 0203 exit(1); 1445 0204 } 1446 0205 1447 0206 while(!feof(fp)){ 1448 0207 int i; 1449 0208 fgets(buf, 4096, fp); 1450 0209 if(*buf=='/' && *(buf+1)=='@'){ 1451 0210 sscanf(buf+6,"%d", &i); 1452 0211 dat = get_hex(buf+9); 1453 0212 if(i==32) pc=dat; 1454 0213 else r[i]=dat; 1455 0214 } 1456 0215 if(i==32) break; 1457 0216 } 1458 0217 fclose(fp); 1459 0218 } 1460 0219 1461 0220 /************************************************/ 1462 0221 uint_64t architecture_state::rr(int n){ 1463 0222 if(n==0) return pc; 1464 0223 if(n>=1 && n<=32) return r[n-1]; 1465 0224 if(n>=33 && n<=64) return f[n-33]; 1466 0225 printf("Error:architecture_state::rr(%d)\n",n); 1467 0226 exit(1); 1468 0227 return 0; 1469 0228 } 1470 0229 1471 0230 /************************************************/ 1472 0231 void print_evaluation_result(Env *ev){ 1473 0232 class evaluation_result *e = ev->e; 1474 0233 struct timeval tp; 1475 0234 struct timezone tzp; 1476 0235 1477 0236 if(ev->sc->simple_result){ 1478 0237 printf("\n"); 1479 0238 for(int i=0; i<60; i++) printf("="); 1480 0239 printf("\n=== %s %s\n", NAME, VER); 1481 0240 printf("=== %6lld million code(%14lld code)\n", 1482 0241 e->retired_inst/1000000,e->retired_inst); 1483 0242 return; 1484 0243 } 1485 0244 1486 0245 gettimeofday(&tp, &tzp); 1487 0246 uint_64t usec = 1488 0247 (uint_64t)(tp.tv_sec - e->tp.tv_sec) 1489 0248 * 1000000ull + (uint_64t)tp.tv_usec - 1490 0249 (uint_64t)e->tp.tv_usec; 1491 0250 fflush(stdout); 1492 0251 fflush(stderr); 1493 0252 uint_64t minute = (usec / 1000000) / 60; 1494 0253 uint_64t second = (usec / 1000000) % 60; 1495 0254 printf("\n"); 1496 0255 for(int i=0; i<60; i++) printf("="); 1497 0256 printf("\n=== %s %s\n", NAME, VER); 1498 0257 char buf[256]; 1499 0258 getcwd(buf, 256); 1500 0259 printf("=== cwd: %s\n", buf); 1501 0260 printf("=== %6lld million code(%14lld code)", 1502 0261 e->retired_inst/1000000,e->retired_inst); 1503 0262 printf(" %6.3f MIPS\n", 1504 0263 (double)e->retired_inst/(double)usec); 1505 0264 printf("=== SimAlpha takes "); 1506 0265 printf("%5lld min %2lld second", 1507 0266 minute, second); 1508 0267 printf(" (%12lld usec)\n", usec); 1509 0268 printf("=== SimAlpha starts at %s", 1510 0269 ctime(&e->time_begin)); 1511 0270 printf("=== Memory %5dKB used", 1512 0271 BLOCK_SIZE/1024 * e->used_memory_block); 1513 0272 printf("(block size %2dKB, %4d blocks)\n", 1514 0273 BLOCK_SIZE/1024, e->used_memory_block); 1515 0274 fflush(stdout); 1516 0275 } 1517 0276 1518 0277 /************************************************/ 1519 0278 system_config::system_config(char *program, 1520 0279 char **option){ 1521 0280 memset(this, 0, sizeof(system_config)); 1522 0281 strcpy(program_name, program); 1523 0282 1524 0283 if(option==NULL) return; 1525 0284 for(int i=0; option[i]!=NULL; i++){ 1526 0285 char opt[1024]; 1527 0286 strcpy(opt, option[i]); 1528 0287 if(opt[0]!='-') continue; 1529 0288 switch(opt[1]){ 1530 0289 case 'a': simple_result = 1; break; 1531 0290 case 'c': syscall_flag = 1; break; 1532 0291 case 'z': verify_flag = 1; break; 1533 0292 case 'd': 1534 0293 debug_flag = atoi(&opt[2]); 1535 0294 if(debug_flag==0) debug_flag=1; 1536 0295 break; 1537 0296 case 't': 1538 0297 trace_flag = atoi(&opt[2]); 1539 0298 if(opt[strlen(opt)-1]=='m') 1540 0299 trace_flag*=1000000; 1541 0300 if(trace_flag==0) trace_flag = 1; 1542 0301 printf("*** gen trace data at %lld exec.\n", 1543 0302 trace_flag); 1544 0303 break; 1545 0304 case 'v': 1546 0305 verbose_interval =atoi(&opt[2]); 1547 0306 if(verbose_interval == 0) 1548 0307 verbose_interval = 100000; 1549 0308 if(opt[strlen(opt)-1]=='m') 1550 0309 verbose_interval*=1000000; 1551 0310 printf("*** verbose interval: %d\n", 1552 0311 verbose_interval); 1553 0312 break; 1554 0313 case 'f': 1555 0314 fd_adjust = atoi(&opt[2]); 1556 0315 if(fd_adjust==0) fd_adjust=1; 1557 0316 printf("*** fd_adjust=%d \n",fd_adjust); 1558 0317 if(fd_adjust<0){ 1559 0318 printf("Error fd_adjust.\n"); 1560 0319 exit(1); 1561 0320 } 1562 0321 break; 1563 0322 case 'e': 1564 0323 end_tc =atoi(&opt[2]); 1565 0324 if(opt[strlen(opt)-1]=='m')end_tc*=1000000; 1566 0325 printf("** Finish at %lld code execution\n", 1567 0326 end_tc); 1568 0327 break; 1569 0328 case 'i': 1570 0329 fd_stdin_flag = 1; 1571 0330 fd_stdin = open(&opt[2], O_RDONLY); 1572 0331 printf("*** SimAlpha: use [%s] as STDIN.\n", 1573 0332 &opt[2]); 1574 0333 if(fd_stdin<0){ 1575 0334 printf("Can not open file:%s\n",&opt[2]); 1576 0335 exit(1); 1577 0336 } 1578 0337 break; 1579 0338 default: 1580 0339 printf("*** Error:[%s] Wrong option!!\n\n", 1581 0340 opt); 1582 0341 usage(); 1583 0342 exit(1); 1584 0343 } 1585 0344 } 1586 0345 slow_mode = debug_flag || verbose_interval 1587 0346 || end_tc || trace_flag; 1588 0347 } 1589 0348 1590 0349 /************************************************/ 1591 0350 evaluation_result::evaluation_result(){ 1592 0351 memset(this,0,sizeof(class evaluation_result)); 1593 0352 1594 0353 time_begin = time(0); 1595 0354 gettimeofday(&tp, &tzp); 1596 0355 } 1597 0356 /************************************************/ 1598 ------------------------------------------------------------ 1599 file name: syscall.cc 1600 0001 /*** Yet Another Alpha Processor Simulator ***/ 1601 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 1602 0003 /************************************************/ 1603 0004 #include "define.h" 1604 0005 #include 1605 0006 1606 0007 /************************************************/ 1607 0008 int system_manager::translate_fd(DATA_TYPE fd){ 1608 0009 for(int i=0; isc->fd_adjust; 1630 0031 } 1631 0032 1632 0033 /************************************************/ 1633 0034 void system_manager::execute_pal(instruction *p){ 1634 0035 INST_TYPE ir = p->ir; 1635 0036 int_64t ret=0; 1636 0037 int F = ev->sc->syscall_flag; 1637 0038 data_t *r = ev->as->r; 1638 0039 1639 0040 if(F) printf("%8lld: ", ev->e->retired_inst); 1640 0041 1641 0042 if((ir & 0xFFFF)!=0x0083){ 1642 0043 switch((ir & 0xFFFF)){ 1643 0044 case 0x009e: // rdunique(Read Unique Value) 1644 0045 r[0]=(uniq); 1645 0046 if(F){ 1646 0047 printf("call_pal rduniq=%llx\n", uniq); 1647 0048 } 1648 0049 return; 1649 0050 case 0x009f: // wrunique(Write Unique Value) 1650 0051 uniq = r[16]; 1651 0052 if(F){ 1652 0053 printf("call_pal wrruniq=%llx\n", 1653 0054 r[16]); 1654 0055 } 1655 0056 return; 1656 0057 default: 1657 0058 if(F){ 1658 0059 printf("*** PAL(ir & 0xFFFF)!=0x83 F=%x", 1659 0060 (ir & 0xffff)); 1660 0061 printf(" TC:%lld default. %llx\n", 1661 0062 ev->e->retired_inst, r[0]); 1662 0063 } 1663 0064 return; 1664 0065 } 1665 0066 } 1666 0067 1667 0068 if(r[0]==0){ 1668 0069 r[19]=(0); 1669 0070 return; 1670 0071 } 1671 0072 1672 0073 switch(r[0]){ 1673 0074 /********************************************/ 1674 0075 case ASYS_UNIMPLEMENT: { 1675 0076 ret = -1; 1676 0077 r[0]=(0); 1677 0078 r[19]=(ret); 1678 0079 if(F){ 1679 0080 printf("SYS_226 = %lld\n", ret); 1680 0081 } 1681 0082 break; 1682 0083 } 1683 0084 /********************************************/ 1684 0085 case ASYS_unlink: { 1685 0086 char buf[512]; /** file name **/ 1686 0087 for(int i=0; i<=512; i++){ 1687 0088 data_t d; 1688 0089 data_t adr; 1689 0090 adr=(r[16]+i); 1690 0091 ev->mem->ld_nbyte(1, &adr, &d); 1691 0092 buf[i] = (char)d; 1692 0093 if(buf[i]=='\0') break; 1693 0094 } 1694 0095 if(ev->sc->fd_adjust){ /** rename **/ 1695 0096 buf[1]='S'; 1696 0097 buf[2]='A'; 1697 0098 buf[3]='0'+ ev->sc->fd_adjust; 1698 0099 } 1699 0100 1700 0101 ret = unlink(buf); 1701 0102 if(ret==-1){ 1702 0103 r[0]=(errno); 1703 0104 r[19]=(ret); 1704 0105 } 1705 0106 else{ 1706 0107 r[19]=(0); 1707 0108 } 1708 0109 1709 0110 if(F){ 1710 0111 printf("unlink(%s) = %lld\n", buf, ret); 1711 0112 } 1712 0113 break; 1713 0114 } 1714 0115 /********************************************/ 1715 0116 case ASYS_open: { 1716 0117 int fd_t; 1717 0118 char buf[512]; /** file name **/ 1718 0119 for(int i=0; i<=512; i++){ 1719 0120 data_t d; 1720 0121 data_t adr; 1721 0122 adr=(r[16]+i); 1722 0123 ev->mem->ld_nbyte(1, &adr, &d); 1723 0124 buf[i] = (char)d; 1724 0125 if(buf[i]=='\0') break; 1725 0126 } 1726 0127 /** RDONLY or RDWR **/ 1727 0128 if(r[17]==0 || r[17]==2){ 1728 0129 fd_t = open(buf, r[17], r[18]); 1729 0130 } 1730 0131 else{ 1731 0132 if(ev->sc->fd_adjust){ /** rename **/ 1732 0133 buf[1]='S'; 1733 0134 buf[2]='A'; 1734 0135 buf[3]='0'+ ev->sc->fd_adjust; 1735 0136 } 1736 0137 int flag = (int)r[17] | O_CREAT; 1737 0138 fd_t = open(buf, flag, r[18]); 1738 0139 } 1739 0140 1740 0141 /* mapping from the real to the logical */ 1741 0142 if(fd_t==-1){ 1742 0143 ret = -1; 1743 0144 r[0]=(errno); 1744 0145 r[19]=(~0ull); 1745 0146 } 1746 0147 else{ 1747 0148 ret = fd_table[fd_t]; 1748 0149 r[0]=(ret); 1749 0150 r[19]=(0); 1750 0151 } 1751 0152 1752 0153 if(F){ 1753 0154 printf("open(\"%s\", 0x%llx, 0x%llx)", 1754 0155 buf, r[17], r[18]); 1755 0156 printf("= logic %lld(real %d)\n", 1756 0157 ret, fd_t); 1757 0158 } 1758 0159 break; 1759 0160 } 1760 0161 /*** Note that sigreturn updates as->pc ***/ 1761 0162 /********************************************/ 1762 0163 case ASYS_sigreturn: { 1763 0164 uint_64t pt[OSF_SIGCONTEXT_SIZE/8]; 1764 0165 char *buf = (char *)pt; 1765 0166 1766 0167 data_t d; 1767 0168 data_t adr; 1768 0169 for(int i=0; imem->ld_nbyte(1, &adr, &d); 1771 0172 buf[i] = (char)d; 1772 0173 } 1773 0174 for(int i=0; i<31; i++) r[i]=(pt[i+4]); 1774 0175 for(int i=0; i<31; i++){ 1775 0176 ev->as->f[i]=(pt[i+37]); 1776 0177 } 1777 0178 ev->as->pc=(pt[2]); /** Update PC **/ 1778 0179 1779 0180 if(F){ 1780 0181 printf("sigreturn(0x%llx),Npc:0x%llx\n", 1781 0182 r[16], ev->as->pc); 1782 0183 } 1783 0184 break; 1784 0185 } 1785 0186 /********************************************/ 1786 0187 case ASYS_close: { 1787 0188 int fd_t = translate_fd(r[16]); 1788 0189 1789 0190 if(fd_t!=0 && fd_t!=1 && fd_t!=2){ 1790 0191 ret = close(fd_t); 1791 0192 r[0]=(ret); 1792 0193 } 1793 0194 r[19]=(0); 1794 0195 if(F){ 1795 0196 printf("close(%lld(%d)) = %lld\n", 1796 0197 r[16], fd_t, ret); 1797 0198 } 1798 0199 break; 1799 0200 } 1800 0201 /********************************************/ 1801 0202 case ASYS_getpagesize: { 1802 0203 ret = 8192; /* getpagesize(); */ 1803 0204 r[0]=(ret); 1804 0205 r[19]=(0); 1805 0206 if(F){ 1806 0207 printf("getpagesize() = 0x%llx\n", ret); 1807 0208 } 1808 0209 break; 1809 0210 } 1810 0211 /********************************************/ 1811 0212 case ASYS_sigprocmask: { 1812 0213 ret = 0; 1813 0214 r[0]=(ret); 1814 0215 r[19]=(ret); 1815 0216 if(F){ 1816 0217 printf("%8lld: sigprocmask(%lld,%llx) = %lld\n", 1817 0218 ev->e->retired_inst, r[16], 1818 0219 r[17], ret); 1819 0220 } 1820 0221 break; 1821 0222 } 1822 0223 /********************************************/ 1823 0224 case ASYS_getrusage: { // Not Checked 1824 0225 struct rusage ru; 1825 0226 // ret=getrusage((enum __rusage_who)r[16], 1826 0227 ret=getrusage((int)r[16], 1827 0228 &ru); 1828 0229 1829 0230 for(int i=0; imem->st_nbyte(1, &adr, &dat); 1833 0234 } 1834 0235 1835 0236 r[0]=(ret); 1836 0237 r[19]=(0); 1837 0238 1838 0239 if(F){ 1839 0240 printf("getrusage(%lld, %llx)=%lld\n", 1840 0241 r[16], r[17], ret); 1841 0242 } 1842 0243 break; 1843 0244 } 1844 0245 /********************************************/ 1845 0246 case ASYS_gettimeofday:{ 1846 0247 r[19]=(0); 1847 0248 if(F){ 1848 0249 printf("gettimeofday(%lld,%llx) = %lld\n", 1849 0250 r[16], r[17], ret); 1850 0251 } 1851 0252 break; 1852 0253 } 1853 0254 /********************************************/ 1854 0255 case ASYS_fcntl: { 1855 0256 ret = 0; 1856 0257 r[0]=(ret); 1857 0258 r[19]=(0); 1858 0259 if(F){ 1859 0260 printf("fcntl(%lld,%llx) = %lld\n", 1860 0261 r[16], r[17], ret); 1861 0262 } 1862 0263 break; 1863 0264 } 1864 0265 /********************************************/ 1865 0266 case ASYS_sigaction: { 1866 0267 ret = 0; 1867 0268 r[0]=(ret); 1868 0269 r[18]=(r[17]); 1869 0270 r[19]=(0); 1870 0271 if(F){ 1871 0272 printf("sigaction(%llx,%llx,%llx,%llx)", 1872 0273 r[16], r[17], 1873 0274 r[18], r[19]); 1874 0275 printf(" = %lld\n", ret); 1875 0276 } 1876 0277 break; 1877 0278 } 1878 0279 /********************************************/ 1879 0280 case ASYS_osf_getsysinfo: { 1880 0281 ret = 0; 1881 0282 r[0]=(ret); 1882 0283 r[19]=(0); 1883 0284 if(F){ 1884 0285 printf("osf_getsysinfo(%llx,%llx,%llx,%llx)", 1885 0286 r[16], r[17], 1886 0287 r[18], r[19]); 1887 0288 printf(" = %lld\n", ret); 1888 0289 } 1889 0290 break; 1890 0291 } 1891 0292 /********************************************/ 1892 0293 case ASYS_osf_setsysinfo: { 1893 0294 ret = 0; 1894 0295 r[0]=(ret); 1895 0296 // r[20]= ret; 1896 0297 r[19]=(0); 1897 0298 if(F){ 1898 0299 printf("osf_setsysinfo(%llx,%llx,%llx,%llx)", 1899 0300 r[16], r[17], 1900 0301 r[18], r[19]); 1901 0302 printf(" = %lld\n", ret); 1902 0303 } 1903 0304 break; 1904 0305 } 1905 0306 /********************************************/ 1906 0307 case ASYS_getuid: { 1907 0308 ret = getuid(); 1908 0309 r[0]=(ret); 1909 0310 r[19]=(0); 1910 0311 r[20]=(geteuid()); 1911 0312 if(F){ 1912 0313 printf("getuid() = %lld\n", ret); 1913 0314 } 1914 0315 break; 1915 0316 } 1916 0317 /********************************************/ 1917 0318 case ASYS_getgid: { 1918 0319 ret = getgid(); 1919 0320 r[0]=(ret); 1920 0321 r[19]=(0); 1921 0322 r[20]=(getegid()); 1922 0323 if(F){ 1923 0324 printf("getgid(0x%llx) = %lld\n", 1924 0325 r[16], ret); 1925 0326 } 1926 0327 break; 1927 0328 } 1928 0329 /********************************************/ 1929 0330 case ASYS_brk: { 1930 0331 ret = r[16]; 1931 0332 r[0]=(ret); 1932 0333 r[19]=(0); 1933 0334 if(F){ 1934 0335 printf("brk(0x%llx) = %llx\n", 1935 0336 r[16], ret); 1936 0337 } 1937 0338 break; 1938 0339 } 1939 0340 /********************************************/ 1940 0341 case ASYS_getpid: { 1941 0342 ret = getpid(); 1942 0343 r[0]=(ret); 1943 0344 r[19]=(0); 1944 0345 if(F){ 1945 0346 printf("getpid() = %llx\n", ret); 1946 0347 } 1947 0348 break; 1948 0349 } 1949 0350 /********************************************/ 1950 0351 case ASYS_fstat: { 1951 0352 int fd_t = translate_fd(r[16]); 1952 0353 1953 0354 struct stat sbuf; 1954 0355 ret = fstat(fd_t, &sbuf); 1955 0356 1956 0357 struct osf_statbuf asbuf; 1957 0358 memset(&asbuf,0,sizeof(struct osf_statbuf)); 1958 0359 asbuf.a_st_dev = sbuf.st_dev; 1959 0360 asbuf.a_st_ino = sbuf.st_ino; 1960 0361 asbuf.a_st_mode = sbuf.st_mode; 1961 0362 asbuf.a_st_nlink = sbuf.st_nlink; 1962 0363 asbuf.a_st_uid = sbuf.st_uid; 1963 0364 asbuf.a_st_gid = sbuf.st_gid; 1964 0365 asbuf.a_st_rdev = sbuf.st_rdev; 1965 0366 asbuf.a_st_size = sbuf.st_size; 1966 0367 asbuf.a_st_atime = sbuf.st_atime; 1967 0368 asbuf.a_st_mtime = sbuf.st_mtime; 1968 0369 asbuf.a_st_ctime = sbuf.st_ctime; 1969 0370 asbuf.a_st_blksize = sbuf.st_blksize; 1970 0371 asbuf.a_st_blocks = sbuf.st_blocks; 1971 0372 1972 0373 char *buf = (char *)&asbuf; 1973 0374 1974 0375 for(int i=0; imem->st_nbyte(1, &adr, &dat); 1980 0381 } 1981 0382 1982 0383 r[0]=(ret); 1983 0384 r[19]=(0); 1984 0385 if(F){ 1985 0386 printf("fstat(logic %lld(real %d), 0x%llx)", 1986 0387 r[16],fd_t, r[17]); 1987 0388 printf(" = %lld\n", ret); 1988 0389 } 1989 0390 break; 1990 0391 } 1991 0392 /********************************************/ 1992 0393 case ASYS_ioctl: { 1993 0394 int fd_t = translate_fd(r[16]); 1994 0395 1995 0396 switch(r[17]){ 1996 0397 case 0x40067408: // OSF_TIOCGRETP 1997 0398 { 1998 0399 struct osf_sgttyb { 1999 0400 uint_08t sg_ispeed; /* input speed */ 2000 0401 uint_08t sg_ospeed; /* output speed */ 2001 0402 uint_08t sg_erase; /* erase char */ 2002 0403 uint_08t sg_kill; /* kill char */ 2003 0404 uint_16t sg_flags; /* mode flags */ 2004 0405 }; 2005 0406 2006 0407 struct termios lbuf; 2007 0408 ret = tcgetattr(fd_t, &lbuf); 2008 0409 2009 0410 /*** store 6 byte, value of 0 ***/ 2010 0411 for(int i=0; i<6; i++){ 2011 0412 data_t adr; adr=(r[18]+i); 2012 0413 data_t dat; dat=(0); 2013 0414 ev->mem->st_nbyte(1, &adr, &dat); 2014 0415 } 2015 0416 2016 0417 if(ret!=-1){ 2017 0418 r[0]=(ret); 2018 0419 r[19]=(0); // A3 2019 0420 } 2020 0421 else{ 2021 0422 r[0]=(errno); 2022 0423 r[19]=(ret); 2023 0424 } 2024 0425 break; 2025 0426 } 2026 0427 2027 0428 default: 2028 0429 ret = 0; 2029 0430 r[19]=(ret); 2030 0431 if(F) printf("*** ioctl default\n"); 2031 0432 break; 2032 0433 } 2033 0434 2034 0435 if(F){ 2035 0436 printf("ioctl(logic%lld(r%d),0x%llx,0x%llx)", 2036 0437 r[16], fd_t, 2037 0438 r[17], r[18]); 2038 0439 printf(" = %llx\n", ret); 2039 0440 } 2040 0441 break; 2041 0442 } 2042 0443 /********************************************/ 2043 0444 case ASYS_read: { 2044 0445 char *buf = (char *)calloc(1, (size_t)r[18]); 2045 0446 if(buf==NULL){ 2046 0447 printf("*** malloc error: "); 2047 0448 printf("in syscall.cc::read\n"); 2048 0449 } 2049 0450 2050 0451 int fd_t = translate_fd(r[16]); 2051 0452 if(ev->sc->fd_stdin_flag && fd_t==0) 2052 0453 fd_t=ev->sc->fd_stdin; /* STDIN */ 2053 0454 2054 0455 ret = read(fd_t, buf, r[18]); 2055 0456 2056 0457 // This is better. & 2057 0458 // simple scalar imple! 2058 0459 /* for(int i=0; imem->st_nbyte(1, &adr, &dat); 2064 0465 } 2065 0466 r[0]=(ret); 2066 0467 r[19]=(0); 2067 0468 free(buf); 2068 0469 2069 0470 if(F){ 2070 0471 printf("read(logic %lld(real%d),%llx,0x%llx)", 2071 0472 r[16], 2072 0473 fd_t, r[17], r[18]); 2073 0474 printf(" = %llx\n", ret); 2074 0475 } 2075 0476 break; 2076 0477 } 2077 0478 /********************************************/ 2078 0479 case ASYS_write: { 2079 0480 char *buf = (char *)malloc((size_t)r[18]); 2080 0481 if(buf==NULL){ 2081 0482 printf("*** malloc error: "); 2082 0483 printf("in syscall.cc::write\n"); 2083 0484 } 2084 0485 2085 0486 for(int i=0; i<(int)r[18]; i++){ 2086 0487 data_t d; 2087 0488 data_t adr; 2088 0489 adr=(r[17]+i); 2089 0490 ev->mem->ld_nbyte(1, &adr, &d); 2090 0491 buf[i] = (char)d; 2091 0492 } 2092 0493 2093 0494 int fd_t = translate_fd(r[16]); 2094 0495 2095 0496 ret = write(fd_t, (void *)buf, 2096 0497 (long)r[18]); 2097 0498 r[0]=(ret); 2098 0499 r[19]=(0); 2099 0500 free(buf); 2100 0501 2101 0502 if(F){ 2102 0503 printf("write(%lld(%d), 0x%llx, %lld)=%lld\n", 2103 0504 r[16], 2104 0505 fd_t, r[17], r[18], ret); 2105 0506 } 2106 0507 break; 2107 0508 } 2108 0509 /********************************************/ 2109 0510 case ASYS_lseek: { 2110 0511 int fd_t = translate_fd(r[16]); 2111 0512 if(ev->sc->fd_stdin_flag && fd_t==0) 2112 0513 fd_t=ev->sc->fd_stdin; /* STDIN */ 2113 0514 2114 0515 ret = lseek(fd_t, r[17], r[18]); 2115 0516 if(ret==-1){ 2116 0517 r[0]=(errno); 2117 0518 r[19]=(~0); 2118 0519 } 2119 0520 else{ 2120 0521 r[0]=(ret); 2121 0522 r[19]=(0); 2122 0523 } 2123 0524 if(F){ 2124 0525 printf("lseek(logic%lld(real%d),%lld,%lld)\n", 2125 0526 r[16], fd_t, 2126 0527 r[17], r[18]); 2127 0528 printf(" = %llx\n", ret); 2128 0529 } 2129 0530 break; 2130 0531 } 2131 0532 /********************************************/ 2132 0533 case ASYS_getrlimit: { 2133 0534 ret = 0; 2134 0535 r[19]=(ret); 2135 0536 if(F){ 2136 0537 printf("%8lld: getrlimit(%lld,%lld,%lld)", 2137 0538 ev->e->retired_inst, r[16], 2138 0539 r[17], r[18]); 2139 0540 printf(" = %llx\n", ret); 2140 0541 } 2141 0542 break; 2142 0543 } 2143 0544 /********************************************/ 2144 0545 case ASYS_setrlimit: { 2145 0546 ret = 0; 2146 0547 r[19]=(ret); 2147 0548 if(F){ 2148 0549 printf("setrlimit(%lld,%lld,%lld) = %lld\n", 2149 0550 r[16], 2150 0551 r[17], r[18], ret); 2151 0552 } 2152 0553 break; 2153 0554 } 2154 0555 /********************************************/ 2155 0556 case ASYS_exit: { 2156 0557 ret = 0; 2157 0558 running = 0; 2158 0559 if(F){ 2159 0560 printf("%8lld: exit() = %lld\n", 2160 0561 ev->e->retired_inst, ret); 2161 0562 } 2162 0563 break; 2163 0564 } 2164 0565 default: { 2165 0566 printf("systemcall not implemented!!: %lld\n", 2166 0567 r[0]); 2167 0568 r[0]=(0); 2168 0569 r[19]=((uint_64t)-1); 2169 0570 } 2170 0571 } 2171 0572 fflush(stdout); 2172 0573 } 2173 0574 /************************************************/ 2174 ------------------------------------------------------------ 2175 file name: define.h 2176 0001 /*** Yet Another Alpha Processor Simulator ***/ 2177 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 2178 0003 /************************************************/ 2179 0004 #include 2180 0005 #include 2181 0006 #include 2182 0007 #include 2183 0008 #include 2184 0009 #include 2185 0010 #include 2186 0011 #include 2187 0012 #include 2188 0013 #include 2189 0014 #include 2190 0015 #include 2191 0016 #include 2192 0017 #include 2193 0018 2194 0019 /* 1. Type Definition */ 2195 0020 /************************************************/ 2196 0021 typedef signed char int_08t; 2197 0022 typedef signed short int_16t; 2198 0023 typedef signed int int_32t; 2199 0024 typedef signed long long int_64t; 2200 0025 typedef unsigned char uint_08t; 2201 0026 typedef unsigned short uint_16t; 2202 0027 typedef unsigned int uint_32t; 2203 0028 typedef unsigned long long uint_64t; 2204 0029 2205 0030 typedef uint_32t INST_TYPE; 2206 0031 typedef uint_64t ADDR_TYPE; 2207 0032 typedef uint_64t DATA_TYPE; 2208 0033 typedef uint_64t data_t; 2209 0034 2210 0035 2211 0036 /* 2. Constant Definition */ 2212 0037 /************************************************/ 2213 0038 #define NAME "SimAlpha Release" 2214 0039 #define VER "Version 1.4.2 2003-09-18" 2215 0040 2216 0041 #define DEF_FILE_NAME "aout.txt" 2217 0042 #define BLOCK_SIZE 0x00002000 /* 8KB page */ 2218 0043 #define BLOCK_TABLE_SIZE 0x00080000 /* page size*/ 2219 0044 #define BLOCK_MASK 0x00001fff /* page mask*/ 2220 0045 #define BLOCK_MASK_BIT 13 /* mask bit */ 2221 0046 #define DATA_T_SIZE 8 /* size of data_t */ 2222 0047 #define DATA_T_BIT 3 /* s bit of data_t */ 2223 0048 2224 0049 /** for AMASK op and IMPLVER op **/ 2225 0050 #define IMPLEMENTATION_VERSION 2 2226 0051 #define CPU_FEATURE_MASK 0x0000000000000107ull 2227 0052 2228 0053 #define FD_MAPPING_MAX 128 /* read/write */ 2229 0054 #define OSF_SIGCONTEXT_SIZE 568 /* in byte */ 2230 0055 #define OSF_FSTAT_SIZE 80 /* in byte */ 2231 0056 #define OSF_RUSAGE_SIZE 72 /* in byte */ 2232 0057 #define OPTION_MAX 30 /* max options */ 2233 0058 2234 0059 /** for systemcall implementation **/ 2235 0060 /** I implement one used for SPEC CPU2000. **/ 2236 0061 /************************************************/ 2237 0062 #define ASYS_exit 1 2238 0063 #define ASYS_read 3 2239 0064 #define ASYS_write 4 2240 0065 #define ASYS_close 6 2241 0066 #define ASYS_unlink 10 2242 0067 #define ASYS_brk 17 2243 0068 #define ASYS_lseek 19 2244 0069 #define ASYS_getpid 20 2245 0070 #define ASYS_getuid 24 2246 0071 #define ASYS_open 45 2247 0072 #define ASYS_getgid 47 2248 0073 #define ASYS_sigprocmask 48 2249 0074 #define ASYS_ioctl 54 2250 0075 #define ASYS_getpagesize 64 2251 0076 #define ASYS_stat 67 2252 0077 #define ASYS_mmap 71 2253 0078 #define ASYS_munmap 73 2254 0079 #define ASYS_fstat 91 2255 0080 #define ASYS_fcntl 92 2256 0081 #define ASYS_sigreturn 103 2257 0082 #define ASYS_gettimeofday 116 2258 0083 #define ASYS_getrusage 117 2259 0084 #define ASYS_rename 128 2260 0085 #define ASYS_getrlimit 144 2261 0086 #define ASYS_setrlimit 145 2262 0087 #define ASYS_sigaction 156 2263 0088 #define ASYS_getdirentries 159 2264 0089 #define ASYS_UNIMPLEMENT 226 2265 0090 #define ASYS_osf_getsysinfo 256 2266 0091 #define ASYS_osf_setsysinfo 257 2267 0092 2268 0093 /** Table C-6: Opcode Summary **/ 2269 0094 /** by Alpha Architecture Handbook V.4 **/ 2270 0095 /************************************************/ 2271 0096 /** 0x00 PALcode instruction(CALL_PAL) **/ 2272 0097 /** 0x08 load address instruction **/ 2273 0098 /** 0x09 load address high instruction **/ 2274 0099 /** 0x10 Integer arithmetic instruction **/ 2275 0100 /** 0x11 Integer logical instruction **/ 2276 0101 /** 0x12 Integer shift instruction **/ 2277 0102 /** 0x13 Integer multiply instruction **/ 2278 0103 /** 0x14 Integer to floating-point register **/ 2279 0104 /** 0x15 VAX floating-point instruction **/ 2280 0105 /** 0x16 IEEE floating-point instruction **/ 2281 0106 /** 0x17 Floating-point instruction **/ 2282 0107 /** 0x18 Miscellaneous instruction **/ 2283 0108 /** 0x1a Jump instruction **/ 2284 0109 /** 0x1c Floating-point to integer register **/ 2285 0110 /************************************************/ 2286 0111 #define OP_PAL 0x00 2287 0112 #define OP_LDA 0x08 2288 0113 #define OP_LDAH 0x09 2289 0114 #define OP_INTA 0x10 2290 0115 #define OP_INTL 0x11 2291 0116 #define OP_INTS 0x12 2292 0117 #define OP_INTM 0x13 2293 0118 #define OP_ITFP 0x14 2294 0119 #define OP_FLTV 0x15 2295 0120 #define OP_FLTI 0x16 2296 0121 #define OP_FLTL 0x17 2297 0122 #define OP_MISC 0x18 2298 0123 #define OP_JSR 0x1a 2299 0124 #define OP_FPTI 0x1c 2300 0125 2301 0126 #define BIT0 0x0000000000000001ull 2302 0127 #define BIT1 0x0000000000000002ull 2303 0128 #define BIT2 0x0000000000000004ull 2304 0129 #define BIT3 0x0000000000000008ull 2305 0130 #define BIT4 0x0000000000000010ull 2306 0131 #define BIT5 0x0000000000000020ull 2307 0132 #define BIT6 0x0000000000000040ull 2308 0133 #define BIT7 0x0000000000000080ull 2309 0134 #define BIT8 0x0000000000000100ull 2310 0135 #define BIT9 0x0000000000000200ull 2311 0136 #define BIT10 0x0000000000000400ull 2312 0137 #define BIT11 0x0000000000000800ull 2313 0138 #define BIT12 0x0000000000001000ull 2314 0139 #define BIT15 0x0000000000008000ull 2315 0140 #define BIT20 0x0000000000100000ull 2316 0141 #define BIT31 0x0000000080000000ull 2317 0142 #define BIT63 0x8000000000000000ull 2318 0143 2319 0144 #define EXTND8 0xffffffffffffff00ull 2320 0145 #define EXTND16 0xffffffffffff0000ull 2321 0146 #define EXTND21 0xffffffffffe00000ull 2322 0147 #define EXTND32 0xffffffff00000000ull 2323 0148 #define MASK08 0x00000000000000ffull 2324 0149 #define MASK16 0x000000000000ffffull 2325 0150 #define MASK21 0x00000000001fffffull 2326 0151 #define MASK32 0x00000000ffffffffull 2327 0152 2328 0153 #define ZAP0 0xffffffffffffff00ull 2329 0154 #define ZAP1 0xffffffffffff00ffull 2330 0155 #define ZAP2 0xffffffffff00ffffull 2331 0156 #define ZAP3 0xffffffff00ffffffull 2332 0157 #define ZAP4 0xffffff00ffffffffull 2333 0158 #define ZAP5 0xffff00ffffffffffull 2334 0159 #define ZAP6 0xff00ffffffffffffull 2335 0160 #define ZAP7 0x00ffffffffffffffull 2336 0161 2337 0162 /** for instruction.cc **/ 2338 0163 #define MSK1 0x3e /* 6bit of 111110 */ 2339 0164 #define MSK2 0x3c /* 6bit of 111100 */ 2340 0165 #define MSK3 0x38 /* 6bit of 111000 */ 2341 0166 #define MSK4 0x30 /* 6bit of 110000 */ 2342 0167 2343 0168 /*** Control Transfer instructions ***/ 2344 0169 /************************************************/ 2345 0170 #define _JMP__ 0x1a0000 // 1a.0 2346 0171 #define _JSR__ 0x1a0001 // 1a.1 2347 0172 #define _RET__ 0x1a0002 // 1a.2 2348 0173 #define _JSR_C 0x1a0003 // 1a.3 JSR_COROUTINE 2349 0174 2350 0175 #define _BR__ 0x300000 2351 0176 #define _FBEQ 0x310000 2352 0177 #define _FBLT 0x320000 2353 0178 #define _FBLE 0x330000 2354 0179 #define _BSR_ 0x340000 2355 0180 #define _FBNE 0x350000 2356 0181 #define _FBGE 0x360000 2357 0182 #define _FBGT 0x370000 2358 0183 #define _BLGC 0x380000 2359 0184 #define _BEQ_ 0x390000 2360 0185 #define _BLT_ 0x3a0000 2361 0186 #define _BLE_ 0x3b0000 2362 0187 #define _BLBS 0x3c0000 2363 0188 #define _BNE_ 0x3d0000 2364 0189 #define _BGE_ 0x3e0000 2365 0190 #define _BGT_ 0x3f0000 2366 0191 2367 0192 /*** Memory Access & LDA & LDAH Instructions ***/ 2368 0193 /************************************************/ 2369 0194 #define _LDA___ 0x080000 2370 0195 #define _LDAH__ 0x090000 2371 0196 #define _OPC0A_ 0x0a0000 2372 0197 #define _LDQ_U_ 0x0b0000 2373 0198 2374 0199 #define _OPC0C_ 0x0c0000 2375 0200 #define _OPC0D_ 0x0d0000 2376 0201 #define _OPC0E_ 0x0e0000 2377 0202 #define _STQ_U_ 0x0f0000 2378 0203 #define _LDF___ 0x200000 2379 0204 #define _LDG___ 0x210000 2380 0205 #define _LDS___ 0x220000 2381 0206 #define _LDT___ 0x230000 2382 0207 #define _STF___ 0x240000 2383 0208 #define _STG___ 0x250000 2384 0209 #define _STS___ 0x260000 2385 0210 #define _STT___ 0x270000 2386 0211 #define _LDL___ 0x280000 2387 0212 #define _LDQ___ 0x290000 2388 0213 #define _LDL_L_ 0x2a0000 2389 0214 #define _LDQ_L_ 0x2b0000 2390 0215 #define _STL___ 0x2c0000 2391 0216 #define _STQ___ 0x2d0000 2392 0217 #define _STL_C_ 0x2e0000 2393 0218 #define _STQ_C_ 0x2f0000 2394 0219 2395 0220 /*** Arithmetic instructions (int and float) ***/ 2396 0221 /************************************************/ 2397 0222 #define _ADDL__ 0x100000 2398 0223 #define _S4ADDL 0x100002 2399 0224 #define _SUBL__ 0x100009 2400 0225 #define _S4SUBL 0x10000b 2401 0226 #define _CMPBGE 0x10000f 2402 0227 #define _S8ADDL 0x100012 2403 0228 #define _S8SUBL 0x10001b 2404 0229 #define _CMPULT 0x10001d 2405 0230 #define _ADDQ__ 0x100020 2406 0231 #define _S4ADDQ 0x100022 2407 0232 #define _SUBQ__ 0x100029 2408 0233 #define _S4SUBQ 0x10002b 2409 0234 #define _CMPEQ_ 0x10002d 2410 0235 #define _S8ADDQ 0x100032 2411 0236 #define _S8SUBQ 0x10003b 2412 0237 #define _CMPULE 0x10003d 2413 0238 #define _CMPLT_ 0x10004d 2414 0239 #define _CMPLE_ 0x10006d 2415 0240 2416 0241 /*** Arithmetic Logical ***/ 2417 0242 /************************************************/ 2418 0243 #define _AND___ 0x110000 2419 0244 #define _BIC___ 0x110008 2420 0245 #define _CMOVLBS 0x110014 2421 0246 #define _CMOVLBC 0x110016 2422 0247 #define _BIS___ 0x110020 2423 0248 #define _CMOVEQ 0x110024 2424 0249 #define _CMOVNE 0x110026 2425 0250 #define _ORNOT_ 0x110028 2426 0251 #define _XOR___ 0x110040 2427 0252 #define _CMOVLT 0x110044 2428 0253 #define _CMOVGE 0x110046 2429 0254 #define _EQV___ 0x110048 2430 0255 #define _AMASK_ 0x110061 2431 0256 #define _CMOVLE 0x110064 2432 0257 #define _CMOVGT 0x110066 2433 0258 #define _IMPLVER 0x11006c 2434 0259 2435 0260 /*** Integer shift instruction ***/ 2436 0261 /************************************************/ 2437 0262 #define _SRL___ 0x120034 2438 0263 #define _SLL___ 0x120039 2439 0264 #define _SRA___ 0x12003c 2440 0265 #define _ZAP___ 0x120030 2441 0266 #define _ZAPNOT 0x120031 2442 0267 #define _EXTBL_ 0x120006 2443 0268 #define _EXTWL_ 0x120016 2444 0269 #define _EXTLL_ 0x120026 2445 0270 #define _EXTQL_ 0x120036 2446 0271 #define _EXTWH_ 0x12005a 2447 0272 #define _EXTLH_ 0x12006a 2448 0273 #define _EXTQH_ 0x12007a 2449 0274 #define _INSBL_ 0x12000b 2450 0275 #define _INSWL_ 0x12001b 2451 0276 #define _INSLL_ 0x12002b 2452 0277 #define _INSQL_ 0x12003b 2453 0278 #define _MSKBL_ 0x120002 2454 0279 #define _MSKWL_ 0x120012 2455 0280 #define _MSKLL_ 0x120022 2456 0281 #define _MSKQL_ 0x120032 2457 0282 #define _MSKWH_ 0x120052 2458 0283 #define _MSKLH_ 0x120062 2459 0284 #define _MSKQH_ 0x120072 2460 0285 #define _INSWH_ 0x120057 2461 0286 #define _INSLH_ 0x120067 2462 0287 #define _INSQH_ 0x120077 2463 0288 2464 0289 /*** Floating instruction (a part of) ***/ 2465 0290 /************************************************/ 2466 0291 #define _FCMOVEQ 0x17002a 2467 0292 #define _FCMOVNE 0x17002b 2468 0293 #define _FCMOVLT 0x17002c 2469 0294 #define _FCMOVGE 0x17002d 2470 0295 #define _FCMOVLE 0x17002e 2471 0296 #define _FCMOVGT 0x17002f 2472 0297 2473 0298 /*** Multiply instruction ***/ 2474 0299 /************************************************/ 2475 0300 #define _MULL__ 0x130000 2476 0301 #define _MULQ__ 0x130020 2477 0302 #define _UMULH_ 0x130030 2478 0303 2479 0304 /************************************************/ 2480 0305 2481 0306 2482 0307 /* 4. structure and class definition */ 2483 0308 /************************************************/ 2484 0309 /*** Used in syscall.c SYS_fstat ***/ 2485 0310 struct osf_statbuf{ 2486 0311 uint_32t a_st_dev; 2487 0312 uint_32t a_st_ino; 2488 0313 uint_32t a_st_mode; 2489 0314 uint_16t a_st_nlink; 2490 0315 uint_16t a_pad0; 2491 0316 uint_32t a_st_uid; 2492 0317 uint_32t a_st_gid; 2493 0318 uint_32t a_st_rdev; 2494 0319 uint_32t a_pad1; 2495 0320 uint_64t a_st_size; 2496 0321 uint_32t a_st_atime; 2497 0322 uint_32t a_st_spare1; 2498 0323 uint_32t a_st_mtime; 2499 0324 uint_32t a_st_spare2; 2500 0325 uint_32t a_st_ctime; 2501 0326 uint_32t a_st_spare3; 2502 0327 uint_32t a_st_blksize; 2503 0328 uint_32t a_st_blocks; 2504 0329 uint_32t a_st_gennum; 2505 0330 uint_32t a_st_spare4; 2506 0331 }; 2507 0332 2508 0333 /************************************************/ 2509 0334 class Env{ 2510 0335 public: 2511 0336 class system_config *sc; 2512 0337 class evaluation_result *e; 2513 0338 class debug *deb; 2514 0339 class system_manager *sys; 2515 0340 class memory_system *mem; 2516 0341 class architecture_state *as; 2517 0342 }; 2518 0343 2519 0344 /************************************************/ 2520 0345 class system_config{ 2521 0346 public: 2522 0347 char program_name[512]; 2523 0348 uint_64t end_tc; 2524 0349 uint_64t trace_flag; 2525 0350 int slow_mode; 2526 0351 int verbose_interval; 2527 0352 int debug_flag; 2528 0353 int verify_flag; 2529 0354 int syscall_flag; 2530 0355 int simple_result; 2531 0356 int fd_adjust; 2532 0357 int fd_stdin_flag; 2533 0358 int fd_stdin; /* file descripter for STDIN */ 2534 0359 system_config(char *, char**); 2535 0360 }; 2536 0361 2537 0362 /************************************************/ 2538 0363 class evaluation_result{ 2539 0364 public: 2540 0365 uint_64t retired_inst; 2541 0366 int used_memory_block; 2542 0367 time_t time_begin; /* start time stamp */ 2543 0368 struct timeval tp; /* start time stamp */ 2544 0369 struct timezone tzp; /* start time stamp */ 2545 0370 evaluation_result(); 2546 0371 }; 2547 0372 2548 0373 /************************************************/ 2549 0374 class architecture_state{ 2550 0375 Env *ev; 2551 0376 public: 2552 0377 data_t pc; /* program counter */ 2553 0378 data_t r[32]; /* general purpose regs */ 2554 0379 data_t f[32]; /* floating point regs */ 2555 0380 uint_64t rr(int); /* register read */ 2556 0381 architecture_state(Env*); 2557 0382 architecture_state(); 2558 0383 }; 2559 0384 2560 0385 /************************************************/ 2561 0386 class main_memory{ 2562 0387 Env *ev; 2563 0388 data_t *block_table[BLOCK_TABLE_SIZE]; 2564 0389 data_t *allocblock(data_t *); 2565 0390 public: 2566 0391 void ld_8byte(data_t *, data_t *); 2567 0392 void st_8byte(data_t *, data_t *, DATA_TYPE); 2568 0393 main_memory(Env*); 2569 0394 }; 2570 0395 2571 0396 /************************************************/ 2572 0397 class memory_system{ 2573 0398 Env *ev; 2574 0399 public: 2575 0400 class main_memory *mm; 2576 0401 void ld_8byte(data_t *, data_t *); 2577 0402 void st_8byte(data_t *, data_t *, DATA_TYPE); 2578 0403 void ld_inst(data_t *, INST_TYPE *); 2579 0404 void ld_nbyte(int, data_t *, data_t *); 2580 0405 void st_nbyte(int, data_t *, data_t *); 2581 0406 ~memory_system(); 2582 0407 memory_system(Env*); 2583 0408 }; 2584 0409 2585 0410 /************************************************/ 2586 0411 class system_manager{ 2587 0412 Env *ev; 2588 0413 /* File Descriptor Mapping Table */ 2589 0414 DATA_TYPE fd_table[FD_MAPPING_MAX]; 2590 0415 /* Unique Data for rduniq & wruniq inst */ 2591 0416 DATA_TYPE uniq; 2592 0417 public: 2593 0418 int running; /* chip is running ? */ 2594 0419 void execute_pal(class instruction*); 2595 0420 int translate_fd(DATA_TYPE); 2596 0421 system_manager(Env*); 2597 0422 }; 2598 0423 2599 0424 /************************************************/ 2600 0425 class debug{ 2601 0426 Env *ev; 2602 0427 public: 2603 0428 debug(Env*); 2604 0429 void debugmode(instruction*); 2605 0430 }; 2606 0431 2607 0432 /************************************************/ 2608 0433 class instruction{ 2609 0434 public: 2610 0435 Env *ev; /* pointer to the environment */ 2611 0436 INST_TYPE ir; /* 32b: instruction code */ 2612 0437 int CI; /* 24b: Code ID */ 2613 0438 char Op; /* 6b: Opcode field */ 2614 0439 char BR; /* 1b: branch inst ? */ 2615 0440 char CM; /* 1b: CMOV inst ? */ 2616 0441 char ST; /* 4b: store inst & byte num */ 2617 0442 char LD; /* 4b: load inst & byte num */ 2618 0443 char Ai; /* 1b: Rav is immediate ? */ 2619 0444 char Bi; /* 1b: Rbv is immediate ? */ 2620 0445 char Ar; /* 1b: Rav from general-reg ? */ 2621 0446 char Br; /* 1b: Rbv from general-reg ? */ 2622 0447 char RA; /* 5b: Rav reg-read index */ 2623 0448 char RB; /* 5b: Rbv reg-read index */ 2624 0449 char WB; /* 5b: Writeback reg index */ 2625 0450 data_t Cpc; /* PC of the instruction */ 2626 0451 data_t Npc; /* PC of the next inst. */ 2627 0452 /* Calculate in Exe. stage */ 2628 0453 data_t Imm; /* immediate */ 2629 0454 data_t Adr; /* load & store : mem address */ 2630 0455 /* cmov inst. : Rmv value */ 2631 0456 data_t Rav; /* Ra */ 2632 0457 data_t Rbv; /* Rb */ 2633 0458 data_t Rcv; /* Rc */ 2634 0459 void Fetch(data_t*); /* stage 0 */ 2635 0460 void Slot(); /* stage 1 */ 2636 0461 void Rename(); /* stage 2 */ 2637 0462 void Issue(); /* stage 3 */ 2638 0463 void RegisterRead(); /* stage 4 */ 2639 0464 void Execute(); /* stage 5 */ 2640 0465 void Memory(); /* stage 6 */ 2641 0466 void WriteBack(); /* stage 7 */ 2642 0467 void BackEnd(); /* stage 4,5,6,7 */ 2643 0468 instruction(Env*); 2644 0469 }; 2645 0470 2646 0471 /************************************************/ 2647 0472 class simple_chip{ 2648 0473 public: 2649 0474 Env *ev; 2650 0475 instruction *p; 2651 0476 simple_chip(char*, char**); 2652 0477 ~simple_chip(); 2653 0478 int step(); 2654 0479 void loop(); 2655 0480 }; 2656 0481 2657 0482 /************************************************/ 2658 0483 struct alpha_stat{ /*** for syscall.cc ***/ 2659 0484 uint_64t a_st_dev; 2660 0485 uint_32t a_st_ino; 2661 0486 int_32t a___pad1; 2662 0487 uint_32t a_st_mode; 2663 0488 uint_32t a_st_nlink; 2664 0489 uint_32t a_st_uid; 2665 0490 uint_32t a_st_gid; 2666 0491 uint_64t a_st_rdev; 2667 0492 int_64t a_st_size; 2668 0493 int_64t a_st_atime; 2669 0494 int_64t a_st_mtime; 2670 0495 int_64t a_st_ctime; 2671 0496 uint_32t a_st_blocks; 2672 0497 int_32t a___pad2; 2673 0498 uint_32t a_st_blksize; 2674 0499 uint_32t a_st_flags; 2675 0500 uint_32t a_st_gen; 2676 0501 int_32t a___pad3; 2677 0502 int_64t a___unused[4]; 2678 0503 }; 2679 0504 2680 0505 2681 0506 /* 5. function prototypes */ 2682 0507 /************************************************/ 2683 0508 extern void print_evaluation_result(Env*); 2684 0509 extern void usage(); 2685 0510 extern uint_64t map_s(DATA_TYPE); 2686 0511 extern int cmov_ir(INST_TYPE); 2687 0512 extern void option_from_file(char**, char*); 2688 0513 extern void house_keeper(instruction*); 2689 0514 extern "C" int simple_cpu(int, uint_64t*); 2690 0515 extern uint_64t get_hex(char*); 2691 0516 extern int get_code(INST_TYPE); 2692 0517 extern int ld_bytes(int); 2693 0518 extern int st_bytes(int); 2694 0519 extern DATA_TYPE sext(DATA_TYPE); 2695 0520 extern DATA_TYPE sext16(DATA_TYPE); 2696 0521 extern DATA_TYPE sext21(DATA_TYPE); 2697 0522 extern int RA(INST_TYPE); 2698 0523 extern int RB(INST_TYPE); 2699 0524 extern int WR(int); 2700 0525 extern void set_ld_data(int, int, data_t*, 2701 0526 data_t*, data_t*); 2702 0527 extern void set_st_data(int, int, data_t*, 2703 0528 data_t*, data_t*, 2704 0529 DATA_TYPE*); 2705 0530 extern void UnitA(int, DATA_TYPE, 2706 0531 DATA_TYPE, DATA_TYPE*); 2707 0532 extern void UnitL(int, DATA_TYPE, 2708 0533 DATA_TYPE, DATA_TYPE*); 2709 0534 extern void UnitS(int, DATA_TYPE, 2710 0535 DATA_TYPE, DATA_TYPE*); 2711 0536 extern void UnitM(int, DATA_TYPE, 2712 0537 DATA_TYPE, DATA_TYPE*); 2713 0538 extern void FuITFP(INST_TYPE, DATA_TYPE, 2714 0539 DATA_TYPE, DATA_TYPE*); 2715 0540 extern void FuFLTL(INST_TYPE, DATA_TYPE, 2716 0541 DATA_TYPE, DATA_TYPE*); 2717 0542 extern void FuFPTI(INST_TYPE, DATA_TYPE, 2718 0543 DATA_TYPE, DATA_TYPE*); 2719 0544 extern void FuFLTI(INST_TYPE, DATA_TYPE, 2720 0545 DATA_TYPE, DATA_TYPE*); 2721 0546 extern void CmovUnit(int, DATA_TYPE, int*); 2722 0547 extern int Btaken(int, DATA_TYPE); 2723 0548 extern void print_register_name(int); 2724 0549 /************************************************/