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