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