exetrace.cc revision 4565
1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Steve Reinhardt 29 * Lisa Hsu 30 * Nathan Binkert 31 * Steve Raasch 32 */ 33 34#include <errno.h> 35#include <fstream> 36#include <iomanip> 37#include <sys/ipc.h> 38#include <sys/shm.h> 39 40#include "arch/predecoder.hh" 41#include "arch/regfile.hh" 42#include "arch/utility.hh" 43#include "base/loader/symtab.hh" 44#include "base/socket.hh" 45#include "config/full_system.hh" 46#include "cpu/base.hh" 47#include "cpu/exetrace.hh" 48#include "cpu/static_inst.hh" 49#include "sim/param.hh" 50#include "sim/system.hh" 51 52#if FULL_SYSTEM 53#include "arch/tlb.hh" 54#endif 55 56//XXX This is temporary 57#include "arch/isa_specific.hh" 58#include "cpu/m5legion_interface.h" 59 60using namespace std; 61using namespace TheISA; 62 63#if THE_ISA == SPARC_ISA && FULL_SYSTEM 64static int diffcount = 0; 65static bool wasMicro = false; 66#endif 67 68namespace Trace { 69SharedData *shared_data = NULL; 70ListenSocket *cosim_listener = NULL; 71 72void 73setupSharedData() 74{ 75 int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777); 76 if (shmfd < 0) 77 fatal("Couldn't get shared memory fd. Is Legion running?"); 78 79 shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); 80 if (shared_data == (SharedData*)-1) 81 fatal("Couldn't allocate shared memory"); 82 83 if (shared_data->flags != OWN_M5) 84 fatal("Shared memory has invalid owner"); 85 86 if (shared_data->version != VERSION) 87 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, 88 shared_data->version); 89 90 // step legion forward one cycle so we can get register values 91 shared_data->flags = OWN_LEGION; 92} 93 94//////////////////////////////////////////////////////////////////////// 95// 96// Methods for the InstRecord object 97// 98 99#if THE_ISA == SPARC_ISA 100 101inline char * genCenteredLabel(int length, char * buffer, char * label) 102{ 103 int labelLength = strlen(label); 104 assert(labelLength <= length); 105 int leftPad = (length - labelLength) / 2; 106 int rightPad = length - leftPad - labelLength; 107 char format[64]; 108 sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad); 109 sprintf(buffer, format, "", label, ""); 110 return buffer; 111} 112 113inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b) 114{ 115 ccprintf(os, " %16s | %#018x %s %#-018x \n", 116 title, a, (a == b) ? "|" : "X", b); 117} 118 119inline void printColumnLabels(ostream & os) 120{ 121 static char * regLabel = genCenteredLabel(16, new char[17], "Register"); 122 static char * m5Label = genCenteredLabel(18, new char[18], "M5"); 123 static char * legionLabel = genCenteredLabel(18, new char[18], "Legion"); 124 ccprintf(os, " %s | %s | %s \n", regLabel, m5Label, legionLabel); 125 ccprintf(os, "--------------------+-----------------------+-----------------------\n"); 126} 127 128inline void printSectionHeader(ostream & os, char * name) 129{ 130 char sectionString[70]; 131 genCenteredLabel(69, sectionString, name); 132 ccprintf(os, "====================================================================\n"); 133 ccprintf(os, "%69s\n", sectionString); 134 ccprintf(os, "====================================================================\n"); 135} 136 137inline void printLevelHeader(ostream & os, int level) 138{ 139 char sectionString[70]; 140 char levelName[70]; 141 sprintf(levelName, "Trap stack level %d", level); 142 genCenteredLabel(69, sectionString, levelName); 143 ccprintf(os, "====================================================================\n"); 144 ccprintf(os, "%69s\n", sectionString); 145 ccprintf(os, "====================================================================\n"); 146} 147 148#endif 149 150void 151Trace::InstRecord::dump() 152{ 153 ostream &outs = Trace::output(); 154 155 DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst); 156 bool diff = true; 157 if (IsOn(ExecRegDelta)) 158 { 159 diff = false; 160#ifndef NDEBUG 161#if THE_ISA == SPARC_ISA 162 static int fd = 0; 163 //Don't print what happens for each micro-op, just print out 164 //once at the last op, and for regular instructions. 165 if(!staticInst->isMicroop() || staticInst->isLastMicroop()) 166 { 167 if(!cosim_listener) 168 { 169 int port = 8000; 170 cosim_listener = new ListenSocket(); 171 while(!cosim_listener->listen(port, true)) 172 { 173 DPRINTF(GDBMisc, "Can't bind port %d\n", port); 174 port++; 175 } 176 ccprintf(cerr, "Listening for cosimulator on port %d\n", port); 177 fd = cosim_listener->accept(); 178 } 179 char prefix[] = "goli"; 180 for(int p = 0; p < 4; p++) 181 { 182 for(int i = 0; i < 8; i++) 183 { 184 uint64_t regVal; 185 int res = read(fd, ®Val, sizeof(regVal)); 186 if(res < 0) 187 panic("First read call failed! %s\n", strerror(errno)); 188 regVal = TheISA::gtoh(regVal); 189 uint64_t realRegVal = thread->readIntReg(p * 8 + i); 190 if((regVal & 0xffffffffULL) != (realRegVal & 0xffffffffULL)) 191 { 192 DPRINTF(ExecRegDelta, "Register %s%d should be %#x but is %#x.\n", prefix[p], i, regVal, realRegVal); 193 diff = true; 194 } 195 //ccprintf(outs, "%s%d m5 = %#x statetrace = %#x\n", prefix[p], i, realRegVal, regVal); 196 } 197 } 198 /*for(int f = 0; f <= 62; f+=2) 199 { 200 uint64_t regVal; 201 int res = read(fd, ®Val, sizeof(regVal)); 202 if(res < 0) 203 panic("First read call failed! %s\n", strerror(errno)); 204 regVal = TheISA::gtoh(regVal); 205 uint64_t realRegVal = thread->readFloatRegBits(f, 64); 206 if(regVal != realRegVal) 207 { 208 DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal); 209 } 210 }*/ 211 uint64_t regVal; 212 int res = read(fd, ®Val, sizeof(regVal)); 213 if(res < 0) 214 panic("First read call failed! %s\n", strerror(errno)); 215 regVal = TheISA::gtoh(regVal); 216 uint64_t realRegVal = thread->readNextPC(); 217 if(regVal != realRegVal) 218 { 219 DPRINTF(ExecRegDelta, "Register pc should be %#x but is %#x.\n", regVal, realRegVal); 220 diff = true; 221 } 222 res = read(fd, ®Val, sizeof(regVal)); 223 if(res < 0) 224 panic("First read call failed! %s\n", strerror(errno)); 225 regVal = TheISA::gtoh(regVal); 226 realRegVal = thread->readNextNPC(); 227 if(regVal != realRegVal) 228 { 229 DPRINTF(ExecRegDelta, "Register npc should be %#x but is %#x.\n", regVal, realRegVal); 230 diff = true; 231 } 232 res = read(fd, ®Val, sizeof(regVal)); 233 if(res < 0) 234 panic("First read call failed! %s\n", strerror(errno)); 235 regVal = TheISA::gtoh(regVal); 236 realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2); 237 if((regVal & 0xF) != (realRegVal & 0xF)) 238 { 239 DPRINTF(ExecRegDelta, "Register ccr should be %#x but is %#x.\n", regVal, realRegVal); 240 diff = true; 241 } 242 } 243#endif 244#endif 245#if 0 //THE_ISA == SPARC_ISA 246 //Don't print what happens for each micro-op, just print out 247 //once at the last op, and for regular instructions. 248 if(!staticInst->isMicroop() || staticInst->isLastMicroop()) 249 { 250 static uint64_t regs[32] = { 251 0, 0, 0, 0, 0, 0, 0, 0, 252 0, 0, 0, 0, 0, 0, 0, 0, 253 0, 0, 0, 0, 0, 0, 0, 0, 254 0, 0, 0, 0, 0, 0, 0, 0}; 255 static uint64_t ccr = 0; 256 static uint64_t y = 0; 257 static uint64_t floats[32]; 258 uint64_t newVal; 259 static const char * prefixes[4] = {"G", "O", "L", "I"}; 260 261 outs << hex; 262 outs << "PC = " << thread->readNextPC(); 263 outs << " NPC = " << thread->readNextNPC(); 264 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2); 265 //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_CCR); 266 if(newVal != ccr) 267 { 268 outs << " CCR = " << newVal; 269 ccr = newVal; 270 } 271 newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1); 272 //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_Y); 273 if(newVal != y) 274 { 275 outs << " Y = " << newVal; 276 y = newVal; 277 } 278 for(int y = 0; y < 4; y++) 279 { 280 for(int x = 0; x < 8; x++) 281 { 282 int index = x + 8 * y; 283 newVal = thread->readIntReg(index); 284 if(regs[index] != newVal) 285 { 286 outs << " " << prefixes[y] << dec << x << " = " << hex << newVal; 287 regs[index] = newVal; 288 } 289 } 290 } 291 for(int y = 0; y < 32; y++) 292 { 293 newVal = thread->readFloatRegBits(2 * y, 64); 294 if(floats[y] != newVal) 295 { 296 outs << " F" << dec << (2 * y) << " = " << hex << newVal; 297 floats[y] = newVal; 298 } 299 } 300 outs << dec << endl; 301 } 302#endif 303 } 304 if(!diff) { 305 } else if (IsOn(ExecIntel)) { 306 ccprintf(outs, "%7d ) ", when); 307 outs << "0x" << hex << PC << ":\t"; 308 if (staticInst->isLoad()) { 309 ccprintf(outs, "<RD %#x>", addr); 310 } else if (staticInst->isStore()) { 311 ccprintf(outs, "<WR %#x>", addr); 312 } 313 outs << endl; 314 } else { 315 if (IsOn(ExecTicks)) 316 ccprintf(outs, "%7d: ", when); 317 318 outs << thread->getCpuPtr()->name() << " "; 319 320 if (IsOn(ExecSpeculative)) 321 outs << (misspeculating ? "-" : "+") << " "; 322 323 if (IsOn(ExecThread)) 324 outs << "T" << thread->getThreadNum() << " : "; 325 326 327 std::string sym_str; 328 Addr sym_addr; 329 if (debugSymbolTable 330 && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr) 331 && IsOn(ExecSymbol)) { 332 if (PC != sym_addr) 333 sym_str += csprintf("+%d", PC - sym_addr); 334 outs << "@" << sym_str << " : "; 335 } 336 else { 337 outs << "0x" << hex << PC << " : "; 338 } 339 340 // 341 // Print decoded instruction 342 // 343 344#if defined(__GNUC__) && (__GNUC__ < 3) 345 // There's a bug in gcc 2.x library that prevents setw() 346 // from working properly on strings 347 string mc(staticInst->disassemble(PC, debugSymbolTable)); 348 while (mc.length() < 26) 349 mc += " "; 350 outs << mc; 351#else 352 outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable); 353#endif 354 355 outs << " : "; 356 357 if (IsOn(ExecOpClass)) { 358 outs << opClassStrings[staticInst->opClass()] << " : "; 359 } 360 361 if (IsOn(ExecResult) && data_status != DataInvalid) { 362 outs << " D="; 363#if 0 364 if (data_status == DataDouble) 365 ccprintf(outs, "%f", data.as_double); 366 else 367 ccprintf(outs, "%#018x", data.as_int); 368#else 369 ccprintf(outs, "%#018x", data.as_int); 370#endif 371 } 372 373 if (IsOn(ExecEffAddr) && addr_valid) 374 outs << " A=0x" << hex << addr; 375 376 if (IsOn(ExecIntRegs) && regs_valid) { 377 for (int i = 0; i < TheISA::NumIntRegs;) 378 for (int j = i + 1; i <= j; i++) 379 ccprintf(outs, "r%02d = %#018x%s", i, 380 iregs->regs.readReg(i), 381 ((i == j) ? "\n" : " ")); 382 outs << "\n"; 383 } 384 385 if (IsOn(ExecFetchSeq) && fetch_seq_valid) 386 outs << " FetchSeq=" << dec << fetch_seq; 387 388 if (IsOn(ExecCPSeq) && cp_seq_valid) 389 outs << " CPSeq=" << dec << cp_seq; 390 391 // 392 // End of line... 393 // 394 outs << endl; 395 } 396#if THE_ISA == SPARC_ISA && FULL_SYSTEM 397 static TheISA::Predecoder predecoder(NULL); 398 // Compare 399 if (IsOn(ExecLegion)) 400 { 401 bool compared = false; 402 bool diffPC = false; 403 bool diffCC = false; 404 bool diffInst = false; 405 bool diffIntRegs = false; 406 bool diffFpRegs = false; 407 bool diffTpc = false; 408 bool diffTnpc = false; 409 bool diffTstate = false; 410 bool diffTt = false; 411 bool diffTba = false; 412 bool diffHpstate = false; 413 bool diffHtstate = false; 414 bool diffHtba = false; 415 bool diffPstate = false; 416 bool diffY = false; 417 bool diffFsr = false; 418 bool diffCcr = false; 419 bool diffTl = false; 420 bool diffGl = false; 421 bool diffAsi = false; 422 bool diffPil = false; 423 bool diffCwp = false; 424 bool diffCansave = false; 425 bool diffCanrestore = false; 426 bool diffOtherwin = false; 427 bool diffCleanwin = false; 428 bool diffTlb = false; 429 Addr m5Pc, lgnPc; 430 431 if (!shared_data) 432 setupSharedData(); 433 434 // We took a trap on a micro-op... 435 if (wasMicro && !staticInst->isMicroop()) 436 { 437 // let's skip comparing this tick 438 while (!compared) 439 if (shared_data->flags == OWN_M5) { 440 shared_data->flags = OWN_LEGION; 441 compared = true; 442 } 443 compared = false; 444 wasMicro = false; 445 } 446 447 if (staticInst->isLastMicroop()) 448 wasMicro = false; 449 else if (staticInst->isMicroop()) 450 wasMicro = true; 451 452 453 if(!staticInst->isMicroop() || staticInst->isLastMicroop()) { 454 while (!compared) { 455 if (shared_data->flags == OWN_M5) { 456 m5Pc = PC & TheISA::PAddrImplMask; 457 if (bits(shared_data->pstate,3,3)) { 458 m5Pc &= mask(32); 459 } 460 lgnPc = shared_data->pc & TheISA::PAddrImplMask; 461 if (lgnPc != m5Pc) 462 diffPC = true; 463 464 if (shared_data->cycle_count != 465 thread->getCpuPtr()->instCount()) 466 diffCC = true; 467 468 if (shared_data->instruction != 469 (SparcISA::MachInst)staticInst->machInst) { 470 diffInst = true; 471 } 472 // assume we have %g0 working correctly 473 for (int i = 1; i < TheISA::NumIntArchRegs; i++) { 474 if (thread->readIntReg(i) != shared_data->intregs[i]) { 475 diffIntRegs = true; 476 } 477 } 478 for (int i = 0; i < TheISA::NumFloatRegs/2; i++) { 479 if (thread->readFloatRegBits(i*2,FloatRegFile::DoubleWidth) != shared_data->fpregs[i]) { 480 diffFpRegs = true; 481 } 482 } 483 uint64_t oldTl = thread->readMiscRegNoEffect(MISCREG_TL); 484 if (oldTl != shared_data->tl) 485 diffTl = true; 486 for (int i = 1; i <= MaxTL; i++) { 487 thread->setMiscRegNoEffect(MISCREG_TL, i); 488 if (thread->readMiscRegNoEffect(MISCREG_TPC) != 489 shared_data->tpc[i-1]) 490 diffTpc = true; 491 if (thread->readMiscRegNoEffect(MISCREG_TNPC) != 492 shared_data->tnpc[i-1]) 493 diffTnpc = true; 494 if (thread->readMiscRegNoEffect(MISCREG_TSTATE) != 495 shared_data->tstate[i-1]) 496 diffTstate = true; 497 if (thread->readMiscRegNoEffect(MISCREG_TT) != 498 shared_data->tt[i-1]) 499 diffTt = true; 500 if (thread->readMiscRegNoEffect(MISCREG_HTSTATE) != 501 shared_data->htstate[i-1]) 502 diffHtstate = true; 503 } 504 thread->setMiscRegNoEffect(MISCREG_TL, oldTl); 505 506 if(shared_data->tba != thread->readMiscRegNoEffect(MISCREG_TBA)) 507 diffTba = true; 508 //When the hpstate register is read by an instruction, 509 //legion has bit 11 set. When it's in storage, it doesn't. 510 //Since we don't directly support seperate interpretations 511 //of the registers like that, the bit is always set to 1 and 512 //we just don't compare it. It's not supposed to matter 513 //anyway. 514 if((shared_data->hpstate | (1 << 11)) != thread->readMiscRegNoEffect(MISCREG_HPSTATE)) 515 diffHpstate = true; 516 if(shared_data->htba != thread->readMiscRegNoEffect(MISCREG_HTBA)) 517 diffHtba = true; 518 if(shared_data->pstate != thread->readMiscRegNoEffect(MISCREG_PSTATE)) 519 diffPstate = true; 520 //if(shared_data->y != thread->readMiscRegNoEffect(MISCREG_Y)) 521 if(shared_data->y != 522 thread->readIntReg(NumIntArchRegs + 1)) 523 diffY = true; 524 if(shared_data->fsr != thread->readMiscRegNoEffect(MISCREG_FSR)) { 525 diffFsr = true; 526 if (mbits(shared_data->fsr, 63,10) == 527 mbits(thread->readMiscRegNoEffect(MISCREG_FSR), 63,10)) { 528 thread->setMiscRegNoEffect(MISCREG_FSR, shared_data->fsr); 529 diffFsr = false; 530 } 531 } 532 //if(shared_data->ccr != thread->readMiscRegNoEffect(MISCREG_CCR)) 533 if(shared_data->ccr != 534 thread->readIntReg(NumIntArchRegs + 2)) 535 diffCcr = true; 536 if(shared_data->gl != thread->readMiscRegNoEffect(MISCREG_GL)) 537 diffGl = true; 538 if(shared_data->asi != thread->readMiscRegNoEffect(MISCREG_ASI)) 539 diffAsi = true; 540 if(shared_data->pil != thread->readMiscRegNoEffect(MISCREG_PIL)) 541 diffPil = true; 542 if(shared_data->cwp != thread->readMiscRegNoEffect(MISCREG_CWP)) 543 diffCwp = true; 544 //if(shared_data->cansave != thread->readMiscRegNoEffect(MISCREG_CANSAVE)) 545 if(shared_data->cansave != 546 thread->readIntReg(NumIntArchRegs + 3)) 547 diffCansave = true; 548 //if(shared_data->canrestore != 549 // thread->readMiscRegNoEffect(MISCREG_CANRESTORE)) 550 if(shared_data->canrestore != 551 thread->readIntReg(NumIntArchRegs + 4)) 552 diffCanrestore = true; 553 //if(shared_data->otherwin != thread->readMiscRegNoEffect(MISCREG_OTHERWIN)) 554 if(shared_data->otherwin != 555 thread->readIntReg(NumIntArchRegs + 6)) 556 diffOtherwin = true; 557 //if(shared_data->cleanwin != thread->readMiscRegNoEffect(MISCREG_CLEANWIN)) 558 if(shared_data->cleanwin != 559 thread->readIntReg(NumIntArchRegs + 5)) 560 diffCleanwin = true; 561 562 for (int i = 0; i < 64; i++) { 563 if (shared_data->itb[i] != thread->getITBPtr()->TteRead(i)) 564 diffTlb = true; 565 if (shared_data->dtb[i] != thread->getDTBPtr()->TteRead(i)) 566 diffTlb = true; 567 } 568 569 if (diffPC || diffCC || diffInst || diffIntRegs || 570 diffFpRegs || diffTpc || diffTnpc || diffTstate || 571 diffTt || diffHpstate || diffHtstate || diffHtba || 572 diffPstate || diffY || diffCcr || diffTl || diffFsr || 573 diffGl || diffAsi || diffPil || diffCwp || diffCansave || 574 diffCanrestore || diffOtherwin || diffCleanwin || diffTlb) 575 { 576 577 outs << "Differences found between M5 and Legion:"; 578 if (diffPC) 579 outs << " [PC]"; 580 if (diffCC) 581 outs << " [CC]"; 582 if (diffInst) 583 outs << " [Instruction]"; 584 if (diffIntRegs) 585 outs << " [IntRegs]"; 586 if (diffFpRegs) 587 outs << " [FpRegs]"; 588 if (diffTpc) 589 outs << " [Tpc]"; 590 if (diffTnpc) 591 outs << " [Tnpc]"; 592 if (diffTstate) 593 outs << " [Tstate]"; 594 if (diffTt) 595 outs << " [Tt]"; 596 if (diffHpstate) 597 outs << " [Hpstate]"; 598 if (diffHtstate) 599 outs << " [Htstate]"; 600 if (diffHtba) 601 outs << " [Htba]"; 602 if (diffPstate) 603 outs << " [Pstate]"; 604 if (diffY) 605 outs << " [Y]"; 606 if (diffFsr) 607 outs << " [FSR]"; 608 if (diffCcr) 609 outs << " [Ccr]"; 610 if (diffTl) 611 outs << " [Tl]"; 612 if (diffGl) 613 outs << " [Gl]"; 614 if (diffAsi) 615 outs << " [Asi]"; 616 if (diffPil) 617 outs << " [Pil]"; 618 if (diffCwp) 619 outs << " [Cwp]"; 620 if (diffCansave) 621 outs << " [Cansave]"; 622 if (diffCanrestore) 623 outs << " [Canrestore]"; 624 if (diffOtherwin) 625 outs << " [Otherwin]"; 626 if (diffCleanwin) 627 outs << " [Cleanwin]"; 628 if (diffTlb) 629 outs << " [Tlb]"; 630 outs << endl << endl; 631 632 outs << right << setfill(' ') << setw(15) 633 << "M5 PC: " << "0x"<< setw(16) << setfill('0') 634 << hex << m5Pc << endl; 635 outs << setfill(' ') << setw(15) 636 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex 637 << lgnPc << endl << endl; 638 639 outs << right << setfill(' ') << setw(15) 640 << "M5 CC: " << "0x"<< setw(16) << setfill('0') 641 << hex << thread->getCpuPtr()->instCount() << endl; 642 outs << setfill(' ') << setw(15) 643 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex 644 << shared_data->cycle_count << endl << endl; 645 646 outs << setfill(' ') << setw(15) 647 << "M5 Inst: " << "0x"<< setw(8) 648 << setfill('0') << hex << staticInst->machInst 649 << staticInst->disassemble(m5Pc, debugSymbolTable) 650 << endl; 651 652 predecoder.setTC(thread); 653 predecoder.moreBytes(m5Pc, m5Pc, 0, 654 shared_data->instruction); 655 656 assert(predecoder.extMachInstReady()); 657 658 StaticInstPtr legionInst = 659 StaticInst::decode(predecoder.getExtMachInst()); 660 outs << setfill(' ') << setw(15) 661 << " Legion Inst: " 662 << "0x" << setw(8) << setfill('0') << hex 663 << shared_data->instruction 664 << legionInst->disassemble(lgnPc, debugSymbolTable) 665 << endl << endl; 666 667 printSectionHeader(outs, "General State"); 668 printColumnLabels(outs); 669 printRegPair(outs, "HPstate", 670 thread->readMiscRegNoEffect(MISCREG_HPSTATE), 671 shared_data->hpstate | (1 << 11)); 672 printRegPair(outs, "Htba", 673 thread->readMiscRegNoEffect(MISCREG_HTBA), 674 shared_data->htba); 675 printRegPair(outs, "Pstate", 676 thread->readMiscRegNoEffect(MISCREG_PSTATE), 677 shared_data->pstate); 678 printRegPair(outs, "Y", 679 //thread->readMiscRegNoEffect(MISCREG_Y), 680 thread->readIntReg(NumIntArchRegs + 1), 681 shared_data->y); 682 printRegPair(outs, "FSR", 683 thread->readMiscRegNoEffect(MISCREG_FSR), 684 shared_data->fsr); 685 printRegPair(outs, "Ccr", 686 //thread->readMiscRegNoEffect(MISCREG_CCR), 687 thread->readIntReg(NumIntArchRegs + 2), 688 shared_data->ccr); 689 printRegPair(outs, "Tl", 690 thread->readMiscRegNoEffect(MISCREG_TL), 691 shared_data->tl); 692 printRegPair(outs, "Gl", 693 thread->readMiscRegNoEffect(MISCREG_GL), 694 shared_data->gl); 695 printRegPair(outs, "Asi", 696 thread->readMiscRegNoEffect(MISCREG_ASI), 697 shared_data->asi); 698 printRegPair(outs, "Pil", 699 thread->readMiscRegNoEffect(MISCREG_PIL), 700 shared_data->pil); 701 printRegPair(outs, "Cwp", 702 thread->readMiscRegNoEffect(MISCREG_CWP), 703 shared_data->cwp); 704 printRegPair(outs, "Cansave", 705 //thread->readMiscRegNoEffect(MISCREG_CANSAVE), 706 thread->readIntReg(NumIntArchRegs + 3), 707 shared_data->cansave); 708 printRegPair(outs, "Canrestore", 709 //thread->readMiscRegNoEffect(MISCREG_CANRESTORE), 710 thread->readIntReg(NumIntArchRegs + 4), 711 shared_data->canrestore); 712 printRegPair(outs, "Otherwin", 713 //thread->readMiscRegNoEffect(MISCREG_OTHERWIN), 714 thread->readIntReg(NumIntArchRegs + 6), 715 shared_data->otherwin); 716 printRegPair(outs, "Cleanwin", 717 //thread->readMiscRegNoEffect(MISCREG_CLEANWIN), 718 thread->readIntReg(NumIntArchRegs + 5), 719 shared_data->cleanwin); 720 outs << endl; 721 for (int i = 1; i <= MaxTL; i++) { 722 printLevelHeader(outs, i); 723 printColumnLabels(outs); 724 thread->setMiscRegNoEffect(MISCREG_TL, i); 725 printRegPair(outs, "Tpc", 726 thread->readMiscRegNoEffect(MISCREG_TPC), 727 shared_data->tpc[i-1]); 728 printRegPair(outs, "Tnpc", 729 thread->readMiscRegNoEffect(MISCREG_TNPC), 730 shared_data->tnpc[i-1]); 731 printRegPair(outs, "Tstate", 732 thread->readMiscRegNoEffect(MISCREG_TSTATE), 733 shared_data->tstate[i-1]); 734 printRegPair(outs, "Tt", 735 thread->readMiscRegNoEffect(MISCREG_TT), 736 shared_data->tt[i-1]); 737 printRegPair(outs, "Htstate", 738 thread->readMiscRegNoEffect(MISCREG_HTSTATE), 739 shared_data->htstate[i-1]); 740 } 741 thread->setMiscRegNoEffect(MISCREG_TL, oldTl); 742 outs << endl; 743 744 printSectionHeader(outs, "General Purpose Registers"); 745 static const char * regtypes[4] = {"%g", "%o", "%l", "%i"}; 746 for(int y = 0; y < 4; y++) { 747 for(int x = 0; x < 8; x++) { 748 char label[8]; 749 sprintf(label, "%s%d", regtypes[y], x); 750 printRegPair(outs, label, 751 thread->readIntReg(y*8+x), 752 shared_data->intregs[y*8+x]); 753 } 754 } 755 if (diffFpRegs) { 756 for (int x = 0; x < 32; x++) { 757 char label[8]; 758 sprintf(label, "%%f%d", x); 759 printRegPair(outs, label, 760 thread->readFloatRegBits(x*2,FloatRegFile::DoubleWidth), 761 shared_data->fpregs[x]); 762 } 763 } 764 if (diffTlb) { 765 printColumnLabels(outs); 766 char label[8]; 767 for (int x = 0; x < 64; x++) { 768 if (shared_data->itb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 769 thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 770 sprintf(label, "I-TLB:%02d", x); 771 printRegPair(outs, label, thread->getITBPtr()->TteRead(x), 772 shared_data->itb[x]); 773 } 774 } 775 for (int x = 0; x < 64; x++) { 776 if (shared_data->dtb[x] != ULL(0xFFFFFFFFFFFFFFFF) || 777 thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF)) { 778 sprintf(label, "D-TLB:%02d", x); 779 printRegPair(outs, label, thread->getDTBPtr()->TteRead(x), 780 shared_data->dtb[x]); 781 } 782 } 783 thread->getITBPtr()->dumpAll(); 784 thread->getDTBPtr()->dumpAll(); 785 } 786 787 diffcount++; 788 if (diffcount > 3) 789 fatal("Differences found between Legion and M5\n"); 790 } else 791 diffcount = 0; 792 793 compared = true; 794 shared_data->flags = OWN_LEGION; 795 } 796 } // while 797 } // if not microop 798 } 799#endif 800} 801 802/* namespace Trace */ } 803