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