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