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