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 diffFsr
= false;
311 bool diffCcr
= false;
314 bool diffAsi
= false;
315 bool diffPil
= false;
316 bool diffCwp
= false;
317 bool diffCansave
= false;
318 bool diffCanrestore
= false;
319 bool diffOtherwin
= false;
320 bool diffCleanwin
= false;
321 bool diffTlb
= false;
324 // We took a trap on a micro-op...
325 if (wasMicro
&& !staticInst
->isMicroOp())
327 // let's skip comparing this cycle
329 if (shared_data
->flags
== OWN_M5
) {
330 shared_data
->flags
= OWN_LEGION
;
337 if (staticInst
->isLastMicroOp())
339 else if (staticInst
->isMicroOp())
343 if(!staticInst
->isMicroOp() || staticInst
->isLastMicroOp()) {
345 if (shared_data
->flags
== OWN_M5
) {
346 m5Pc
= PC
& TheISA::PAddrImplMask
;
347 if (bits(shared_data
->pstate
,3,3)) {
350 lgnPc
= shared_data
->pc
& TheISA::PAddrImplMask
;
354 if (shared_data
->cycle_count
!=
355 thread
->getCpuPtr()->instCount())
358 if (shared_data
->instruction
!=
359 (SparcISA::MachInst
)staticInst
->machInst
) {
362 // assume we have %g0 working correctly
363 for (int i
= 1; i
< TheISA::NumIntArchRegs
; i
++) {
364 if (thread
->readIntReg(i
) != shared_data
->intregs
[i
]) {
368 for (int i
= 0; i
< TheISA::NumFloatRegs
/2; i
++) {
369 if (thread
->readFloatRegBits(i
*2,FloatRegFile::DoubleWidth
) != shared_data
->fpregs
[i
]) {
373 uint64_t oldTl
= thread
->readMiscReg(MISCREG_TL
);
374 if (oldTl
!= shared_data
->tl
)
376 for (int i
= 1; i
<= MaxTL
; i
++) {
377 thread
->setMiscReg(MISCREG_TL
, i
);
378 if (thread
->readMiscReg(MISCREG_TPC
) !=
379 shared_data
->tpc
[i
-1])
381 if (thread
->readMiscReg(MISCREG_TNPC
) !=
382 shared_data
->tnpc
[i
-1])
384 if (thread
->readMiscReg(MISCREG_TSTATE
) !=
385 shared_data
->tstate
[i
-1])
387 if (thread
->readMiscReg(MISCREG_TT
) !=
388 shared_data
->tt
[i
-1])
390 if (thread
->readMiscReg(MISCREG_HTSTATE
) !=
391 shared_data
->htstate
[i
-1])
394 thread
->setMiscReg(MISCREG_TL
, oldTl
);
396 if(shared_data
->tba
!= thread
->readMiscReg(MISCREG_TBA
))
398 //When the hpstate register is read by an instruction,
399 //legion has bit 11 set. When it's in storage, it doesn't.
400 //Since we don't directly support seperate interpretations
401 //of the registers like that, the bit is always set to 1 and
402 //we just don't compare it. It's not supposed to matter
404 if((shared_data
->hpstate
| (1 << 11)) != thread
->readMiscReg(MISCREG_HPSTATE
))
406 if(shared_data
->htba
!= thread
->readMiscReg(MISCREG_HTBA
))
408 if(shared_data
->pstate
!= thread
->readMiscReg(MISCREG_PSTATE
))
410 //if(shared_data->y != thread->readMiscReg(MISCREG_Y))
412 thread
->readIntReg(NumIntArchRegs
+ 1))
414 if(shared_data
->fsr
!= thread
->readMiscReg(MISCREG_FSR
)) {
416 if (mbits(shared_data
->fsr
, 63,10) ==
417 mbits(thread
->readMiscReg(MISCREG_FSR
), 63,10)) {
418 thread
->setMiscReg(MISCREG_FSR
, shared_data
->fsr
);
422 //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
423 if(shared_data
->ccr
!=
424 thread
->readIntReg(NumIntArchRegs
+ 2))
426 if(shared_data
->gl
!= thread
->readMiscReg(MISCREG_GL
))
428 if(shared_data
->asi
!= thread
->readMiscReg(MISCREG_ASI
))
430 if(shared_data
->pil
!= thread
->readMiscReg(MISCREG_PIL
))
432 if(shared_data
->cwp
!= thread
->readMiscReg(MISCREG_CWP
))
434 //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
435 if(shared_data
->cansave
!=
436 thread
->readIntReg(NumIntArchRegs
+ 3))
438 //if(shared_data->canrestore !=
439 // thread->readMiscReg(MISCREG_CANRESTORE))
440 if(shared_data
->canrestore
!=
441 thread
->readIntReg(NumIntArchRegs
+ 4))
442 diffCanrestore
= true;
443 //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
444 if(shared_data
->otherwin
!=
445 thread
->readIntReg(NumIntArchRegs
+ 6))
447 //if(shared_data->cleanwin != thread->readMiscReg(MISCREG_CLEANWIN))
448 if(shared_data
->cleanwin
!=
449 thread
->readIntReg(NumIntArchRegs
+ 5))
452 for (int i
= 0; i
< 64; i
++) {
453 if (shared_data
->itb
[i
] != thread
->getITBPtr()->TteRead(i
))
455 if (shared_data
->dtb
[i
] != thread
->getDTBPtr()->TteRead(i
))
459 if (diffPC
|| diffCC
|| diffInst
|| diffIntRegs
||
460 diffFpRegs
|| diffTpc
|| diffTnpc
|| diffTstate
||
461 diffTt
|| diffHpstate
|| diffHtstate
|| diffHtba
||
462 diffPstate
|| diffY
|| diffCcr
|| diffTl
|| diffFsr
||
463 diffGl
|| diffAsi
|| diffPil
|| diffCwp
|| diffCansave
||
464 diffCanrestore
|| diffOtherwin
|| diffCleanwin
|| diffTlb
)
467 outs
<< "Differences found between M5 and Legion:";
473 outs
<< " [Instruction]";
475 outs
<< " [IntRegs]";
487 outs
<< " [Hpstate]";
489 outs
<< " [Htstate]";
511 outs
<< " [Cansave]";
513 outs
<< " [Canrestore]";
515 outs
<< " [Otherwin]";
517 outs
<< " [Cleanwin]";
520 outs
<< endl
<< endl
;
522 outs
<< right
<< setfill(' ') << setw(15)
523 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
524 << hex
<< m5Pc
<< endl
;
525 outs
<< setfill(' ') << setw(15)
526 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
527 << lgnPc
<< endl
<< endl
;
529 outs
<< right
<< setfill(' ') << setw(15)
530 << "M5 CC: " << "0x"<< setw(16) << setfill('0')
531 << hex
<< thread
->getCpuPtr()->instCount() << endl
;
532 outs
<< setfill(' ') << setw(15)
533 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
534 << shared_data
->cycle_count
<< endl
<< endl
;
536 outs
<< setfill(' ') << setw(15)
537 << "M5 Inst: " << "0x"<< setw(8)
538 << setfill('0') << hex
<< staticInst
->machInst
539 << staticInst
->disassemble(m5Pc
, debugSymbolTable
)
542 StaticInstPtr legionInst
=
543 StaticInst::decode(makeExtMI(shared_data
->instruction
,
545 outs
<< setfill(' ') << setw(15)
547 << "0x" << setw(8) << setfill('0') << hex
548 << shared_data
->instruction
549 << legionInst
->disassemble(lgnPc
, debugSymbolTable
)
552 printSectionHeader(outs
, "General State");
553 printColumnLabels(outs
);
554 printRegPair(outs
, "HPstate",
555 thread
->readMiscReg(MISCREG_HPSTATE
),
556 shared_data
->hpstate
| (1 << 11));
557 printRegPair(outs
, "Htba",
558 thread
->readMiscReg(MISCREG_HTBA
),
560 printRegPair(outs
, "Pstate",
561 thread
->readMiscReg(MISCREG_PSTATE
),
562 shared_data
->pstate
);
563 printRegPair(outs
, "Y",
564 //thread->readMiscReg(MISCREG_Y),
565 thread
->readIntReg(NumIntArchRegs
+ 1),
567 printRegPair(outs
, "FSR",
568 thread
->readMiscReg(MISCREG_FSR
),
570 printRegPair(outs
, "Ccr",
571 //thread->readMiscReg(MISCREG_CCR),
572 thread
->readIntReg(NumIntArchRegs
+ 2),
574 printRegPair(outs
, "Tl",
575 thread
->readMiscReg(MISCREG_TL
),
577 printRegPair(outs
, "Gl",
578 thread
->readMiscReg(MISCREG_GL
),
580 printRegPair(outs
, "Asi",
581 thread
->readMiscReg(MISCREG_ASI
),
583 printRegPair(outs
, "Pil",
584 thread
->readMiscReg(MISCREG_PIL
),
586 printRegPair(outs
, "Cwp",
587 thread
->readMiscReg(MISCREG_CWP
),
589 printRegPair(outs
, "Cansave",
590 //thread->readMiscReg(MISCREG_CANSAVE),
591 thread
->readIntReg(NumIntArchRegs
+ 3),
592 shared_data
->cansave
);
593 printRegPair(outs
, "Canrestore",
594 //thread->readMiscReg(MISCREG_CANRESTORE),
595 thread
->readIntReg(NumIntArchRegs
+ 4),
596 shared_data
->canrestore
);
597 printRegPair(outs
, "Otherwin",
598 //thread->readMiscReg(MISCREG_OTHERWIN),
599 thread
->readIntReg(NumIntArchRegs
+ 6),
600 shared_data
->otherwin
);
601 printRegPair(outs
, "Cleanwin",
602 //thread->readMiscReg(MISCREG_CLEANWIN),
603 thread
->readIntReg(NumIntArchRegs
+ 5),
604 shared_data
->cleanwin
);
606 for (int i
= 1; i
<= MaxTL
; i
++) {
607 printLevelHeader(outs
, i
);
608 printColumnLabels(outs
);
609 thread
->setMiscReg(MISCREG_TL
, i
);
610 printRegPair(outs
, "Tpc",
611 thread
->readMiscReg(MISCREG_TPC
),
612 shared_data
->tpc
[i
-1]);
613 printRegPair(outs
, "Tnpc",
614 thread
->readMiscReg(MISCREG_TNPC
),
615 shared_data
->tnpc
[i
-1]);
616 printRegPair(outs
, "Tstate",
617 thread
->readMiscReg(MISCREG_TSTATE
),
618 shared_data
->tstate
[i
-1]);
619 printRegPair(outs
, "Tt",
620 thread
->readMiscReg(MISCREG_TT
),
621 shared_data
->tt
[i
-1]);
622 printRegPair(outs
, "Htstate",
623 thread
->readMiscReg(MISCREG_HTSTATE
),
624 shared_data
->htstate
[i
-1]);
626 thread
->setMiscReg(MISCREG_TL
, oldTl
);
629 printSectionHeader(outs
, "General Purpose Registers");
630 static const char * regtypes
[4] = {"%g", "%o", "%l", "%i"};
631 for(int y
= 0; y
< 4; y
++) {
632 for(int x
= 0; x
< 8; x
++) {
634 sprintf(label
, "%s%d", regtypes
[y
], x
);
635 printRegPair(outs
, label
,
636 thread
->readIntReg(y
*8+x
),
637 shared_data
->intregs
[y
*8+x
]);
641 for (int x
= 0; x
< 32; x
++) {
643 sprintf(label
, "%%f%d", x
);
644 printRegPair(outs
, label
,
645 thread
->readFloatRegBits(x
*2,FloatRegFile::DoubleWidth
),
646 shared_data
->fpregs
[x
]);
650 printColumnLabels(outs
);
652 for (int x
= 0; x
< 64; x
++) {
653 if (shared_data
->itb
[x
] != ULL(0xFFFFFFFFFFFFFFFF) ||
654 thread
->getITBPtr()->TteRead(x
) != ULL(0xFFFFFFFFFFFFFFFF)) {
655 sprintf(label
, "I-TLB:%02d", x
);
656 printRegPair(outs
, label
, thread
->getITBPtr()->TteRead(x
),
657 shared_data
->itb
[x
]);
660 for (int x
= 0; x
< 64; x
++) {
661 if (shared_data
->dtb
[x
] != ULL(0xFFFFFFFFFFFFFFFF) ||
662 thread
->getDTBPtr()->TteRead(x
) != ULL(0xFFFFFFFFFFFFFFFF)) {
663 sprintf(label
, "D-TLB:%02d", x
);
664 printRegPair(outs
, label
, thread
->getDTBPtr()->TteRead(x
),
665 shared_data
->dtb
[x
]);
668 thread
->getITBPtr()->dumpAll();
669 thread
->getDTBPtr()->dumpAll();
674 fatal("Differences found between Legion and M5\n");
679 shared_data
->flags
= OWN_LEGION
;
688 vector
<bool> Trace::InstRecord::flags(NUM_BITS
);
689 string
Trace::InstRecord::trace_system
;
691 ////////////////////////////////////////////////////////////////////////
693 // Parameter space for per-cycle execution address tracing options.
694 // Derive from ParamContext so we can override checkParams() function.
696 class ExecutionTraceParamContext
: public ParamContext
699 ExecutionTraceParamContext(const string
&_iniSection
)
700 : ParamContext(_iniSection
)
704 void checkParams(); // defined at bottom of file
707 ExecutionTraceParamContext
exeTraceParams("exetrace");
709 Param
<bool> exe_trace_spec(&exeTraceParams
, "speculative",
710 "capture speculative instructions", true);
712 Param
<bool> exe_trace_print_cycle(&exeTraceParams
, "print_cycle",
713 "print cycle number", true);
714 Param
<bool> exe_trace_print_opclass(&exeTraceParams
, "print_opclass",
715 "print op class", true);
716 Param
<bool> exe_trace_print_thread(&exeTraceParams
, "print_thread",
717 "print thread number", true);
718 Param
<bool> exe_trace_print_effaddr(&exeTraceParams
, "print_effaddr",
719 "print effective address", true);
720 Param
<bool> exe_trace_print_data(&exeTraceParams
, "print_data",
721 "print result data", true);
722 Param
<bool> exe_trace_print_iregs(&exeTraceParams
, "print_iregs",
723 "print all integer regs", false);
724 Param
<bool> exe_trace_print_fetchseq(&exeTraceParams
, "print_fetchseq",
725 "print fetch sequence number", false);
726 Param
<bool> exe_trace_print_cp_seq(&exeTraceParams
, "print_cpseq",
727 "print correct-path sequence number", false);
728 Param
<bool> exe_trace_print_reg_delta(&exeTraceParams
, "print_reg_delta",
729 "print which registers changed to what", false);
730 Param
<bool> exe_trace_pc_symbol(&exeTraceParams
, "pc_symbol",
731 "Use symbols for the PC if available", true);
732 Param
<bool> exe_trace_intel_format(&exeTraceParams
, "intel_format",
733 "print trace in intel compatible format", false);
734 Param
<bool> exe_trace_legion_lockstep(&exeTraceParams
, "legion_lockstep",
735 "Compare sim state to legion state every cycle",
737 Param
<string
> exe_trace_system(&exeTraceParams
, "trace_system",
738 "print trace of which system (client or server)",
743 // Helper function for ExecutionTraceParamContext::checkParams() just
744 // to get us into the InstRecord namespace
747 Trace::InstRecord::setParams()
749 flags
[TRACE_MISSPEC
] = exe_trace_spec
;
751 flags
[PRINT_CYCLE
] = exe_trace_print_cycle
;
752 flags
[PRINT_OP_CLASS
] = exe_trace_print_opclass
;
753 flags
[PRINT_THREAD_NUM
] = exe_trace_print_thread
;
754 flags
[PRINT_RESULT_DATA
] = exe_trace_print_effaddr
;
755 flags
[PRINT_EFF_ADDR
] = exe_trace_print_data
;
756 flags
[PRINT_INT_REGS
] = exe_trace_print_iregs
;
757 flags
[PRINT_FETCH_SEQ
] = exe_trace_print_fetchseq
;
758 flags
[PRINT_CP_SEQ
] = exe_trace_print_cp_seq
;
759 flags
[PRINT_REG_DELTA
] = exe_trace_print_reg_delta
;
760 flags
[PC_SYMBOL
] = exe_trace_pc_symbol
;
761 flags
[INTEL_FORMAT
] = exe_trace_intel_format
;
762 flags
[LEGION_LOCKSTEP
] = exe_trace_legion_lockstep
;
763 trace_system
= exe_trace_system
;
765 // If were going to be in lockstep with Legion
766 // Setup shared memory, and get otherwise ready
767 if (flags
[LEGION_LOCKSTEP
]) {
768 int shmfd
= shmget('M' << 24 | getuid(), sizeof(SharedData
), 0777);
770 fatal("Couldn't get shared memory fd. Is Legion running?");
772 shared_data
= (SharedData
*)shmat(shmfd
, NULL
, SHM_RND
);
773 if (shared_data
== (SharedData
*)-1)
774 fatal("Couldn't allocate shared memory");
776 if (shared_data
->flags
!= OWN_M5
)
777 fatal("Shared memory has invalid owner");
779 if (shared_data
->version
!= VERSION
)
780 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION
,
781 shared_data
->version
);
783 // step legion forward one cycle so we can get register values
784 shared_data
->flags
= OWN_LEGION
;
789 ExecutionTraceParamContext::checkParams()
791 Trace::InstRecord::setParams();