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