60namespace Trace { 61SharedData *shared_data = NULL; 62} 63 64//////////////////////////////////////////////////////////////////////// 65// 66// Methods for the InstRecord object 67// 68 69#if THE_ISA == SPARC_ISA 70 71inline char * genCenteredLabel(int length, char * buffer, char * label) 72{ 73 int labelLength = strlen(label); 74 assert(labelLength <= length); 75 int leftPad = (length - labelLength) / 2; 76 int rightPad = length - leftPad - labelLength; 77 char format[64]; 78 sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad); 79 sprintf(buffer, format, "", label, ""); 80 return buffer; 81} 82 83inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b) 84{ 85 ccprintf(os, " %16s | %#018x %s %#-018x \n", 86 title, a, (a == b) ? "|" : "X", b); 87} 88 89inline void printColumnLabels(ostream & os) 90{ 91 static char * regLabel = genCenteredLabel(16, new char[17], "Register"); 92 static char * m5Label = genCenteredLabel(18, new char[18], "M5"); 93 static char * legionLabel = genCenteredLabel(18, new char[18], "Legion"); 94 ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel); 95 ccprintf(os, "--------------------+-----------------------+-----------------------\n"); 96} 97 98inline void printSectionHeader(ostream & os, char * name) 99{ 100 char sectionString[70]; 101 genCenteredLabel(69, sectionString, name); 102 ccprintf(os, "====================================================================\n"); 103 ccprintf(os, "%69s\n", sectionString); 104 ccprintf(os, "====================================================================\n"); 105} 106 107inline void printLevelHeader(ostream & os, int level) 108{ 109 char sectionString[70]; 110 char levelName[70]; 111 sprintf(levelName, "Trap stack level %d", level); 112 genCenteredLabel(69, sectionString, levelName); 113 ccprintf(os, "====================================================================\n"); 114 ccprintf(os, "%69s\n", sectionString); 115 ccprintf(os, "====================================================================\n"); 116} 117 118#endif 119 120void 121Trace::InstRecord::dump(ostream &outs) 122{ 123 if (flags[PRINT_REG_DELTA]) 124 { 125#if THE_ISA == SPARC_ISA 126 //Don't print what happens for each micro-op, just print out 127 //once at the last op, and for regular instructions. 128 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) 129 { 130 static uint64_t regs[32] = { 131 0, 0, 0, 0, 0, 0, 0, 0, 132 0, 0, 0, 0, 0, 0, 0, 0, 133 0, 0, 0, 0, 0, 0, 0, 0, 134 0, 0, 0, 0, 0, 0, 0, 0}; 135 static uint64_t ccr = 0; 136 static uint64_t y = 0; 137 static uint64_t floats[32]; 138 uint64_t newVal; 139 static const char * prefixes[4] = {"G", "O", "L", "I"}; 140 141 outs << hex; 142 outs << "PC = " << thread->readNextPC(); 143 outs << " NPC = " << thread->readNextNPC(); 144 newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); 145 if(newVal != ccr) 146 { 147 outs << " CCR = " << newVal; 148 ccr = newVal; 149 } 150 newVal = thread->readMiscReg(SparcISA::MISCREG_Y); 151 if(newVal != y) 152 { 153 outs << " Y = " << newVal; 154 y = newVal; 155 } 156 for(int y = 0; y < 4; y++) 157 { 158 for(int x = 0; x < 8; x++) 159 { 160 int index = x + 8 * y; 161 newVal = thread->readIntReg(index); 162 if(regs[index] != newVal) 163 { 164 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal; 165 regs[index] = newVal; 166 } 167 } 168 } 169 for(int y = 0; y < 32; y++) 170 { 171 newVal = thread->readFloatRegBits(2 * y, 64); 172 if(floats[y] != newVal) 173 { 174 outs << " F" << dec << (2 * y) << " = " << hex << newVal; 175 floats[y] = newVal; 176 } 177 } 178 outs << dec << endl; 179 } 180#endif 181 } 182 else if (flags[INTEL_FORMAT]) { 183#if FULL_SYSTEM 184 bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system); 185#else 186 bool is_trace_system = true; 187#endif 188 if (is_trace_system) { 189 ccprintf(outs, "%7d ) ", cycle); 190 outs << "0x" << hex << PC << ":\t"; 191 if (staticInst->isLoad()) { 192 outs << "<RD 0x" << hex << addr; 193 outs << ">"; 194 } else if (staticInst->isStore()) { 195 outs << "<WR 0x" << hex << addr; 196 outs << ">"; 197 } 198 outs << endl; 199 } 200 } else { 201 if (flags[PRINT_CYCLE]) 202 ccprintf(outs, "%7d: ", cycle); 203 204 outs << thread->getCpuPtr()->name() << " "; 205 206 if (flags[TRACE_MISSPEC]) 207 outs << (misspeculating ? "-" : "+") << " "; 208 209 if (flags[PRINT_THREAD_NUM]) 210 outs << "T" << thread->getThreadNum() << " : "; 211 212 213 std::string sym_str; 214 Addr sym_addr; 215 if (debugSymbolTable 216 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr) 217 && flags[PC_SYMBOL]) { 218 if (PC != sym_addr) 219 sym_str += csprintf("+%d", PC - sym_addr); 220 outs << "@" << sym_str << " : "; 221 } 222 else { 223 outs << "0x" << hex << PC << " : "; 224 } 225 226 // 227 // Print decoded instruction 228 // 229 230#if defined(__GNUC__) && (__GNUC__ < 3) 231 // There's a bug in gcc 2.x library that prevents setw() 232 // from working properly on strings 233 string mc(staticInst->disassemble(PC, debugSymbolTable)); 234 while (mc.length() < 26) 235 mc += " "; 236 outs << mc; 237#else 238 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable); 239#endif 240 241 outs << " : "; 242 243 if (flags[PRINT_OP_CLASS]) { 244 outs << opClassStrings[staticInst->opClass()] << " : "; 245 } 246 247 if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) { 248 outs << " D="; 249#if 0 250 if (data_status == DataDouble) 251 ccprintf(outs, "%f", data.as_double); 252 else 253 ccprintf(outs, "%#018x", data.as_int); 254#else 255 ccprintf(outs, "%#018x", data.as_int); 256#endif 257 } 258 259 if (flags[PRINT_EFF_ADDR] && addr_valid) 260 outs << " A=0x" << hex << addr; 261 262 if (flags[PRINT_INT_REGS] && regs_valid) { 263 for (int i = 0; i < TheISA::NumIntRegs;) 264 for (int j = i + 1; i <= j; i++) 265 ccprintf(outs, "r%02d = %#018x%s", i, 266 iregs->regs.readReg(i), 267 ((i == j) ? "\n" : " ")); 268 outs << "\n"; 269 } 270 271 if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid) 272 outs << " FetchSeq=" << dec << fetch_seq; 273 274 if (flags[PRINT_CP_SEQ] && cp_seq_valid) 275 outs << " CPSeq=" << dec << cp_seq; 276 277 // 278 // End of line... 279 // 280 outs << endl; 281 } 282#if THE_ISA == SPARC_ISA && FULL_SYSTEM 283 // Compare 284 if (flags[LEGION_LOCKSTEP]) 285 { 286 bool compared = false; 287 bool diffPC = false; 288 bool diffCC = false; 289 bool diffInst = false; 290 bool diffRegs = false; 291 bool diffTpc = false; 292 bool diffTnpc = false; 293 bool diffTstate = false; 294 bool diffTt = false; 295 bool diffTba = false; 296 bool diffHpstate = false; 297 bool diffHtstate = false; 298 bool diffHtba = false; 299 bool diffPstate = false; 300 bool diffY = false; 301 bool diffCcr = false; 302 bool diffTl = false; 303 bool diffGl = false; 304 bool diffAsi = false; 305 bool diffPil = false; 306 bool diffCwp = false; 307 bool diffCansave = false; 308 bool diffCanrestore = false; 309 bool diffOtherwin = false; 310 bool diffCleanwin = false; 311 Addr m5Pc, lgnPc; 312 313 314 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { 315 while (!compared) { 316 if (shared_data->flags == OWN_M5) { 317 m5Pc = PC & TheISA::PAddrImplMask; 318 lgnPc = shared_data->pc & TheISA::PAddrImplMask; 319 if (lgnPc != m5Pc) 320 diffPC = true; 321 322 if (shared_data->cycle_count != 323 thread->getCpuPtr()->instCount()) 324 diffCC = true; 325 326 if (shared_data->instruction != 327 (SparcISA::MachInst)staticInst->machInst) { 328 diffInst = true; 329 } 330 for (int i = 0; i < TheISA::NumIntArchRegs; i++) { 331 if (thread->readIntReg(i) != shared_data->intregs[i]) { 332 diffRegs = true; 333 } 334 } 335 uint64_t oldTl = thread->readMiscReg(MISCREG_TL); 336 if (oldTl != shared_data->tl) 337 diffTl = true; 338 for (int i = 1; i <= MaxTL; i++) { 339 thread->setMiscReg(MISCREG_TL, i); 340 if (thread->readMiscReg(MISCREG_TPC) != 341 shared_data->tpc[i-1]) 342 diffTpc = true; 343 if (thread->readMiscReg(MISCREG_TNPC) != 344 shared_data->tnpc[i-1]) 345 diffTnpc = true; 346 if (thread->readMiscReg(MISCREG_TSTATE) != 347 shared_data->tstate[i-1]) 348 diffTstate = true; 349 if (thread->readMiscReg(MISCREG_TT) != 350 shared_data->tt[i-1]) 351 diffTt = true; 352 if (thread->readMiscReg(MISCREG_HTSTATE) != 353 shared_data->htstate[i-1]) 354 diffHtstate = true; 355 } 356 thread->setMiscReg(MISCREG_TL, oldTl); 357 358 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA)) 359 diffTba = true; 360 //When the hpstate register is read by an instruction, 361 //legion has bit 11 set. When it's in storage, it doesn't. 362 //Since we don't directly support seperate interpretations 363 //of the registers like that, the bit is always set to 1 and 364 //we just don't compare it. It's not supposed to matter 365 //anyway. 366 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE)) 367 diffHpstate = true; 368 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA)) 369 diffHtba = true; 370 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE)) 371 diffPstate = true; 372 if(shared_data->y != thread->readMiscReg(MISCREG_Y)) 373 diffY = true; 374 if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) 375 diffCcr = true; 376 if(shared_data->gl != thread->readMiscReg(MISCREG_GL)) 377 diffGl = true; 378 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI)) 379 diffAsi = true; 380 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL)) 381 diffPil = true; 382 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP)) 383 diffCwp = true; 384 if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE)) 385 diffCansave = true; 386 if(shared_data->canrestore != 387 thread->readMiscReg(MISCREG_CANRESTORE)) 388 diffCanrestore = true; 389 if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN)) 390 diffOtherwin = true; 391 if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN)) 392 diffCleanwin = true; 393 394 if (diffPC || diffCC || diffInst || diffRegs || diffTpc || 395 diffTnpc || diffTstate || diffTt || diffHpstate || 396 diffHtstate || diffHtba || diffPstate || diffY || 397 diffCcr || diffTl || diffGl || diffAsi || diffPil || 398 diffCwp || diffCansave || diffCanrestore || 399 diffOtherwin || diffCleanwin) { 400 outs << "Differences found between M5 and Legion:"; 401 if (diffPC) 402 outs << " [PC]"; 403 if (diffCC) 404 outs << " [CC]"; 405 if (diffInst) 406 outs << " [Instruction]"; 407 if (diffRegs) 408 outs << " [IntRegs]"; 409 if (diffTpc) 410 outs << " [Tpc]"; 411 if (diffTnpc) 412 outs << " [Tnpc]"; 413 if (diffTstate) 414 outs << " [Tstate]"; 415 if (diffTt) 416 outs << " [Tt]"; 417 if (diffHpstate) 418 outs << " [Hpstate]"; 419 if (diffHtstate) 420 outs << " [Htstate]"; 421 if (diffHtba) 422 outs << " [Htba]"; 423 if (diffPstate) 424 outs << " [Pstate]"; 425 if (diffY) 426 outs << " [Y]"; 427 if (diffCcr) 428 outs << " [Ccr]"; 429 if (diffTl) 430 outs << " [Tl]"; 431 if (diffGl) 432 outs << " [Gl]"; 433 if (diffAsi) 434 outs << " [Asi]"; 435 if (diffPil) 436 outs << " [Pil]"; 437 if (diffCwp) 438 outs << " [Cwp]"; 439 if (diffCansave) 440 outs << " [Cansave]"; 441 if (diffCanrestore) 442 outs << " [Canrestore]"; 443 if (diffOtherwin) 444 outs << " [Otherwin]"; 445 if (diffCleanwin) 446 outs << " [Cleanwin]"; 447 outs << endl << endl; 448 449 outs << right << setfill(' ') << setw(15) 450 << "M5 PC: " << "0x"<< setw(16) << setfill('0') 451 << hex << m5Pc << endl; 452 outs << setfill(' ') << setw(15) 453 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex 454 << lgnPc << endl << endl; 455 456 outs << right << setfill(' ') << setw(15) 457 << "M5 CC: " << "0x"<< setw(16) << setfill('0') 458 << hex << thread->getCpuPtr()->instCount() << endl; 459 outs << setfill(' ') << setw(15) 460 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex 461 << shared_data->cycle_count << endl << endl; 462 463 outs << setfill(' ') << setw(15) 464 << "M5 Inst: " << "0x"<< setw(8) 465 << setfill('0') << hex << staticInst->machInst 466 << staticInst->disassemble(m5Pc, debugSymbolTable) 467 << endl; 468 469 StaticInstPtr legionInst = 470 StaticInst::decode(makeExtMI(shared_data->instruction, 471 thread)); 472 outs << setfill(' ') << setw(15) 473 << " Legion Inst: " 474 << "0x" << setw(8) << setfill('0') << hex 475 << shared_data->instruction 476 << legionInst->disassemble(lgnPc, debugSymbolTable) 477 << endl << endl; 478 479 printSectionHeader(outs, "General State"); 480 printColumnLabels(outs); 481 printRegPair(outs, "HPstate", 482 thread->readMiscReg(MISCREG_HPSTATE), 483 shared_data->hpstate | (1 << 11)); 484 printRegPair(outs, "Htba", 485 thread->readMiscReg(MISCREG_HTBA), 486 shared_data->htba); 487 printRegPair(outs, "Pstate", 488 thread->readMiscReg(MISCREG_PSTATE), 489 shared_data->pstate); 490 printRegPair(outs, "Y", 491 thread->readMiscReg(MISCREG_Y), 492 shared_data->y); 493 printRegPair(outs, "Ccr", 494 thread->readMiscReg(MISCREG_CCR), 495 shared_data->ccr); 496 printRegPair(outs, "Tl", 497 thread->readMiscReg(MISCREG_TL), 498 shared_data->tl); 499 printRegPair(outs, "Gl", 500 thread->readMiscReg(MISCREG_GL), 501 shared_data->gl); 502 printRegPair(outs, "Asi", 503 thread->readMiscReg(MISCREG_ASI), 504 shared_data->asi); 505 printRegPair(outs, "Pil", 506 thread->readMiscReg(MISCREG_PIL), 507 shared_data->pil); 508 printRegPair(outs, "Cwp", 509 thread->readMiscReg(MISCREG_CWP), 510 shared_data->cwp); 511 printRegPair(outs, "Cansave", 512 thread->readMiscReg(MISCREG_CANSAVE), 513 shared_data->cansave); 514 printRegPair(outs, "Canrestore", 515 thread->readMiscReg(MISCREG_CANRESTORE), 516 shared_data->canrestore); 517 printRegPair(outs, "Otherwin", 518 thread->readMiscReg(MISCREG_OTHERWIN), 519 shared_data->otherwin); 520 printRegPair(outs, "Cleanwin", 521 thread->readMiscReg(MISCREG_CLEANWIN), 522 shared_data->cleanwin); 523 outs << endl; 524 for (int i = 1; i <= MaxTL; i++) { 525 printLevelHeader(outs, i); 526 printColumnLabels(outs); 527 thread->setMiscReg(MISCREG_TL, i); 528 printRegPair(outs, "Tpc", 529 thread->readMiscReg(MISCREG_TPC), 530 shared_data->tpc[i-1]); 531 printRegPair(outs, "Tnpc", 532 thread->readMiscReg(MISCREG_TNPC), 533 shared_data->tnpc[i-1]); 534 printRegPair(outs, "Tstate", 535 thread->readMiscReg(MISCREG_TSTATE), 536 shared_data->tstate[i-1]); 537 printRegPair(outs, "Tt", 538 thread->readMiscReg(MISCREG_TT), 539 shared_data->tt[i-1]); 540 printRegPair(outs, "Htstate", 541 thread->readMiscReg(MISCREG_HTSTATE), 542 shared_data->htstate[i-1]); 543 } 544 thread->setMiscReg(MISCREG_TL, oldTl); 545 outs << endl; 546 547 printSectionHeader(outs, "General Purpose Registers"); 548 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"}; 549 for(int y = 0; y < 4; y++) 550 { 551 for(int x = 0; x < 8; x++) 552 { 553 char label[8]; 554 sprintf(label, "%s%d", regtypes[y], x); 555 printRegPair(outs, label, 556 thread->readIntReg(y*8+x), 557 shared_data->intregs[y*8+x]); 558 /*outs << regtypes[y] << x << " " ; 559 outs << "0x" << hex << setw(16) 560 << thread->readIntReg(y*8+x); 561 if (thread->readIntReg(y*8 + x) 562 != shared_data->intregs[y*8+x]) 563 outs << " X "; 564 else 565 outs << " | "; 566 outs << "0x" << setw(16) << hex 567 << shared_data->intregs[y*8+x] 568 << endl;*/ 569 } 570 }
| 62namespace Trace { 63SharedData *shared_data = NULL; 64} 65 66//////////////////////////////////////////////////////////////////////// 67// 68// Methods for the InstRecord object 69// 70 71#if THE_ISA == SPARC_ISA 72 73inline char * genCenteredLabel(int length, char * buffer, char * label) 74{ 75 int labelLength = strlen(label); 76 assert(labelLength <= length); 77 int leftPad = (length - labelLength) / 2; 78 int rightPad = length - leftPad - labelLength; 79 char format[64]; 80 sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad); 81 sprintf(buffer, format, "", label, ""); 82 return buffer; 83} 84 85inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b) 86{ 87 ccprintf(os, " %16s | %#018x %s %#-018x \n", 88 title, a, (a == b) ? "|" : "X", b); 89} 90 91inline void printColumnLabels(ostream & os) 92{ 93 static char * regLabel = genCenteredLabel(16, new char[17], "Register"); 94 static char * m5Label = genCenteredLabel(18, new char[18], "M5"); 95 static char * legionLabel = genCenteredLabel(18, new char[18], "Legion"); 96 ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel); 97 ccprintf(os, "--------------------+-----------------------+-----------------------\n"); 98} 99 100inline void printSectionHeader(ostream & os, char * name) 101{ 102 char sectionString[70]; 103 genCenteredLabel(69, sectionString, name); 104 ccprintf(os, "====================================================================\n"); 105 ccprintf(os, "%69s\n", sectionString); 106 ccprintf(os, "====================================================================\n"); 107} 108 109inline void printLevelHeader(ostream & os, int level) 110{ 111 char sectionString[70]; 112 char levelName[70]; 113 sprintf(levelName, "Trap stack level %d", level); 114 genCenteredLabel(69, sectionString, levelName); 115 ccprintf(os, "====================================================================\n"); 116 ccprintf(os, "%69s\n", sectionString); 117 ccprintf(os, "====================================================================\n"); 118} 119 120#endif 121 122void 123Trace::InstRecord::dump(ostream &outs) 124{ 125 if (flags[PRINT_REG_DELTA]) 126 { 127#if THE_ISA == SPARC_ISA 128 //Don't print what happens for each micro-op, just print out 129 //once at the last op, and for regular instructions. 130 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) 131 { 132 static uint64_t regs[32] = { 133 0, 0, 0, 0, 0, 0, 0, 0, 134 0, 0, 0, 0, 0, 0, 0, 0, 135 0, 0, 0, 0, 0, 0, 0, 0, 136 0, 0, 0, 0, 0, 0, 0, 0}; 137 static uint64_t ccr = 0; 138 static uint64_t y = 0; 139 static uint64_t floats[32]; 140 uint64_t newVal; 141 static const char * prefixes[4] = {"G", "O", "L", "I"}; 142 143 outs << hex; 144 outs << "PC = " << thread->readNextPC(); 145 outs << " NPC = " << thread->readNextNPC(); 146 newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); 147 if(newVal != ccr) 148 { 149 outs << " CCR = " << newVal; 150 ccr = newVal; 151 } 152 newVal = thread->readMiscReg(SparcISA::MISCREG_Y); 153 if(newVal != y) 154 { 155 outs << " Y = " << newVal; 156 y = newVal; 157 } 158 for(int y = 0; y < 4; y++) 159 { 160 for(int x = 0; x < 8; x++) 161 { 162 int index = x + 8 * y; 163 newVal = thread->readIntReg(index); 164 if(regs[index] != newVal) 165 { 166 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal; 167 regs[index] = newVal; 168 } 169 } 170 } 171 for(int y = 0; y < 32; y++) 172 { 173 newVal = thread->readFloatRegBits(2 * y, 64); 174 if(floats[y] != newVal) 175 { 176 outs << " F" << dec << (2 * y) << " = " << hex << newVal; 177 floats[y] = newVal; 178 } 179 } 180 outs << dec << endl; 181 } 182#endif 183 } 184 else if (flags[INTEL_FORMAT]) { 185#if FULL_SYSTEM 186 bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system); 187#else 188 bool is_trace_system = true; 189#endif 190 if (is_trace_system) { 191 ccprintf(outs, "%7d ) ", cycle); 192 outs << "0x" << hex << PC << ":\t"; 193 if (staticInst->isLoad()) { 194 outs << "<RD 0x" << hex << addr; 195 outs << ">"; 196 } else if (staticInst->isStore()) { 197 outs << "<WR 0x" << hex << addr; 198 outs << ">"; 199 } 200 outs << endl; 201 } 202 } else { 203 if (flags[PRINT_CYCLE]) 204 ccprintf(outs, "%7d: ", cycle); 205 206 outs << thread->getCpuPtr()->name() << " "; 207 208 if (flags[TRACE_MISSPEC]) 209 outs << (misspeculating ? "-" : "+") << " "; 210 211 if (flags[PRINT_THREAD_NUM]) 212 outs << "T" << thread->getThreadNum() << " : "; 213 214 215 std::string sym_str; 216 Addr sym_addr; 217 if (debugSymbolTable 218 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr) 219 && flags[PC_SYMBOL]) { 220 if (PC != sym_addr) 221 sym_str += csprintf("+%d", PC - sym_addr); 222 outs << "@" << sym_str << " : "; 223 } 224 else { 225 outs << "0x" << hex << PC << " : "; 226 } 227 228 // 229 // Print decoded instruction 230 // 231 232#if defined(__GNUC__) && (__GNUC__ < 3) 233 // There's a bug in gcc 2.x library that prevents setw() 234 // from working properly on strings 235 string mc(staticInst->disassemble(PC, debugSymbolTable)); 236 while (mc.length() < 26) 237 mc += " "; 238 outs << mc; 239#else 240 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable); 241#endif 242 243 outs << " : "; 244 245 if (flags[PRINT_OP_CLASS]) { 246 outs << opClassStrings[staticInst->opClass()] << " : "; 247 } 248 249 if (flags[PRINT_RESULT_DATA] && data_status != DataInvalid) { 250 outs << " D="; 251#if 0 252 if (data_status == DataDouble) 253 ccprintf(outs, "%f", data.as_double); 254 else 255 ccprintf(outs, "%#018x", data.as_int); 256#else 257 ccprintf(outs, "%#018x", data.as_int); 258#endif 259 } 260 261 if (flags[PRINT_EFF_ADDR] && addr_valid) 262 outs << " A=0x" << hex << addr; 263 264 if (flags[PRINT_INT_REGS] && regs_valid) { 265 for (int i = 0; i < TheISA::NumIntRegs;) 266 for (int j = i + 1; i <= j; i++) 267 ccprintf(outs, "r%02d = %#018x%s", i, 268 iregs->regs.readReg(i), 269 ((i == j) ? "\n" : " ")); 270 outs << "\n"; 271 } 272 273 if (flags[PRINT_FETCH_SEQ] && fetch_seq_valid) 274 outs << " FetchSeq=" << dec << fetch_seq; 275 276 if (flags[PRINT_CP_SEQ] && cp_seq_valid) 277 outs << " CPSeq=" << dec << cp_seq; 278 279 // 280 // End of line... 281 // 282 outs << endl; 283 } 284#if THE_ISA == SPARC_ISA && FULL_SYSTEM 285 // Compare 286 if (flags[LEGION_LOCKSTEP]) 287 { 288 bool compared = false; 289 bool diffPC = false; 290 bool diffCC = false; 291 bool diffInst = false; 292 bool diffRegs = false; 293 bool diffTpc = false; 294 bool diffTnpc = false; 295 bool diffTstate = false; 296 bool diffTt = false; 297 bool diffTba = false; 298 bool diffHpstate = false; 299 bool diffHtstate = false; 300 bool diffHtba = false; 301 bool diffPstate = false; 302 bool diffY = false; 303 bool diffCcr = false; 304 bool diffTl = false; 305 bool diffGl = false; 306 bool diffAsi = false; 307 bool diffPil = false; 308 bool diffCwp = false; 309 bool diffCansave = false; 310 bool diffCanrestore = false; 311 bool diffOtherwin = false; 312 bool diffCleanwin = false; 313 Addr m5Pc, lgnPc; 314 315 316 if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { 317 while (!compared) { 318 if (shared_data->flags == OWN_M5) { 319 m5Pc = PC & TheISA::PAddrImplMask; 320 lgnPc = shared_data->pc & TheISA::PAddrImplMask; 321 if (lgnPc != m5Pc) 322 diffPC = true; 323 324 if (shared_data->cycle_count != 325 thread->getCpuPtr()->instCount()) 326 diffCC = true; 327 328 if (shared_data->instruction != 329 (SparcISA::MachInst)staticInst->machInst) { 330 diffInst = true; 331 } 332 for (int i = 0; i < TheISA::NumIntArchRegs; i++) { 333 if (thread->readIntReg(i) != shared_data->intregs[i]) { 334 diffRegs = true; 335 } 336 } 337 uint64_t oldTl = thread->readMiscReg(MISCREG_TL); 338 if (oldTl != shared_data->tl) 339 diffTl = true; 340 for (int i = 1; i <= MaxTL; i++) { 341 thread->setMiscReg(MISCREG_TL, i); 342 if (thread->readMiscReg(MISCREG_TPC) != 343 shared_data->tpc[i-1]) 344 diffTpc = true; 345 if (thread->readMiscReg(MISCREG_TNPC) != 346 shared_data->tnpc[i-1]) 347 diffTnpc = true; 348 if (thread->readMiscReg(MISCREG_TSTATE) != 349 shared_data->tstate[i-1]) 350 diffTstate = true; 351 if (thread->readMiscReg(MISCREG_TT) != 352 shared_data->tt[i-1]) 353 diffTt = true; 354 if (thread->readMiscReg(MISCREG_HTSTATE) != 355 shared_data->htstate[i-1]) 356 diffHtstate = true; 357 } 358 thread->setMiscReg(MISCREG_TL, oldTl); 359 360 if(shared_data->tba != thread->readMiscReg(MISCREG_TBA)) 361 diffTba = true; 362 //When the hpstate register is read by an instruction, 363 //legion has bit 11 set. When it's in storage, it doesn't. 364 //Since we don't directly support seperate interpretations 365 //of the registers like that, the bit is always set to 1 and 366 //we just don't compare it. It's not supposed to matter 367 //anyway. 368 if((shared_data->hpstate | (1 << 11)) != thread->readMiscReg(MISCREG_HPSTATE)) 369 diffHpstate = true; 370 if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA)) 371 diffHtba = true; 372 if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE)) 373 diffPstate = true; 374 if(shared_data->y != thread->readMiscReg(MISCREG_Y)) 375 diffY = true; 376 if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR)) 377 diffCcr = true; 378 if(shared_data->gl != thread->readMiscReg(MISCREG_GL)) 379 diffGl = true; 380 if(shared_data->asi != thread->readMiscReg(MISCREG_ASI)) 381 diffAsi = true; 382 if(shared_data->pil != thread->readMiscReg(MISCREG_PIL)) 383 diffPil = true; 384 if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP)) 385 diffCwp = true; 386 if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE)) 387 diffCansave = true; 388 if(shared_data->canrestore != 389 thread->readMiscReg(MISCREG_CANRESTORE)) 390 diffCanrestore = true; 391 if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN)) 392 diffOtherwin = true; 393 if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN)) 394 diffCleanwin = true; 395 396 if (diffPC || diffCC || diffInst || diffRegs || diffTpc || 397 diffTnpc || diffTstate || diffTt || diffHpstate || 398 diffHtstate || diffHtba || diffPstate || diffY || 399 diffCcr || diffTl || diffGl || diffAsi || diffPil || 400 diffCwp || diffCansave || diffCanrestore || 401 diffOtherwin || diffCleanwin) { 402 outs << "Differences found between M5 and Legion:"; 403 if (diffPC) 404 outs << " [PC]"; 405 if (diffCC) 406 outs << " [CC]"; 407 if (diffInst) 408 outs << " [Instruction]"; 409 if (diffRegs) 410 outs << " [IntRegs]"; 411 if (diffTpc) 412 outs << " [Tpc]"; 413 if (diffTnpc) 414 outs << " [Tnpc]"; 415 if (diffTstate) 416 outs << " [Tstate]"; 417 if (diffTt) 418 outs << " [Tt]"; 419 if (diffHpstate) 420 outs << " [Hpstate]"; 421 if (diffHtstate) 422 outs << " [Htstate]"; 423 if (diffHtba) 424 outs << " [Htba]"; 425 if (diffPstate) 426 outs << " [Pstate]"; 427 if (diffY) 428 outs << " [Y]"; 429 if (diffCcr) 430 outs << " [Ccr]"; 431 if (diffTl) 432 outs << " [Tl]"; 433 if (diffGl) 434 outs << " [Gl]"; 435 if (diffAsi) 436 outs << " [Asi]"; 437 if (diffPil) 438 outs << " [Pil]"; 439 if (diffCwp) 440 outs << " [Cwp]"; 441 if (diffCansave) 442 outs << " [Cansave]"; 443 if (diffCanrestore) 444 outs << " [Canrestore]"; 445 if (diffOtherwin) 446 outs << " [Otherwin]"; 447 if (diffCleanwin) 448 outs << " [Cleanwin]"; 449 outs << endl << endl; 450 451 outs << right << setfill(' ') << setw(15) 452 << "M5 PC: " << "0x"<< setw(16) << setfill('0') 453 << hex << m5Pc << endl; 454 outs << setfill(' ') << setw(15) 455 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex 456 << lgnPc << endl << endl; 457 458 outs << right << setfill(' ') << setw(15) 459 << "M5 CC: " << "0x"<< setw(16) << setfill('0') 460 << hex << thread->getCpuPtr()->instCount() << endl; 461 outs << setfill(' ') << setw(15) 462 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex 463 << shared_data->cycle_count << endl << endl; 464 465 outs << setfill(' ') << setw(15) 466 << "M5 Inst: " << "0x"<< setw(8) 467 << setfill('0') << hex << staticInst->machInst 468 << staticInst->disassemble(m5Pc, debugSymbolTable) 469 << endl; 470 471 StaticInstPtr legionInst = 472 StaticInst::decode(makeExtMI(shared_data->instruction, 473 thread)); 474 outs << setfill(' ') << setw(15) 475 << " Legion Inst: " 476 << "0x" << setw(8) << setfill('0') << hex 477 << shared_data->instruction 478 << legionInst->disassemble(lgnPc, debugSymbolTable) 479 << endl << endl; 480 481 printSectionHeader(outs, "General State"); 482 printColumnLabels(outs); 483 printRegPair(outs, "HPstate", 484 thread->readMiscReg(MISCREG_HPSTATE), 485 shared_data->hpstate | (1 << 11)); 486 printRegPair(outs, "Htba", 487 thread->readMiscReg(MISCREG_HTBA), 488 shared_data->htba); 489 printRegPair(outs, "Pstate", 490 thread->readMiscReg(MISCREG_PSTATE), 491 shared_data->pstate); 492 printRegPair(outs, "Y", 493 thread->readMiscReg(MISCREG_Y), 494 shared_data->y); 495 printRegPair(outs, "Ccr", 496 thread->readMiscReg(MISCREG_CCR), 497 shared_data->ccr); 498 printRegPair(outs, "Tl", 499 thread->readMiscReg(MISCREG_TL), 500 shared_data->tl); 501 printRegPair(outs, "Gl", 502 thread->readMiscReg(MISCREG_GL), 503 shared_data->gl); 504 printRegPair(outs, "Asi", 505 thread->readMiscReg(MISCREG_ASI), 506 shared_data->asi); 507 printRegPair(outs, "Pil", 508 thread->readMiscReg(MISCREG_PIL), 509 shared_data->pil); 510 printRegPair(outs, "Cwp", 511 thread->readMiscReg(MISCREG_CWP), 512 shared_data->cwp); 513 printRegPair(outs, "Cansave", 514 thread->readMiscReg(MISCREG_CANSAVE), 515 shared_data->cansave); 516 printRegPair(outs, "Canrestore", 517 thread->readMiscReg(MISCREG_CANRESTORE), 518 shared_data->canrestore); 519 printRegPair(outs, "Otherwin", 520 thread->readMiscReg(MISCREG_OTHERWIN), 521 shared_data->otherwin); 522 printRegPair(outs, "Cleanwin", 523 thread->readMiscReg(MISCREG_CLEANWIN), 524 shared_data->cleanwin); 525 outs << endl; 526 for (int i = 1; i <= MaxTL; i++) { 527 printLevelHeader(outs, i); 528 printColumnLabels(outs); 529 thread->setMiscReg(MISCREG_TL, i); 530 printRegPair(outs, "Tpc", 531 thread->readMiscReg(MISCREG_TPC), 532 shared_data->tpc[i-1]); 533 printRegPair(outs, "Tnpc", 534 thread->readMiscReg(MISCREG_TNPC), 535 shared_data->tnpc[i-1]); 536 printRegPair(outs, "Tstate", 537 thread->readMiscReg(MISCREG_TSTATE), 538 shared_data->tstate[i-1]); 539 printRegPair(outs, "Tt", 540 thread->readMiscReg(MISCREG_TT), 541 shared_data->tt[i-1]); 542 printRegPair(outs, "Htstate", 543 thread->readMiscReg(MISCREG_HTSTATE), 544 shared_data->htstate[i-1]); 545 } 546 thread->setMiscReg(MISCREG_TL, oldTl); 547 outs << endl; 548 549 printSectionHeader(outs, "General Purpose Registers"); 550 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"}; 551 for(int y = 0; y < 4; y++) 552 { 553 for(int x = 0; x < 8; x++) 554 { 555 char label[8]; 556 sprintf(label, "%s%d", regtypes[y], x); 557 printRegPair(outs, label, 558 thread->readIntReg(y*8+x), 559 shared_data->intregs[y*8+x]); 560 /*outs << regtypes[y] << x << " " ; 561 outs << "0x" << hex << setw(16) 562 << thread->readIntReg(y*8+x); 563 if (thread->readIntReg(y*8 + x) 564 != shared_data->intregs[y*8+x]) 565 outs << " X "; 566 else 567 outs << " | "; 568 outs << "0x" << setw(16) << hex 569 << shared_data->intregs[y*8+x] 570 << endl;*/ 571 } 572 }
|
572 } 573 574 compared = true; 575 shared_data->flags = OWN_LEGION; 576 } 577 } // while 578 } // if not microop 579 } 580#endif 581} 582 583 584vector<bool> Trace::InstRecord::flags(NUM_BITS); 585string Trace::InstRecord::trace_system; 586 587//////////////////////////////////////////////////////////////////////// 588// 589// Parameter space for per-cycle execution address tracing options. 590// Derive from ParamContext so we can override checkParams() function. 591// 592class ExecutionTraceParamContext : public ParamContext 593{ 594 public: 595 ExecutionTraceParamContext(const string &_iniSection) 596 : ParamContext(_iniSection) 597 { 598 } 599 600 void checkParams(); // defined at bottom of file 601}; 602 603ExecutionTraceParamContext exeTraceParams("exetrace"); 604 605Param<bool> exe_trace_spec(&exeTraceParams, "speculative", 606 "capture speculative instructions", true); 607 608Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle", 609 "print cycle number", true); 610Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass", 611 "print op class", true); 612Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread", 613 "print thread number", true); 614Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr", 615 "print effective address", true); 616Param<bool> exe_trace_print_data(&exeTraceParams, "print_data", 617 "print result data", true); 618Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs", 619 "print all integer regs", false); 620Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq", 621 "print fetch sequence number", false); 622Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq", 623 "print correct-path sequence number", false); 624Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta", 625 "print which registers changed to what", false); 626Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol", 627 "Use symbols for the PC if available", true); 628Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format", 629 "print trace in intel compatible format", false); 630Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep", 631 "Compare sim state to legion state every cycle", 632 false); 633Param<string> exe_trace_system(&exeTraceParams, "trace_system", 634 "print trace of which system (client or server)", 635 "client"); 636 637 638// 639// Helper function for ExecutionTraceParamContext::checkParams() just 640// to get us into the InstRecord namespace 641// 642void 643Trace::InstRecord::setParams() 644{ 645 flags[TRACE_MISSPEC] = exe_trace_spec; 646 647 flags[PRINT_CYCLE] = exe_trace_print_cycle; 648 flags[PRINT_OP_CLASS] = exe_trace_print_opclass; 649 flags[PRINT_THREAD_NUM] = exe_trace_print_thread; 650 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr; 651 flags[PRINT_EFF_ADDR] = exe_trace_print_data; 652 flags[PRINT_INT_REGS] = exe_trace_print_iregs; 653 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq; 654 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq; 655 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta; 656 flags[PC_SYMBOL] = exe_trace_pc_symbol; 657 flags[INTEL_FORMAT] = exe_trace_intel_format; 658 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep; 659 trace_system = exe_trace_system; 660 661 // If were going to be in lockstep with Legion 662 // Setup shared memory, and get otherwise ready 663 if (flags[LEGION_LOCKSTEP]) { 664 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); 665 if (shmfd < 0) 666 fatal("Couldn't get shared memory fd. Is Legion running?"); 667 668 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); 669 if (shared_data == (SharedData*)-1) 670 fatal("Couldn't allocate shared memory"); 671 672 if (shared_data->flags != OWN_M5) 673 fatal("Shared memory has invalid owner"); 674 675 if (shared_data->version != VERSION) 676 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, 677 shared_data->version); 678 679 // step legion forward one cycle so we can get register values 680 shared_data->flags = OWN_LEGION; 681 } 682} 683 684void 685ExecutionTraceParamContext::checkParams() 686{ 687 Trace::InstRecord::setParams(); 688} 689
| 576 } 577 578 compared = true; 579 shared_data->flags = OWN_LEGION; 580 } 581 } // while 582 } // if not microop 583 } 584#endif 585} 586 587 588vector<bool> Trace::InstRecord::flags(NUM_BITS); 589string Trace::InstRecord::trace_system; 590 591//////////////////////////////////////////////////////////////////////// 592// 593// Parameter space for per-cycle execution address tracing options. 594// Derive from ParamContext so we can override checkParams() function. 595// 596class ExecutionTraceParamContext : public ParamContext 597{ 598 public: 599 ExecutionTraceParamContext(const string &_iniSection) 600 : ParamContext(_iniSection) 601 { 602 } 603 604 void checkParams(); // defined at bottom of file 605}; 606 607ExecutionTraceParamContext exeTraceParams("exetrace"); 608 609Param<bool> exe_trace_spec(&exeTraceParams, "speculative", 610 "capture speculative instructions", true); 611 612Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle", 613 "print cycle number", true); 614Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass", 615 "print op class", true); 616Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread", 617 "print thread number", true); 618Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr", 619 "print effective address", true); 620Param<bool> exe_trace_print_data(&exeTraceParams, "print_data", 621 "print result data", true); 622Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs", 623 "print all integer regs", false); 624Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq", 625 "print fetch sequence number", false); 626Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq", 627 "print correct-path sequence number", false); 628Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta", 629 "print which registers changed to what", false); 630Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol", 631 "Use symbols for the PC if available", true); 632Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format", 633 "print trace in intel compatible format", false); 634Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep", 635 "Compare sim state to legion state every cycle", 636 false); 637Param<string> exe_trace_system(&exeTraceParams, "trace_system", 638 "print trace of which system (client or server)", 639 "client"); 640 641 642// 643// Helper function for ExecutionTraceParamContext::checkParams() just 644// to get us into the InstRecord namespace 645// 646void 647Trace::InstRecord::setParams() 648{ 649 flags[TRACE_MISSPEC] = exe_trace_spec; 650 651 flags[PRINT_CYCLE] = exe_trace_print_cycle; 652 flags[PRINT_OP_CLASS] = exe_trace_print_opclass; 653 flags[PRINT_THREAD_NUM] = exe_trace_print_thread; 654 flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr; 655 flags[PRINT_EFF_ADDR] = exe_trace_print_data; 656 flags[PRINT_INT_REGS] = exe_trace_print_iregs; 657 flags[PRINT_FETCH_SEQ] = exe_trace_print_fetchseq; 658 flags[PRINT_CP_SEQ] = exe_trace_print_cp_seq; 659 flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta; 660 flags[PC_SYMBOL] = exe_trace_pc_symbol; 661 flags[INTEL_FORMAT] = exe_trace_intel_format; 662 flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep; 663 trace_system = exe_trace_system; 664 665 // If were going to be in lockstep with Legion 666 // Setup shared memory, and get otherwise ready 667 if (flags[LEGION_LOCKSTEP]) { 668 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); 669 if (shmfd < 0) 670 fatal("Couldn't get shared memory fd. Is Legion running?"); 671 672 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); 673 if (shared_data == (SharedData*)-1) 674 fatal("Couldn't allocate shared memory"); 675 676 if (shared_data->flags != OWN_M5) 677 fatal("Shared memory has invalid owner"); 678 679 if (shared_data->version != VERSION) 680 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, 681 shared_data->version); 682 683 // step legion forward one cycle so we can get register values 684 shared_data->flags = OWN_LEGION; 685 } 686} 687 688void 689ExecutionTraceParamContext::checkParams() 690{ 691 Trace::InstRecord::setParams(); 692} 693
|