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