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