2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
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.
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.
28 * Authors: Steve Reinhardt
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"
50 #include "arch/tlb.hh"
53 //XXX This is temporary
54 #include "arch/isa_specific.hh"
55 #include "cpu/m5legion_interface.h"
58 using namespace TheISA
;
60 #if THE_ISA == SPARC_ISA && FULL_SYSTEM
61 static int diffcount
= 0;
62 static bool wasMicro
= false;
66 SharedData
*shared_data
= NULL
;
69 ////////////////////////////////////////////////////////////////////////
71 // Methods for the InstRecord object
74 #if THE_ISA == SPARC_ISA
76 inline char * genCenteredLabel(int length
, char * buffer
, char * label
)
78 int labelLength
= strlen(label
);
79 assert(labelLength
<= length
);
80 int leftPad
= (length
- labelLength
) / 2;
81 int rightPad
= length
- leftPad
- labelLength
;
83 sprintf(format
, "%%%ds%%s%%%ds", leftPad
, rightPad
);
84 sprintf(buffer
, format
, "", label
, "");
88 inline void printRegPair(ostream
& os
, char const * title
, uint64_t a
, uint64_t b
)
90 ccprintf(os
, " %16s | %#018x %s %#-018x \n",
91 title
, a
, (a
== b
) ? "|" : "X", b
);
94 inline void printColumnLabels(ostream
& os
)
96 static char * regLabel
= genCenteredLabel(16, new char[17], "Register");
97 static char * m5Label
= genCenteredLabel(18, new char[18], "M5");
98 static char * legionLabel
= genCenteredLabel(18, new char[18], "Legion");
99 ccprintf(os
, " %s | %s | %s \n", regLabel
, m5Label
, legionLabel
);
100 ccprintf(os
, "--------------------+-----------------------+-----------------------\n");
103 inline void printSectionHeader(ostream
& os
, char * name
)
105 char sectionString
[70];
106 genCenteredLabel(69, sectionString
, name
);
107 ccprintf(os
, "====================================================================\n");
108 ccprintf(os
, "%69s\n", sectionString
);
109 ccprintf(os
, "====================================================================\n");
112 inline void printLevelHeader(ostream
& os
, int level
)
114 char sectionString
[70];
116 sprintf(levelName
, "Trap stack level %d", level
);
117 genCenteredLabel(69, sectionString
, levelName
);
118 ccprintf(os
, "====================================================================\n");
119 ccprintf(os
, "%69s\n", sectionString
);
120 ccprintf(os
, "====================================================================\n");
126 Trace::InstRecord::dump(ostream
&outs
)
128 DPRINTF(Sparc
, "Instruction: %#X\n", staticInst
->machInst
);
129 if (flags
[PRINT_REG_DELTA
])
131 #if THE_ISA == SPARC_ISA
132 //Don't print what happens for each micro-op, just print out
133 //once at the last op, and for regular instructions.
134 if(!staticInst
->isMicroOp() || staticInst
->isLastMicroOp())
136 static uint64_t regs
[32] = {
137 0, 0, 0, 0, 0, 0, 0, 0,
138 0, 0, 0, 0, 0, 0, 0, 0,
139 0, 0, 0, 0, 0, 0, 0, 0,
140 0, 0, 0, 0, 0, 0, 0, 0};
141 static uint64_t ccr
= 0;
142 static uint64_t y
= 0;
143 static uint64_t floats
[32];
145 static const char * prefixes
[4] = {"G", "O", "L", "I"};
148 outs
<< "PC = " << thread
->readNextPC();
149 outs
<< " NPC = " << thread
->readNextNPC();
150 newVal
= thread
->readIntReg(SparcISA::NumIntArchRegs
+ 2);
151 //newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
154 outs
<< " CCR = " << newVal
;
157 newVal
= thread
->readIntReg(SparcISA::NumIntArchRegs
+ 1);
158 //newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
161 outs
<< " Y = " << newVal
;
164 for(int y
= 0; y
< 4; y
++)
166 for(int x
= 0; x
< 8; x
++)
168 int index
= x
+ 8 * y
;
169 newVal
= thread
->readIntReg(index
);
170 if(regs
[index
] != newVal
)
172 outs
<< " " << prefixes
[y
] << dec
<< x
<< " = " << hex
<< newVal
;
173 regs
[index
] = newVal
;
177 for(int y
= 0; y
< 32; y
++)
179 newVal
= thread
->readFloatRegBits(2 * y
, 64);
180 if(floats
[y
] != newVal
)
182 outs
<< " F" << dec
<< (2 * y
) << " = " << hex
<< newVal
;
190 else if (flags
[INTEL_FORMAT
]) {
192 bool is_trace_system
= (thread
->getCpuPtr()->system
->name() == trace_system
);
194 bool is_trace_system
= true;
196 if (is_trace_system
) {
197 ccprintf(outs
, "%7d ) ", cycle
);
198 outs
<< "0x" << hex
<< PC
<< ":\t";
199 if (staticInst
->isLoad()) {
200 outs
<< "<RD 0x" << hex
<< addr
;
202 } else if (staticInst
->isStore()) {
203 outs
<< "<WR 0x" << hex
<< addr
;
209 if (flags
[PRINT_CYCLE
])
210 ccprintf(outs
, "%7d: ", cycle
);
212 outs
<< thread
->getCpuPtr()->name() << " ";
214 if (flags
[TRACE_MISSPEC
])
215 outs
<< (misspeculating
? "-" : "+") << " ";
217 if (flags
[PRINT_THREAD_NUM
])
218 outs
<< "T" << thread
->getThreadNum() << " : ";
224 && debugSymbolTable
->findNearestSymbol(PC
, sym_str
, sym_addr
)
225 && flags
[PC_SYMBOL
]) {
227 sym_str
+= csprintf("+%d", PC
- sym_addr
);
228 outs
<< "@" << sym_str
<< " : ";
231 outs
<< "0x" << hex
<< PC
<< " : ";
235 // Print decoded instruction
238 #if defined(__GNUC__) && (__GNUC__ < 3)
239 // There's a bug in gcc 2.x library that prevents setw()
240 // from working properly on strings
241 string
mc(staticInst
->disassemble(PC
, debugSymbolTable
));
242 while (mc
.length() < 26)
246 outs
<< setw(26) << left
<< staticInst
->disassemble(PC
, debugSymbolTable
);
251 if (flags
[PRINT_OP_CLASS
]) {
252 outs
<< opClassStrings
[staticInst
->opClass()] << " : ";
255 if (flags
[PRINT_RESULT_DATA
] && data_status
!= DataInvalid
) {
258 if (data_status
== DataDouble
)
259 ccprintf(outs
, "%f", data
.as_double
);
261 ccprintf(outs
, "%#018x", data
.as_int
);
263 ccprintf(outs
, "%#018x", data
.as_int
);
267 if (flags
[PRINT_EFF_ADDR
] && addr_valid
)
268 outs
<< " A=0x" << hex
<< addr
;
270 if (flags
[PRINT_INT_REGS
] && regs_valid
) {
271 for (int i
= 0; i
< TheISA::NumIntRegs
;)
272 for (int j
= i
+ 1; i
<= j
; i
++)
273 ccprintf(outs
, "r%02d = %#018x%s", i
,
274 iregs
->regs
.readReg(i
),
275 ((i
== j
) ? "\n" : " "));
279 if (flags
[PRINT_FETCH_SEQ
] && fetch_seq_valid
)
280 outs
<< " FetchSeq=" << dec
<< fetch_seq
;
282 if (flags
[PRINT_CP_SEQ
] && cp_seq_valid
)
283 outs
<< " CPSeq=" << dec
<< cp_seq
;
290 #if THE_ISA == SPARC_ISA && FULL_SYSTEM
292 if (flags
[LEGION_LOCKSTEP
])
294 bool compared
= false;
297 bool diffInst
= false;
298 bool diffIntRegs
= false;
299 bool diffFpRegs
= false;
300 bool diffTpc
= false;
301 bool diffTnpc
= false;
302 bool diffTstate
= false;
304 bool diffTba
= false;
305 bool diffHpstate
= false;
306 bool diffHtstate
= false;
307 bool diffHtba
= false;
308 bool diffPstate
= false;
310 bool diffCcr
= false;
313 bool diffAsi
= false;
314 bool diffPil
= false;
315 bool diffCwp
= false;
316 bool diffCansave
= false;
317 bool diffCanrestore
= false;
318 bool diffOtherwin
= false;
319 bool diffCleanwin
= false;
320 bool diffTlb
= false;
323 // We took a trap on a micro-op...
324 if (wasMicro
&& !staticInst
->isMicroOp())
326 // let's skip comparing this cycle
328 if (shared_data
->flags
== OWN_M5
) {
329 shared_data
->flags
= OWN_LEGION
;
336 if (staticInst
->isLastMicroOp())
338 else if (staticInst
->isMicroOp())
342 if(!staticInst
->isMicroOp() || staticInst
->isLastMicroOp()) {
344 if (shared_data
->flags
== OWN_M5
) {
345 m5Pc
= PC
& TheISA::PAddrImplMask
;
346 if (bits(shared_data
->pstate
,3,3)) {
349 lgnPc
= shared_data
->pc
& TheISA::PAddrImplMask
;
353 if (shared_data
->cycle_count
!=
354 thread
->getCpuPtr()->instCount())
357 if (shared_data
->instruction
!=
358 (SparcISA::MachInst
)staticInst
->machInst
) {
361 for (int i
= 0; i
< TheISA::NumIntArchRegs
; i
++) {
362 if (thread
->readIntReg(i
) != shared_data
->intregs
[i
]) {
366 for (int i
= 0; i
< TheISA::NumFloatRegs
/2; i
++) {
367 if (thread
->readFloatRegBits(i
,FloatRegFile::DoubleWidth
) != shared_data
->fpregs
[i
]) {
371 uint64_t oldTl
= thread
->readMiscReg(MISCREG_TL
);
372 if (oldTl
!= shared_data
->tl
)
374 for (int i
= 1; i
<= MaxTL
; i
++) {
375 thread
->setMiscReg(MISCREG_TL
, i
);
376 if (thread
->readMiscReg(MISCREG_TPC
) !=
377 shared_data
->tpc
[i
-1])
379 if (thread
->readMiscReg(MISCREG_TNPC
) !=
380 shared_data
->tnpc
[i
-1])
382 if (thread
->readMiscReg(MISCREG_TSTATE
) !=
383 shared_data
->tstate
[i
-1])
385 if (thread
->readMiscReg(MISCREG_TT
) !=
386 shared_data
->tt
[i
-1])
388 if (thread
->readMiscReg(MISCREG_HTSTATE
) !=
389 shared_data
->htstate
[i
-1])
392 thread
->setMiscReg(MISCREG_TL
, oldTl
);
394 if(shared_data
->tba
!= thread
->readMiscReg(MISCREG_TBA
))
396 //When the hpstate register is read by an instruction,
397 //legion has bit 11 set. When it's in storage, it doesn't.
398 //Since we don't directly support seperate interpretations
399 //of the registers like that, the bit is always set to 1 and
400 //we just don't compare it. It's not supposed to matter
402 if((shared_data
->hpstate
| (1 << 11)) != thread
->readMiscReg(MISCREG_HPSTATE
))
404 if(shared_data
->htba
!= thread
->readMiscReg(MISCREG_HTBA
))
406 if(shared_data
->pstate
!= thread
->readMiscReg(MISCREG_PSTATE
))
408 //if(shared_data->y != thread->readMiscReg(MISCREG_Y))
410 thread
->readIntReg(NumIntArchRegs
+ 1))
412 //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
413 if(shared_data
->ccr
!=
414 thread
->readIntReg(NumIntArchRegs
+ 2))
416 if(shared_data
->gl
!= thread
->readMiscReg(MISCREG_GL
))
418 if(shared_data
->asi
!= thread
->readMiscReg(MISCREG_ASI
))
420 if(shared_data
->pil
!= thread
->readMiscReg(MISCREG_PIL
))
422 if(shared_data
->cwp
!= thread
->readMiscReg(MISCREG_CWP
))
424 //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
425 if(shared_data
->cansave
!=
426 thread
->readIntReg(NumIntArchRegs
+ 3))
428 //if(shared_data->canrestore !=
429 // thread->readMiscReg(MISCREG_CANRESTORE))
430 if(shared_data
->canrestore
!=
431 thread
->readMiscReg(NumIntArchRegs
+ 4))
432 diffCanrestore
= true;
433 //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
434 if(shared_data
->otherwin
!=
435 thread
->readIntReg(NumIntArchRegs
+ 5))
437 //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
438 if(shared_data
->cleanwin
!=
439 thread
->readMiscReg(NumIntArchRegs
+ 6))
442 for (int i
= 0; i
< 64; i
++) {
443 if (shared_data
->itb
[i
] != thread
->getITBPtr()->TteRead(i
))
445 if (shared_data
->dtb
[i
] != thread
->getDTBPtr()->TteRead(i
))
449 if ((diffPC
|| diffCC
|| diffInst
|| diffIntRegs
||
450 diffFpRegs
|| diffTpc
|| diffTnpc
|| diffTstate
||
451 diffTt
|| diffHpstate
|| diffHtstate
|| diffHtba
||
452 diffPstate
|| diffY
|| diffCcr
|| diffTl
|| diffGl
||
453 diffAsi
|| diffPil
|| diffCwp
|| diffCansave
||
454 diffCanrestore
|| diffOtherwin
|| diffCleanwin
|| diffTlb
)
455 && !((staticInst
->machInst
& 0xC1F80000) == 0x81D00000)
456 && !(((staticInst
->machInst
& 0xC0000000) == 0xC0000000)
457 && shared_data
->tl
== thread
->readMiscReg(MISCREG_TL
) + 1)
460 outs
<< "Differences found between M5 and Legion:";
466 outs
<< " [Instruction]";
468 outs
<< " [IntRegs]";
480 outs
<< " [Hpstate]";
482 outs
<< " [Htstate]";
502 outs
<< " [Cansave]";
504 outs
<< " [Canrestore]";
506 outs
<< " [Otherwin]";
508 outs
<< " [Cleanwin]";
511 outs
<< endl
<< endl
;
513 outs
<< right
<< setfill(' ') << setw(15)
514 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
515 << hex
<< m5Pc
<< endl
;
516 outs
<< setfill(' ') << setw(15)
517 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
518 << lgnPc
<< endl
<< endl
;
520 outs
<< right
<< setfill(' ') << setw(15)
521 << "M5 CC: " << "0x"<< setw(16) << setfill('0')
522 << hex
<< thread
->getCpuPtr()->instCount() << endl
;
523 outs
<< setfill(' ') << setw(15)
524 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
525 << shared_data
->cycle_count
<< endl
<< endl
;
527 outs
<< setfill(' ') << setw(15)
528 << "M5 Inst: " << "0x"<< setw(8)
529 << setfill('0') << hex
<< staticInst
->machInst
530 << staticInst
->disassemble(m5Pc
, debugSymbolTable
)
533 StaticInstPtr legionInst
=
534 StaticInst::decode(makeExtMI(shared_data
->instruction
,
536 outs
<< setfill(' ') << setw(15)
538 << "0x" << setw(8) << setfill('0') << hex
539 << shared_data
->instruction
540 << legionInst
->disassemble(lgnPc
, debugSymbolTable
)
543 printSectionHeader(outs
, "General State");
544 printColumnLabels(outs
);
545 printRegPair(outs
, "HPstate",
546 thread
->readMiscReg(MISCREG_HPSTATE
),
547 shared_data
->hpstate
| (1 << 11));
548 printRegPair(outs
, "Htba",
549 thread
->readMiscReg(MISCREG_HTBA
),
551 printRegPair(outs
, "Pstate",
552 thread
->readMiscReg(MISCREG_PSTATE
),
553 shared_data
->pstate
);
554 printRegPair(outs
, "Y",
555 //thread->readMiscReg(MISCREG_Y),
556 thread
->readMiscReg(NumIntArchRegs
+ 1),
558 printRegPair(outs
, "Ccr",
559 //thread->readMiscReg(MISCREG_CCR),
560 thread
->readMiscReg(NumIntArchRegs
+ 2),
562 printRegPair(outs
, "Tl",
563 thread
->readMiscReg(MISCREG_TL
),
565 printRegPair(outs
, "Gl",
566 thread
->readMiscReg(MISCREG_GL
),
568 printRegPair(outs
, "Asi",
569 thread
->readMiscReg(MISCREG_ASI
),
571 printRegPair(outs
, "Pil",
572 thread
->readMiscReg(MISCREG_PIL
),
574 printRegPair(outs
, "Cwp",
575 thread
->readMiscReg(MISCREG_CWP
),
577 printRegPair(outs
, "Cansave",
578 //thread->readMiscReg(MISCREG_CANSAVE),
579 thread
->readIntReg(NumIntArchRegs
+ 3),
580 shared_data
->cansave
);
581 printRegPair(outs
, "Canrestore",
582 //thread->readMiscReg(MISCREG_CANRESTORE),
583 thread
->readIntReg(NumIntArchRegs
+ 4),
584 shared_data
->canrestore
);
585 printRegPair(outs
, "Otherwin",
586 //thread->readMiscReg(MISCREG_OTHERWIN),
587 thread
->readIntReg(NumIntArchRegs
+ 5),
588 shared_data
->otherwin
);
589 printRegPair(outs
, "Cleanwin",
590 //thread->readMiscReg(MISCREG_CLEANWIN),
591 thread
->readIntReg(NumIntArchRegs
+ 6),
592 shared_data
->cleanwin
);
594 for (int i
= 1; i
<= MaxTL
; i
++) {
595 printLevelHeader(outs
, i
);
596 printColumnLabels(outs
);
597 thread
->setMiscReg(MISCREG_TL
, i
);
598 printRegPair(outs
, "Tpc",
599 thread
->readMiscReg(MISCREG_TPC
),
600 shared_data
->tpc
[i
-1]);
601 printRegPair(outs
, "Tnpc",
602 thread
->readMiscReg(MISCREG_TNPC
),
603 shared_data
->tnpc
[i
-1]);
604 printRegPair(outs
, "Tstate",
605 thread
->readMiscReg(MISCREG_TSTATE
),
606 shared_data
->tstate
[i
-1]);
607 printRegPair(outs
, "Tt",
608 thread
->readMiscReg(MISCREG_TT
),
609 shared_data
->tt
[i
-1]);
610 printRegPair(outs
, "Htstate",
611 thread
->readMiscReg(MISCREG_HTSTATE
),
612 shared_data
->htstate
[i
-1]);
614 thread
->setMiscReg(MISCREG_TL
, oldTl
);
617 printSectionHeader(outs
, "General Purpose Registers");
618 static const char * regtypes
[4] = {"%g", "%o", "%l", "%i"};
619 for(int y
= 0; y
< 4; y
++) {
620 for(int x
= 0; x
< 8; x
++) {
622 sprintf(label
, "%s%d", regtypes
[y
], x
);
623 printRegPair(outs
, label
,
624 thread
->readIntReg(y
*8+x
),
625 shared_data
->intregs
[y
*8+x
]);
629 for (int x
= 0; x
< 32; x
++) {
631 sprintf(label
, "%%f%d", x
);
632 printRegPair(outs
, label
,
633 thread
->readFloatRegBits(x
,FloatRegFile::DoubleWidth
),
634 shared_data
->fpregs
[x
]);
638 printColumnLabels(outs
);
640 for (int x
= 0; x
< 64; x
++) {
641 if (shared_data
->itb
[x
] != ULL(0xFFFFFFFFFFFFFFFF) ||
642 thread
->getITBPtr()->TteRead(x
) != ULL(0xFFFFFFFFFFFFFFFF)) {
643 sprintf(label
, "I-TLB:%02d", x
);
644 printRegPair(outs
, label
, thread
->getITBPtr()->TteRead(x
),
645 shared_data
->itb
[x
]);
648 for (int x
= 0; x
< 64; x
++) {
649 if (shared_data
->dtb
[x
] != ULL(0xFFFFFFFFFFFFFFFF) ||
650 thread
->getDTBPtr()->TteRead(x
) != ULL(0xFFFFFFFFFFFFFFFF)) {
651 sprintf(label
, "D-TLB:%02d", x
);
652 printRegPair(outs
, label
, thread
->getDTBPtr()->TteRead(x
),
653 shared_data
->dtb
[x
]);
656 thread
->getITBPtr()->dumpAll();
657 thread
->getDTBPtr()->dumpAll();
662 fatal("Differences found between Legion and M5\n");
667 shared_data
->flags
= OWN_LEGION
;
676 vector
<bool> Trace::InstRecord::flags(NUM_BITS
);
677 string
Trace::InstRecord::trace_system
;
679 ////////////////////////////////////////////////////////////////////////
681 // Parameter space for per-cycle execution address tracing options.
682 // Derive from ParamContext so we can override checkParams() function.
684 class ExecutionTraceParamContext
: public ParamContext
687 ExecutionTraceParamContext(const string
&_iniSection
)
688 : ParamContext(_iniSection
)
692 void checkParams(); // defined at bottom of file
695 ExecutionTraceParamContext
exeTraceParams("exetrace");
697 Param
<bool> exe_trace_spec(&exeTraceParams
, "speculative",
698 "capture speculative instructions", true);
700 Param
<bool> exe_trace_print_cycle(&exeTraceParams
, "print_cycle",
701 "print cycle number", true);
702 Param
<bool> exe_trace_print_opclass(&exeTraceParams
, "print_opclass",
703 "print op class", true);
704 Param
<bool> exe_trace_print_thread(&exeTraceParams
, "print_thread",
705 "print thread number", true);
706 Param
<bool> exe_trace_print_effaddr(&exeTraceParams
, "print_effaddr",
707 "print effective address", true);
708 Param
<bool> exe_trace_print_data(&exeTraceParams
, "print_data",
709 "print result data", true);
710 Param
<bool> exe_trace_print_iregs(&exeTraceParams
, "print_iregs",
711 "print all integer regs", false);
712 Param
<bool> exe_trace_print_fetchseq(&exeTraceParams
, "print_fetchseq",
713 "print fetch sequence number", false);
714 Param
<bool> exe_trace_print_cp_seq(&exeTraceParams
, "print_cpseq",
715 "print correct-path sequence number", false);
716 Param
<bool> exe_trace_print_reg_delta(&exeTraceParams
, "print_reg_delta",
717 "print which registers changed to what", false);
718 Param
<bool> exe_trace_pc_symbol(&exeTraceParams
, "pc_symbol",
719 "Use symbols for the PC if available", true);
720 Param
<bool> exe_trace_intel_format(&exeTraceParams
, "intel_format",
721 "print trace in intel compatible format", false);
722 Param
<bool> exe_trace_legion_lockstep(&exeTraceParams
, "legion_lockstep",
723 "Compare sim state to legion state every cycle",
725 Param
<string
> exe_trace_system(&exeTraceParams
, "trace_system",
726 "print trace of which system (client or server)",
731 // Helper function for ExecutionTraceParamContext::checkParams() just
732 // to get us into the InstRecord namespace
735 Trace::InstRecord::setParams()
737 flags
[TRACE_MISSPEC
] = exe_trace_spec
;
739 flags
[PRINT_CYCLE
] = exe_trace_print_cycle
;
740 flags
[PRINT_OP_CLASS
] = exe_trace_print_opclass
;
741 flags
[PRINT_THREAD_NUM
] = exe_trace_print_thread
;
742 flags
[PRINT_RESULT_DATA
] = exe_trace_print_effaddr
;
743 flags
[PRINT_EFF_ADDR
] = exe_trace_print_data
;
744 flags
[PRINT_INT_REGS
] = exe_trace_print_iregs
;
745 flags
[PRINT_FETCH_SEQ
] = exe_trace_print_fetchseq
;
746 flags
[PRINT_CP_SEQ
] = exe_trace_print_cp_seq
;
747 flags
[PRINT_REG_DELTA
] = exe_trace_print_reg_delta
;
748 flags
[PC_SYMBOL
] = exe_trace_pc_symbol
;
749 flags
[INTEL_FORMAT
] = exe_trace_intel_format
;
750 flags
[LEGION_LOCKSTEP
] = exe_trace_legion_lockstep
;
751 trace_system
= exe_trace_system
;
753 // If were going to be in lockstep with Legion
754 // Setup shared memory, and get otherwise ready
755 if (flags
[LEGION_LOCKSTEP
]) {
756 int shmfd
= shmget('M' << 24 | getuid(), sizeof(SharedData
), 0777);
758 fatal("Couldn't get shared memory fd. Is Legion running?");
760 shared_data
= (SharedData
*)shmat(shmfd
, NULL
, SHM_RND
);
761 if (shared_data
== (SharedData
*)-1)
762 fatal("Couldn't allocate shared memory");
764 if (shared_data
->flags
!= OWN_M5
)
765 fatal("Shared memory has invalid owner");
767 if (shared_data
->version
!= VERSION
)
768 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION
,
769 shared_data
->version
);
771 // step legion forward one cycle so we can get register values
772 shared_data
->flags
= OWN_LEGION
;
777 ExecutionTraceParamContext::checkParams()
779 Trace::InstRecord::setParams();