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
->readMiscReg(SparcISA::MISCREG_CCR
);
153 outs
<< " CCR = " << newVal
;
156 newVal
= thread
->readMiscReg(SparcISA::MISCREG_Y
);
159 outs
<< " Y = " << newVal
;
162 for(int y
= 0; y
< 4; y
++)
164 for(int x
= 0; x
< 8; x
++)
166 int index
= x
+ 8 * y
;
167 newVal
= thread
->readIntReg(index
);
168 if(regs
[index
] != newVal
)
170 outs
<< " " << prefixes
[y
] << dec
<< x
<< " = " << hex
<< newVal
;
171 regs
[index
] = newVal
;
175 for(int y
= 0; y
< 32; y
++)
177 newVal
= thread
->readFloatRegBits(2 * y
, 64);
178 if(floats
[y
] != newVal
)
180 outs
<< " F" << dec
<< (2 * y
) << " = " << hex
<< newVal
;
188 else if (flags
[INTEL_FORMAT
]) {
190 bool is_trace_system
= (thread
->getCpuPtr()->system
->name() == trace_system
);
192 bool is_trace_system
= true;
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
;
200 } else if (staticInst
->isStore()) {
201 outs
<< "<WR 0x" << hex
<< addr
;
207 if (flags
[PRINT_CYCLE
])
208 ccprintf(outs
, "%7d: ", cycle
);
210 outs
<< thread
->getCpuPtr()->name() << " ";
212 if (flags
[TRACE_MISSPEC
])
213 outs
<< (misspeculating
? "-" : "+") << " ";
215 if (flags
[PRINT_THREAD_NUM
])
216 outs
<< "T" << thread
->getThreadNum() << " : ";
222 && debugSymbolTable
->findNearestSymbol(PC
, sym_str
, sym_addr
)
223 && flags
[PC_SYMBOL
]) {
225 sym_str
+= csprintf("+%d", PC
- sym_addr
);
226 outs
<< "@" << sym_str
<< " : ";
229 outs
<< "0x" << hex
<< PC
<< " : ";
233 // Print decoded instruction
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)
244 outs
<< setw(26) << left
<< staticInst
->disassemble(PC
, debugSymbolTable
);
249 if (flags
[PRINT_OP_CLASS
]) {
250 outs
<< opClassStrings
[staticInst
->opClass()] << " : ";
253 if (flags
[PRINT_RESULT_DATA
] && data_status
!= DataInvalid
) {
256 if (data_status
== DataDouble
)
257 ccprintf(outs
, "%f", data
.as_double
);
259 ccprintf(outs
, "%#018x", data
.as_int
);
261 ccprintf(outs
, "%#018x", data
.as_int
);
265 if (flags
[PRINT_EFF_ADDR
] && addr_valid
)
266 outs
<< " A=0x" << hex
<< addr
;
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" : " "));
277 if (flags
[PRINT_FETCH_SEQ
] && fetch_seq_valid
)
278 outs
<< " FetchSeq=" << dec
<< fetch_seq
;
280 if (flags
[PRINT_CP_SEQ
] && cp_seq_valid
)
281 outs
<< " CPSeq=" << dec
<< cp_seq
;
288 #if THE_ISA == SPARC_ISA && FULL_SYSTEM
290 if (flags
[LEGION_LOCKSTEP
])
292 bool compared
= false;
295 bool diffInst
= false;
296 bool diffIntRegs
= false;
297 bool diffFpRegs
= false;
298 bool diffTpc
= false;
299 bool diffTnpc
= false;
300 bool diffTstate
= false;
302 bool diffTba
= false;
303 bool diffHpstate
= false;
304 bool diffHtstate
= false;
305 bool diffHtba
= false;
306 bool diffPstate
= false;
308 bool diffCcr
= false;
311 bool diffAsi
= false;
312 bool diffPil
= false;
313 bool diffCwp
= false;
314 bool diffCansave
= false;
315 bool diffCanrestore
= false;
316 bool diffOtherwin
= false;
317 bool diffCleanwin
= false;
318 bool diffTlb
= false;
321 // We took a trap on a micro-op...
322 if (wasMicro
&& !staticInst
->isMicroOp())
324 // let's skip comparing this cycle
326 if (shared_data
->flags
== OWN_M5
) {
327 shared_data
->flags
= OWN_LEGION
;
334 if (staticInst
->isLastMicroOp())
336 else if (staticInst
->isMicroOp())
340 if(!staticInst
->isMicroOp() || staticInst
->isLastMicroOp()) {
342 if (shared_data
->flags
== OWN_M5
) {
343 m5Pc
= PC
& TheISA::PAddrImplMask
;
344 if (bits(shared_data
->pstate
,3,3)) {
347 lgnPc
= shared_data
->pc
& TheISA::PAddrImplMask
;
351 if (shared_data
->cycle_count
!=
352 thread
->getCpuPtr()->instCount())
355 if (shared_data
->instruction
!=
356 (SparcISA::MachInst
)staticInst
->machInst
) {
359 for (int i
= 0; i
< TheISA::NumIntArchRegs
; i
++) {
360 if (thread
->readIntReg(i
) != shared_data
->intregs
[i
]) {
364 for (int i
= 0; i
< TheISA::NumFloatRegs
/2; i
++) {
365 if (thread
->readFloatRegBits(i
*2,FloatRegFile::DoubleWidth
) != shared_data
->fpregs
[i
]) {
369 uint64_t oldTl
= thread
->readMiscReg(MISCREG_TL
);
370 if (oldTl
!= shared_data
->tl
)
372 for (int i
= 1; i
<= MaxTL
; i
++) {
373 thread
->setMiscReg(MISCREG_TL
, i
);
374 if (thread
->readMiscReg(MISCREG_TPC
) !=
375 shared_data
->tpc
[i
-1])
377 if (thread
->readMiscReg(MISCREG_TNPC
) !=
378 shared_data
->tnpc
[i
-1])
380 if (thread
->readMiscReg(MISCREG_TSTATE
) !=
381 shared_data
->tstate
[i
-1])
383 if (thread
->readMiscReg(MISCREG_TT
) !=
384 shared_data
->tt
[i
-1])
386 if (thread
->readMiscReg(MISCREG_HTSTATE
) !=
387 shared_data
->htstate
[i
-1])
390 thread
->setMiscReg(MISCREG_TL
, oldTl
);
392 if(shared_data
->tba
!= thread
->readMiscReg(MISCREG_TBA
))
394 //When the hpstate register is read by an instruction,
395 //legion has bit 11 set. When it's in storage, it doesn't.
396 //Since we don't directly support seperate interpretations
397 //of the registers like that, the bit is always set to 1 and
398 //we just don't compare it. It's not supposed to matter
400 if((shared_data
->hpstate
| (1 << 11)) != thread
->readMiscReg(MISCREG_HPSTATE
))
402 if(shared_data
->htba
!= thread
->readMiscReg(MISCREG_HTBA
))
404 if(shared_data
->pstate
!= thread
->readMiscReg(MISCREG_PSTATE
))
406 if(shared_data
->y
!= thread
->readMiscReg(MISCREG_Y
))
408 if(shared_data
->ccr
!= thread
->readMiscReg(MISCREG_CCR
))
410 if(shared_data
->gl
!= thread
->readMiscReg(MISCREG_GL
))
412 if(shared_data
->asi
!= thread
->readMiscReg(MISCREG_ASI
))
414 if(shared_data
->pil
!= thread
->readMiscReg(MISCREG_PIL
))
416 if(shared_data
->cwp
!= thread
->readMiscReg(MISCREG_CWP
))
418 if(shared_data
->cansave
!= thread
->readMiscReg(MISCREG_CANSAVE
))
420 if(shared_data
->canrestore
!=
421 thread
->readMiscReg(MISCREG_CANRESTORE
))
422 diffCanrestore
= true;
423 if(shared_data
->otherwin
!= thread
->readMiscReg(MISCREG_OTHERWIN
))
425 if(shared_data
->cleanwin
!= thread
->readMiscReg(MISCREG_CLEANWIN
))
428 for (int i
= 0; i
< 64; i
++) {
429 if (shared_data
->itb
[i
] != thread
->getITBPtr()->TteRead(i
))
431 if (shared_data
->dtb
[i
] != thread
->getDTBPtr()->TteRead(i
))
435 if ((diffPC
|| diffCC
|| diffInst
|| diffIntRegs
||
436 diffFpRegs
|| diffTpc
|| diffTnpc
|| diffTstate
||
437 diffTt
|| diffHpstate
|| diffHtstate
|| diffHtba
||
438 diffPstate
|| diffY
|| diffCcr
|| diffTl
|| diffGl
||
439 diffAsi
|| diffPil
|| diffCwp
|| diffCansave
||
440 diffCanrestore
|| diffOtherwin
|| diffCleanwin
|| diffTlb
)
441 && !((staticInst
->machInst
& 0xC1F80000) == 0x81D00000)
442 && !(((staticInst
->machInst
& 0xC0000000) == 0xC0000000)
443 && shared_data
->tl
== thread
->readMiscReg(MISCREG_TL
) + 1)
446 outs
<< "Differences found between M5 and Legion:";
452 outs
<< " [Instruction]";
454 outs
<< " [IntRegs]";
466 outs
<< " [Hpstate]";
468 outs
<< " [Htstate]";
488 outs
<< " [Cansave]";
490 outs
<< " [Canrestore]";
492 outs
<< " [Otherwin]";
494 outs
<< " [Cleanwin]";
497 outs
<< endl
<< endl
;
499 outs
<< right
<< setfill(' ') << setw(15)
500 << "M5 PC: " << "0x"<< setw(16) << setfill('0')
501 << hex
<< m5Pc
<< endl
;
502 outs
<< setfill(' ') << setw(15)
503 << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
504 << lgnPc
<< endl
<< endl
;
506 outs
<< right
<< setfill(' ') << setw(15)
507 << "M5 CC: " << "0x"<< setw(16) << setfill('0')
508 << hex
<< thread
->getCpuPtr()->instCount() << endl
;
509 outs
<< setfill(' ') << setw(15)
510 << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
511 << shared_data
->cycle_count
<< endl
<< endl
;
513 outs
<< setfill(' ') << setw(15)
514 << "M5 Inst: " << "0x"<< setw(8)
515 << setfill('0') << hex
<< staticInst
->machInst
516 << staticInst
->disassemble(m5Pc
, debugSymbolTable
)
519 StaticInstPtr legionInst
=
520 StaticInst::decode(makeExtMI(shared_data
->instruction
,
522 outs
<< setfill(' ') << setw(15)
524 << "0x" << setw(8) << setfill('0') << hex
525 << shared_data
->instruction
526 << legionInst
->disassemble(lgnPc
, debugSymbolTable
)
529 printSectionHeader(outs
, "General State");
530 printColumnLabels(outs
);
531 printRegPair(outs
, "HPstate",
532 thread
->readMiscReg(MISCREG_HPSTATE
),
533 shared_data
->hpstate
| (1 << 11));
534 printRegPair(outs
, "Htba",
535 thread
->readMiscReg(MISCREG_HTBA
),
537 printRegPair(outs
, "Pstate",
538 thread
->readMiscReg(MISCREG_PSTATE
),
539 shared_data
->pstate
);
540 printRegPair(outs
, "Y",
541 thread
->readMiscReg(MISCREG_Y
),
543 printRegPair(outs
, "Ccr",
544 thread
->readMiscReg(MISCREG_CCR
),
546 printRegPair(outs
, "Tl",
547 thread
->readMiscReg(MISCREG_TL
),
549 printRegPair(outs
, "Gl",
550 thread
->readMiscReg(MISCREG_GL
),
552 printRegPair(outs
, "Asi",
553 thread
->readMiscReg(MISCREG_ASI
),
555 printRegPair(outs
, "Pil",
556 thread
->readMiscReg(MISCREG_PIL
),
558 printRegPair(outs
, "Cwp",
559 thread
->readMiscReg(MISCREG_CWP
),
561 printRegPair(outs
, "Cansave",
562 thread
->readMiscReg(MISCREG_CANSAVE
),
563 shared_data
->cansave
);
564 printRegPair(outs
, "Canrestore",
565 thread
->readMiscReg(MISCREG_CANRESTORE
),
566 shared_data
->canrestore
);
567 printRegPair(outs
, "Otherwin",
568 thread
->readMiscReg(MISCREG_OTHERWIN
),
569 shared_data
->otherwin
);
570 printRegPair(outs
, "Cleanwin",
571 thread
->readMiscReg(MISCREG_CLEANWIN
),
572 shared_data
->cleanwin
);
574 for (int i
= 1; i
<= MaxTL
; i
++) {
575 printLevelHeader(outs
, i
);
576 printColumnLabels(outs
);
577 thread
->setMiscReg(MISCREG_TL
, i
);
578 printRegPair(outs
, "Tpc",
579 thread
->readMiscReg(MISCREG_TPC
),
580 shared_data
->tpc
[i
-1]);
581 printRegPair(outs
, "Tnpc",
582 thread
->readMiscReg(MISCREG_TNPC
),
583 shared_data
->tnpc
[i
-1]);
584 printRegPair(outs
, "Tstate",
585 thread
->readMiscReg(MISCREG_TSTATE
),
586 shared_data
->tstate
[i
-1]);
587 printRegPair(outs
, "Tt",
588 thread
->readMiscReg(MISCREG_TT
),
589 shared_data
->tt
[i
-1]);
590 printRegPair(outs
, "Htstate",
591 thread
->readMiscReg(MISCREG_HTSTATE
),
592 shared_data
->htstate
[i
-1]);
594 thread
->setMiscReg(MISCREG_TL
, oldTl
);
597 printSectionHeader(outs
, "General Purpose Registers");
598 static const char * regtypes
[4] = {"%g", "%o", "%l", "%i"};
599 for(int y
= 0; y
< 4; y
++) {
600 for(int x
= 0; x
< 8; x
++) {
602 sprintf(label
, "%s%d", regtypes
[y
], x
);
603 printRegPair(outs
, label
,
604 thread
->readIntReg(y
*8+x
),
605 shared_data
->intregs
[y
*8+x
]);
609 for (int x
= 0; x
< 32; x
++) {
611 sprintf(label
, "%%f%d", x
);
612 printRegPair(outs
, label
,
613 thread
->readFloatRegBits(x
,FloatRegFile::DoubleWidth
),
614 shared_data
->fpregs
[x
]);
618 printColumnLabels(outs
);
620 for (int x
= 0; x
< 64; x
++) {
621 if (shared_data
->itb
[x
] != ULL(0xFFFFFFFFFFFFFFFF) ||
622 thread
->getITBPtr()->TteRead(x
) != ULL(0xFFFFFFFFFFFFFFFF)) {
623 sprintf(label
, "I-TLB:%02d", x
);
624 printRegPair(outs
, label
, thread
->getITBPtr()->TteRead(x
),
625 shared_data
->itb
[x
]);
628 for (int x
= 0; x
< 64; x
++) {
629 if (shared_data
->dtb
[x
] != ULL(0xFFFFFFFFFFFFFFFF) ||
630 thread
->getDTBPtr()->TteRead(x
) != ULL(0xFFFFFFFFFFFFFFFF)) {
631 sprintf(label
, "D-TLB:%02d", x
);
632 printRegPair(outs
, label
, thread
->getDTBPtr()->TteRead(x
),
633 shared_data
->dtb
[x
]);
636 thread
->getITBPtr()->dumpAll();
637 thread
->getDTBPtr()->dumpAll();
642 fatal("Differences found between Legion and M5\n");
647 shared_data
->flags
= OWN_LEGION
;
656 vector
<bool> Trace::InstRecord::flags(NUM_BITS
);
657 string
Trace::InstRecord::trace_system
;
659 ////////////////////////////////////////////////////////////////////////
661 // Parameter space for per-cycle execution address tracing options.
662 // Derive from ParamContext so we can override checkParams() function.
664 class ExecutionTraceParamContext
: public ParamContext
667 ExecutionTraceParamContext(const string
&_iniSection
)
668 : ParamContext(_iniSection
)
672 void checkParams(); // defined at bottom of file
675 ExecutionTraceParamContext
exeTraceParams("exetrace");
677 Param
<bool> exe_trace_spec(&exeTraceParams
, "speculative",
678 "capture speculative instructions", true);
680 Param
<bool> exe_trace_print_cycle(&exeTraceParams
, "print_cycle",
681 "print cycle number", true);
682 Param
<bool> exe_trace_print_opclass(&exeTraceParams
, "print_opclass",
683 "print op class", true);
684 Param
<bool> exe_trace_print_thread(&exeTraceParams
, "print_thread",
685 "print thread number", true);
686 Param
<bool> exe_trace_print_effaddr(&exeTraceParams
, "print_effaddr",
687 "print effective address", true);
688 Param
<bool> exe_trace_print_data(&exeTraceParams
, "print_data",
689 "print result data", true);
690 Param
<bool> exe_trace_print_iregs(&exeTraceParams
, "print_iregs",
691 "print all integer regs", false);
692 Param
<bool> exe_trace_print_fetchseq(&exeTraceParams
, "print_fetchseq",
693 "print fetch sequence number", false);
694 Param
<bool> exe_trace_print_cp_seq(&exeTraceParams
, "print_cpseq",
695 "print correct-path sequence number", false);
696 Param
<bool> exe_trace_print_reg_delta(&exeTraceParams
, "print_reg_delta",
697 "print which registers changed to what", false);
698 Param
<bool> exe_trace_pc_symbol(&exeTraceParams
, "pc_symbol",
699 "Use symbols for the PC if available", true);
700 Param
<bool> exe_trace_intel_format(&exeTraceParams
, "intel_format",
701 "print trace in intel compatible format", false);
702 Param
<bool> exe_trace_legion_lockstep(&exeTraceParams
, "legion_lockstep",
703 "Compare sim state to legion state every cycle",
705 Param
<string
> exe_trace_system(&exeTraceParams
, "trace_system",
706 "print trace of which system (client or server)",
711 // Helper function for ExecutionTraceParamContext::checkParams() just
712 // to get us into the InstRecord namespace
715 Trace::InstRecord::setParams()
717 flags
[TRACE_MISSPEC
] = exe_trace_spec
;
719 flags
[PRINT_CYCLE
] = exe_trace_print_cycle
;
720 flags
[PRINT_OP_CLASS
] = exe_trace_print_opclass
;
721 flags
[PRINT_THREAD_NUM
] = exe_trace_print_thread
;
722 flags
[PRINT_RESULT_DATA
] = exe_trace_print_effaddr
;
723 flags
[PRINT_EFF_ADDR
] = exe_trace_print_data
;
724 flags
[PRINT_INT_REGS
] = exe_trace_print_iregs
;
725 flags
[PRINT_FETCH_SEQ
] = exe_trace_print_fetchseq
;
726 flags
[PRINT_CP_SEQ
] = exe_trace_print_cp_seq
;
727 flags
[PRINT_REG_DELTA
] = exe_trace_print_reg_delta
;
728 flags
[PC_SYMBOL
] = exe_trace_pc_symbol
;
729 flags
[INTEL_FORMAT
] = exe_trace_intel_format
;
730 flags
[LEGION_LOCKSTEP
] = exe_trace_legion_lockstep
;
731 trace_system
= exe_trace_system
;
733 // If were going to be in lockstep with Legion
734 // Setup shared memory, and get otherwise ready
735 if (flags
[LEGION_LOCKSTEP
]) {
736 int shmfd
= shmget('M' << 24 | getuid(), sizeof(SharedData
), 0777);
738 fatal("Couldn't get shared memory fd. Is Legion running?");
740 shared_data
= (SharedData
*)shmat(shmfd
, NULL
, SHM_RND
);
741 if (shared_data
== (SharedData
*)-1)
742 fatal("Couldn't allocate shared memory");
744 if (shared_data
->flags
!= OWN_M5
)
745 fatal("Shared memory has invalid owner");
747 if (shared_data
->version
!= VERSION
)
748 fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION
,
749 shared_data
->version
);
751 // step legion forward one cycle so we can get register values
752 shared_data
->flags
= OWN_LEGION
;
757 ExecutionTraceParamContext::checkParams()
759 Trace::InstRecord::setParams();