exetrace.cc revision 4572:5499df089a6c
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, m5Pc, 0,
654                                shared_data->instruction);
655
656                        assert(predecoder.extMachInstReady());
657
658                        StaticInstPtr legionInst =
659                            StaticInst::decode(predecoder.getExtMachInst(), lgnPc);
660                        outs << setfill(' ') << setw(15)
661                             << " Legion Inst: "
662                             << "0x" << setw(8) << setfill('0') << hex
663                             << shared_data->instruction
664                             << legionInst->disassemble(lgnPc, debugSymbolTable)
665                             << endl << endl;
666
667                        printSectionHeader(outs, "General State");
668                        printColumnLabels(outs);
669                        printRegPair(outs, "HPstate",
670                                thread->readMiscRegNoEffect(MISCREG_HPSTATE),
671                                shared_data->hpstate | (1 << 11));
672                        printRegPair(outs, "Htba",
673                                thread->readMiscRegNoEffect(MISCREG_HTBA),
674                                shared_data->htba);
675                        printRegPair(outs, "Pstate",
676                                thread->readMiscRegNoEffect(MISCREG_PSTATE),
677                                shared_data->pstate);
678                        printRegPair(outs, "Y",
679                                //thread->readMiscRegNoEffect(MISCREG_Y),
680                                thread->readIntReg(NumIntArchRegs + 1),
681                                shared_data->y);
682                        printRegPair(outs, "FSR",
683                                thread->readMiscRegNoEffect(MISCREG_FSR),
684                                shared_data->fsr);
685                        printRegPair(outs, "Ccr",
686                                //thread->readMiscRegNoEffect(MISCREG_CCR),
687                                thread->readIntReg(NumIntArchRegs + 2),
688                                shared_data->ccr);
689                        printRegPair(outs, "Tl",
690                                thread->readMiscRegNoEffect(MISCREG_TL),
691                                shared_data->tl);
692                        printRegPair(outs, "Gl",
693                                thread->readMiscRegNoEffect(MISCREG_GL),
694                                shared_data->gl);
695                        printRegPair(outs, "Asi",
696                                thread->readMiscRegNoEffect(MISCREG_ASI),
697                                shared_data->asi);
698                        printRegPair(outs, "Pil",
699                                thread->readMiscRegNoEffect(MISCREG_PIL),
700                                shared_data->pil);
701                        printRegPair(outs, "Cwp",
702                                thread->readMiscRegNoEffect(MISCREG_CWP),
703                                shared_data->cwp);
704                        printRegPair(outs, "Cansave",
705                                //thread->readMiscRegNoEffect(MISCREG_CANSAVE),
706                                thread->readIntReg(NumIntArchRegs + 3),
707                                shared_data->cansave);
708                        printRegPair(outs, "Canrestore",
709                                //thread->readMiscRegNoEffect(MISCREG_CANRESTORE),
710                                thread->readIntReg(NumIntArchRegs + 4),
711                                shared_data->canrestore);
712                        printRegPair(outs, "Otherwin",
713                                //thread->readMiscRegNoEffect(MISCREG_OTHERWIN),
714                                thread->readIntReg(NumIntArchRegs + 6),
715                                shared_data->otherwin);
716                        printRegPair(outs, "Cleanwin",
717                                //thread->readMiscRegNoEffect(MISCREG_CLEANWIN),
718                                thread->readIntReg(NumIntArchRegs + 5),
719                                shared_data->cleanwin);
720                        outs << endl;
721                        for (int i = 1; i <= MaxTL; i++) {
722                            printLevelHeader(outs, i);
723                            printColumnLabels(outs);
724                            thread->setMiscRegNoEffect(MISCREG_TL, i);
725                            printRegPair(outs, "Tpc",
726                                    thread->readMiscRegNoEffect(MISCREG_TPC),
727                                    shared_data->tpc[i-1]);
728                            printRegPair(outs, "Tnpc",
729                                    thread->readMiscRegNoEffect(MISCREG_TNPC),
730                                    shared_data->tnpc[i-1]);
731                            printRegPair(outs, "Tstate",
732                                    thread->readMiscRegNoEffect(MISCREG_TSTATE),
733                                    shared_data->tstate[i-1]);
734                            printRegPair(outs, "Tt",
735                                    thread->readMiscRegNoEffect(MISCREG_TT),
736                                    shared_data->tt[i-1]);
737                            printRegPair(outs, "Htstate",
738                                    thread->readMiscRegNoEffect(MISCREG_HTSTATE),
739                                    shared_data->htstate[i-1]);
740                        }
741                        thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
742                        outs << endl;
743
744                        printSectionHeader(outs, "General Purpose Registers");
745                        static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
746                        for(int y = 0; y < 4; y++) {
747                            for(int x = 0; x < 8; x++) {
748                                char label[8];
749                                sprintf(label, "%s%d", regtypes[y], x);
750                                printRegPair(outs, label,
751                                        thread->readIntReg(y*8+x),
752                                        shared_data->intregs[y*8+x]);
753                            }
754                        }
755                        if (diffFpRegs) {
756                            for (int x = 0; x < 32; x++) {
757                                char label[8];
758                                sprintf(label, "%%f%d", x);
759                                printRegPair(outs, label,
760                                 thread->readFloatRegBits(x*2,FloatRegFile::DoubleWidth),
761                                 shared_data->fpregs[x]);
762                            }
763                        }
764                        if (diffTlb) {
765                            printColumnLabels(outs);
766                            char label[8];
767                            for (int x = 0; x < 64; x++) {
768                                if (shared_data->itb[x] !=  ULL(0xFFFFFFFFFFFFFFFF) ||
769                                    thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF))  {
770                                        sprintf(label, "I-TLB:%02d", x);
771                                        printRegPair(outs, label, thread->getITBPtr()->TteRead(x),
772                                                shared_data->itb[x]);
773                                }
774                            }
775                            for (int x = 0; x < 64; x++) {
776                                if (shared_data->dtb[x] !=  ULL(0xFFFFFFFFFFFFFFFF) ||
777                                    thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF))  {
778                                        sprintf(label, "D-TLB:%02d", x);
779                                        printRegPair(outs, label, thread->getDTBPtr()->TteRead(x),
780                                                shared_data->dtb[x]);
781                                }
782                            }
783                            thread->getITBPtr()->dumpAll();
784                            thread->getDTBPtr()->dumpAll();
785                        }
786
787                        diffcount++;
788                        if (diffcount > 3)
789                            fatal("Differences found between Legion and M5\n");
790                    } else
791                        diffcount = 0;
792
793                    compared = true;
794                    shared_data->flags = OWN_LEGION;
795                }
796            } // while
797        } // if not microop
798    }
799#endif
800}
801
802/* namespace Trace */ }
803