kvm, mem: Refactor some Event subclasses into lambdas
[gem5.git] / src / cpu / exetrace.cc
index 9b87f2e8ae61bcef074e4a1ecd4865a56b638fa5..bbde89c006b029971e4dfb19e871c2ea4b06ea4c 100644 (file)
  *          Steve Raasch
  */
 
-#include <errno.h>
-#include <fstream>
+#include "cpu/exetrace.hh"
+
 #include <iomanip>
-#include <sys/ipc.h>
-#include <sys/shm.h>
 
-#include "arch/predecoder.hh"
-#include "arch/regfile.hh"
+#include "arch/isa_traits.hh"
 #include "arch/utility.hh"
 #include "base/loader/symtab.hh"
-#include "base/socket.hh"
-#include "config/full_system.hh"
+#include "config/the_isa.hh"
 #include "cpu/base.hh"
-#include "cpu/exetrace.hh"
 #include "cpu/static_inst.hh"
-#include "sim/param.hh"
-#include "sim/system.hh"
-
-#if FULL_SYSTEM
-#include "arch/tlb.hh"
-#endif
-
-//XXX This is temporary
-#include "arch/isa_specific.hh"
-#include "cpu/m5legion_interface.h"
+#include "cpu/thread_context.hh"
+#include "debug/ExecAll.hh"
+#include "enums/OpClass.hh"
 
 using namespace std;
 using namespace TheISA;
 
-#if THE_ISA == SPARC_ISA && FULL_SYSTEM
-static int diffcount = 0;
-static bool wasMicro = false;
-#endif
-
 namespace Trace {
-SharedData *shared_data = NULL;
-ListenSocket *cosim_listener = NULL;
 
 void
-setupSharedData()
-{
-    int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
-    if (shmfd < 0)
-        fatal("Couldn't get shared memory fd. Is Legion running?");
-
-    shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
-    if (shared_data == (SharedData*)-1)
-        fatal("Couldn't allocate shared memory");
-
-    if (shared_data->flags != OWN_M5)
-        fatal("Shared memory has invalid owner");
-
-    if (shared_data->version != VERSION)
-        fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
-              shared_data->version);
-
-    // step legion forward one cycle so we can get register values
-    shared_data->flags = OWN_LEGION;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-//  Methods for the InstRecord object
-//
-
-#if THE_ISA == SPARC_ISA
-
-inline char * genCenteredLabel(int length, char * buffer, char * label)
+ExeTracerRecord::dumpTicks(ostream &outs)
 {
-    int labelLength = strlen(label);
-    assert(labelLength <= length);
-    int leftPad = (length - labelLength) / 2;
-    int rightPad = length - leftPad - labelLength;
-    char format[64];
-    sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad);
-    sprintf(buffer, format, "", label, "");
-    return buffer;
+    ccprintf(outs, "%7d: ", when);
 }
 
-inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b)
-{
-    ccprintf(os, "  %16s  |  %#018x   %s   %#-018x  \n",
-            title, a, (a == b) ? "|" : "X", b);
-}
-
-inline void printColumnLabels(ostream & os)
+void
+Trace::ExeTracerRecord::traceInst(const StaticInstPtr &inst, bool ran)
 {
-    static char * regLabel = genCenteredLabel(16, new char[17], "Register");
-    static char * m5Label = genCenteredLabel(18, new char[18], "M5");
-    static char * legionLabel = genCenteredLabel(18, new char[18], "Legion");
-    ccprintf(os, "  %s  |  %s   |   %s  \n", regLabel, m5Label, legionLabel);
-    ccprintf(os, "--------------------+-----------------------+-----------------------\n");
-}
+    ostream &outs = Trace::output();
 
-inline void printSectionHeader(ostream & os, char * name)
-{
-    char sectionString[70];
-    genCenteredLabel(69, sectionString, name);
-    ccprintf(os, "====================================================================\n");
-    ccprintf(os, "%69s\n", sectionString);
-    ccprintf(os, "====================================================================\n");
-}
+    if (!Debug::ExecUser || !Debug::ExecKernel) {
+        bool in_user_mode = TheISA::inUserMode(thread);
+        if (in_user_mode && !Debug::ExecUser) return;
+        if (!in_user_mode && !Debug::ExecKernel) return;
+    }
 
-inline void printLevelHeader(ostream & os, int level)
-{
-    char sectionString[70];
-    char levelName[70];
-    sprintf(levelName, "Trap stack level %d", level);
-    genCenteredLabel(69, sectionString, levelName);
-    ccprintf(os, "====================================================================\n");
-    ccprintf(os, "%69s\n", sectionString);
-    ccprintf(os, "====================================================================\n");
-}
+    if (Debug::ExecTicks)
+        dumpTicks(outs);
 
-#endif
+    outs << thread->getCpuPtr()->name() << " ";
 
-void
-Trace::InstRecord::dump()
-{
-    ostream &outs = Trace::output();
+    if (Debug::ExecAsid)
+        outs << "A" << dec << TheISA::getExecutingAsid(thread) << " ";
 
-    DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst);
-    bool diff = true;
-    if (IsOn(ExecRegDelta))
-    {
-        diff = false;
-#ifndef NDEBUG
-#if THE_ISA == SPARC_ISA
-        static int fd = 0;
-        //Don't print what happens for each micro-op, just print out
-        //once at the last op, and for regular instructions.
-        if(!staticInst->isMicroop() || staticInst->isLastMicroop())
-        {
-            if(!cosim_listener)
-            {
-                int port = 8000;
-                cosim_listener = new ListenSocket();
-                while(!cosim_listener->listen(port, true))
-                {
-                    DPRINTF(GDBMisc, "Can't bind port %d\n", port);
-                    port++;
-                }
-                ccprintf(cerr, "Listening for cosimulator on port %d\n", port);
-                fd = cosim_listener->accept();
-            }
-            char prefix[] = "goli";
-            for(int p = 0; p < 4; p++)
-            {
-                for(int i = 0; i < 8; i++)
-                {
-                    uint64_t regVal;
-                    int res = read(fd, &regVal, sizeof(regVal));
-                    if(res < 0)
-                        panic("First read call failed! %s\n", strerror(errno));
-                    regVal = TheISA::gtoh(regVal);
-                    uint64_t realRegVal = thread->readIntReg(p * 8 + i);
-                    if((regVal & 0xffffffffULL) != (realRegVal & 0xffffffffULL))
-                    {
-                        DPRINTF(ExecRegDelta, "Register %s%d should be %#x but is %#x.\n", prefix[p], i, regVal, realRegVal);
-                        diff = true;
-                    }
-                    //ccprintf(outs, "%s%d m5 = %#x statetrace = %#x\n", prefix[p], i, realRegVal, regVal);
-                }
-            }
-            /*for(int f = 0; f <= 62; f+=2)
-            {
-                uint64_t regVal;
-                int res = read(fd, &regVal, sizeof(regVal));
-                if(res < 0)
-                    panic("First read call failed! %s\n", strerror(errno));
-                regVal = TheISA::gtoh(regVal);
-                uint64_t realRegVal = thread->readFloatRegBits(f, 64);
-                if(regVal != realRegVal)
-                {
-                    DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
-                }
-            }*/
-            uint64_t regVal;
-            int res = read(fd, &regVal, sizeof(regVal));
-            if(res < 0)
-                panic("First read call failed! %s\n", strerror(errno));
-            regVal = TheISA::gtoh(regVal);
-            uint64_t realRegVal = thread->readNextPC();
-            if(regVal != realRegVal)
-            {
-                DPRINTF(ExecRegDelta, "Register pc should be %#x but is %#x.\n", regVal, realRegVal);
-                diff = true;
-            }
-            res = read(fd, &regVal, sizeof(regVal));
-            if(res < 0)
-                panic("First read call failed! %s\n", strerror(errno));
-            regVal = TheISA::gtoh(regVal);
-            realRegVal = thread->readNextNPC();
-            if(regVal != realRegVal)
-            {
-                DPRINTF(ExecRegDelta, "Register npc should be %#x but is %#x.\n", regVal, realRegVal);
-                diff = true;
-            }
-            res = read(fd, &regVal, sizeof(regVal));
-            if(res < 0)
-                panic("First read call failed! %s\n", strerror(errno));
-            regVal = TheISA::gtoh(regVal);
-            realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
-            if((regVal & 0xF) != (realRegVal & 0xF))
-            {
-                DPRINTF(ExecRegDelta, "Register ccr should be %#x but is %#x.\n", regVal, realRegVal);
-                diff = true;
-            }
-        }
-#endif
-#endif
-#if 0 //THE_ISA == SPARC_ISA
-        //Don't print what happens for each micro-op, just print out
-        //once at the last op, and for regular instructions.
-        if(!staticInst->isMicroop() || staticInst->isLastMicroop())
-        {
-            static uint64_t regs[32] = {
-                0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0, 0, 0, 0, 0};
-            static uint64_t ccr = 0;
-            static uint64_t y = 0;
-            static uint64_t floats[32];
-            uint64_t newVal;
-            static const char * prefixes[4] = {"G", "O", "L", "I"};
+    if (Debug::ExecThread)
+        outs << "T" << thread->threadId() << " : ";
 
-            outs << hex;
-            outs << "PC = " << thread->readNextPC();
-            outs << " NPC = " << thread->readNextNPC();
-            newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
-            //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_CCR);
-            if(newVal != ccr)
-            {
-                outs << " CCR = " << newVal;
-                ccr = newVal;
-            }
-            newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1);
-            //newVal = thread->readMiscRegNoEffect(SparcISA::MISCREG_Y);
-            if(newVal != y)
-            {
-                outs << " Y = " << newVal;
-                y = newVal;
-            }
-            for(int y = 0; y < 4; y++)
-            {
-                for(int x = 0; x < 8; x++)
-                {
-                    int index = x + 8 * y;
-                    newVal = thread->readIntReg(index);
-                    if(regs[index] != newVal)
-                    {
-                        outs << " " << prefixes[y] << dec << x << " = " << hex << newVal;
-                        regs[index] = newVal;
-                    }
-                }
-            }
-            for(int y = 0; y < 32; y++)
-            {
-                newVal = thread->readFloatRegBits(2 * y, 64);
-                if(floats[y] != newVal)
-                {
-                    outs << " F" << dec << (2 * y) << " = " << hex << newVal;
-                    floats[y] = newVal;
-                }
-            }
-            outs << dec << endl;
-        }
-#endif
+    std::string sym_str;
+    Addr sym_addr;
+    Addr cur_pc = pc.instAddr();
+    if (debugSymbolTable && Debug::ExecSymbol &&
+            (!FullSystem || !inUserMode(thread)) &&
+            debugSymbolTable->findNearestSymbol(cur_pc, sym_str, sym_addr)) {
+        if (cur_pc != sym_addr)
+            sym_str += csprintf("+%d",cur_pc - sym_addr);
+        outs << "@" << sym_str;
+    } else {
+        outs << "0x" << hex << cur_pc;
     }
-    if(!diff) {
-    } else if (IsOn(ExecIntel)) {
-        ccprintf(outs, "%7d ) ", when);
-        outs << "0x" << hex << PC << ":\t";
-        if (staticInst->isLoad()) {
-            ccprintf(outs, "<RD %#x>", addr);
-        } else if (staticInst->isStore()) {
-            ccprintf(outs, "<WR %#x>", addr);
-        }
-        outs << endl;
+
+    if (inst->isMicroop()) {
+        outs << "." << setw(2) << dec << pc.microPC();
     } else {
-        if (IsOn(ExecTicks))
-            ccprintf(outs, "%7d: ", when);
+        outs << "   ";
+    }
 
-        outs << thread->getCpuPtr()->name() << " ";
+    outs << " : ";
 
-        if (IsOn(ExecSpeculative))
-            outs << (misspeculating ? "-" : "+") << " ";
+    //
+    //  Print decoded instruction
+    //
 
-        if (IsOn(ExecThread))
-            outs << "T" << thread->getThreadNum() << " : ";
+    outs << setw(26) << left;
+    outs << inst->disassemble(cur_pc, debugSymbolTable);
 
+    if (ran) {
+        outs << " : ";
 
-        std::string sym_str;
-        Addr sym_addr;
-        if (debugSymbolTable
-            && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)
-            && IsOn(ExecSymbol)) {
-            if (PC != sym_addr)
-                sym_str += csprintf("+%d", PC - sym_addr);
-            outs << "@" << sym_str << " : ";
+        if (Debug::ExecOpClass) {
+            outs << Enums::OpClassStrings[inst->opClass()] << " : ";
         }
-        else {
-            outs << "0x" << hex << PC << " : ";
-        }
-
-        //
-        //  Print decoded instruction
-        //
-
-#if defined(__GNUC__) && (__GNUC__ < 3)
-        // There's a bug in gcc 2.x library that prevents setw()
-        // from working properly on strings
-        string mc(staticInst->disassemble(PC, debugSymbolTable));
-        while (mc.length() < 26)
-            mc += " ";
-        outs << mc;
-#else
-        outs << setw(26) << left << staticInst->disassemble(PC, debugSymbolTable);
-#endif
-
-        outs << " : ";
 
-        if (IsOn(ExecOpClass)) {
-            outs << opClassStrings[staticInst->opClass()] << " : ";
+        if (Debug::ExecResult && !predicate) {
+            outs << "Predicated False";
         }
 
-        if (IsOn(ExecResult) && data_status != DataInvalid) {
-            outs << " D=";
-#if 0
-            if (data_status == DataDouble)
-                ccprintf(outs, "%f", data.as_double);
-            else
-                ccprintf(outs, "%#018x", data.as_int);
-#else
-            ccprintf(outs, "%#018x", data.as_int);
-#endif
+        if (Debug::ExecResult && data_status != DataInvalid) {
+            ccprintf(outs, " D=%#018x", data.as_int);
         }
 
-        if (IsOn(ExecEffAddr) && addr_valid)
+        if (Debug::ExecEffAddr && getMemValid())
             outs << " A=0x" << hex << addr;
 
-        if (IsOn(ExecIntRegs) && regs_valid) {
-            for (int i = 0; i < TheISA::NumIntRegs;)
-                for (int j = i + 1; i <= j; i++)
-                    ccprintf(outs, "r%02d = %#018x%s", i,
-                            iregs->regs.readReg(i),
-                            ((i == j) ? "\n" : "    "));
-            outs << "\n";
-        }
-
-        if (IsOn(ExecFetchSeq) && fetch_seq_valid)
+        if (Debug::ExecFetchSeq && fetch_seq_valid)
             outs << "  FetchSeq=" << dec << fetch_seq;
 
-        if (IsOn(ExecCPSeq) && cp_seq_valid)
+        if (Debug::ExecCPSeq && cp_seq_valid)
             outs << "  CPSeq=" << dec << cp_seq;
 
-        //
-        //  End of line...
-        //
-        outs << endl;
-    }
-#if THE_ISA == SPARC_ISA && FULL_SYSTEM
-    static TheISA::Predecoder predecoder(NULL);
-    // Compare
-    if (IsOn(ExecLegion))
-    {
-        bool compared = false;
-        bool diffPC   = false;
-        bool diffCC   = false;
-        bool diffInst = false;
-        bool diffIntRegs = false;
-        bool diffFpRegs = false;
-        bool diffTpc = false;
-        bool diffTnpc = false;
-        bool diffTstate = false;
-        bool diffTt = false;
-        bool diffTba = false;
-        bool diffHpstate = false;
-        bool diffHtstate = false;
-        bool diffHtba = false;
-        bool diffPstate = false;
-        bool diffY = false;
-        bool diffFsr = false;
-        bool diffCcr = false;
-        bool diffTl = false;
-        bool diffGl = false;
-        bool diffAsi = false;
-        bool diffPil = false;
-        bool diffCwp = false;
-        bool diffCansave = false;
-        bool diffCanrestore = false;
-        bool diffOtherwin = false;
-        bool diffCleanwin = false;
-        bool diffTlb = false;
-        Addr m5Pc, lgnPc;
-
-        if (!shared_data)
-            setupSharedData();
-
-        // We took a trap on a micro-op...
-        if (wasMicro && !staticInst->isMicroop())
-        {
-            // let's skip comparing this tick
-            while (!compared)
-                if (shared_data->flags == OWN_M5) {
-                    shared_data->flags = OWN_LEGION;
-                    compared = true;
-                }
-            compared = false;
-            wasMicro = false;
+        if (Debug::ExecFlags) {
+            outs << "  flags=(";
+            inst->printFlags(outs, "|");
+            outs << ")";
         }
+    }
 
-        if (staticInst->isLastMicroop())
-            wasMicro = false;
-        else if (staticInst->isMicroop())
-            wasMicro = true;
-
-
-        if(!staticInst->isMicroop() || staticInst->isLastMicroop()) {
-            while (!compared) {
-                if (shared_data->flags == OWN_M5) {
-                    m5Pc = PC & TheISA::PAddrImplMask;
-                    if (bits(shared_data->pstate,3,3)) {
-                        m5Pc &= mask(32);
-                    }
-                    lgnPc = shared_data->pc & TheISA::PAddrImplMask;
-                    if (lgnPc != m5Pc)
-                       diffPC = true;
-
-                    if (shared_data->cycle_count !=
-                            thread->getCpuPtr()->instCount())
-                        diffCC = true;
-
-                    if (shared_data->instruction !=
-                            (SparcISA::MachInst)staticInst->machInst) {
-                        diffInst = true;
-                    }
-                    // assume we have %g0 working correctly
-                    for (int i = 1; i < TheISA::NumIntArchRegs; i++) {
-                        if (thread->readIntReg(i) != shared_data->intregs[i]) {
-                            diffIntRegs = true;
-                        }
-                    }
-                    for (int i = 0; i < TheISA::NumFloatRegs/2; i++) {
-                        if (thread->readFloatRegBits(i*2,FloatRegFile::DoubleWidth) != shared_data->fpregs[i]) {
-                            diffFpRegs = true;
-                        }
-                    }
-                            uint64_t oldTl = thread->readMiscRegNoEffect(MISCREG_TL);
-                    if (oldTl != shared_data->tl)
-                        diffTl = true;
-                    for (int i = 1; i <= MaxTL; i++) {
-                        thread->setMiscRegNoEffect(MISCREG_TL, i);
-                        if (thread->readMiscRegNoEffect(MISCREG_TPC) !=
-                                shared_data->tpc[i-1])
-                            diffTpc = true;
-                        if (thread->readMiscRegNoEffect(MISCREG_TNPC) !=
-                                shared_data->tnpc[i-1])
-                            diffTnpc = true;
-                        if (thread->readMiscRegNoEffect(MISCREG_TSTATE) !=
-                                shared_data->tstate[i-1])
-                            diffTstate = true;
-                        if (thread->readMiscRegNoEffect(MISCREG_TT) !=
-                                shared_data->tt[i-1])
-                            diffTt = true;
-                        if (thread->readMiscRegNoEffect(MISCREG_HTSTATE) !=
-                                shared_data->htstate[i-1])
-                            diffHtstate = true;
-                    }
-                    thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
-
-                    if(shared_data->tba != thread->readMiscRegNoEffect(MISCREG_TBA))
-                        diffTba = true;
-                    //When the hpstate register is read by an instruction,
-                    //legion has bit 11 set. When it's in storage, it doesn't.
-                    //Since we don't directly support seperate interpretations
-                    //of the registers like that, the bit is always set to 1 and
-                    //we just don't compare it. It's not supposed to matter
-                    //anyway.
-                    if((shared_data->hpstate | (1 << 11)) != thread->readMiscRegNoEffect(MISCREG_HPSTATE))
-                        diffHpstate = true;
-                    if(shared_data->htba != thread->readMiscRegNoEffect(MISCREG_HTBA))
-                        diffHtba = true;
-                    if(shared_data->pstate != thread->readMiscRegNoEffect(MISCREG_PSTATE))
-                        diffPstate = true;
-                    //if(shared_data->y != thread->readMiscRegNoEffect(MISCREG_Y))
-                    if(shared_data->y !=
-                            thread->readIntReg(NumIntArchRegs + 1))
-                        diffY = true;
-                    if(shared_data->fsr != thread->readMiscRegNoEffect(MISCREG_FSR)) {
-                        diffFsr = true;
-                        if (mbits(shared_data->fsr, 63,10) ==
-                                mbits(thread->readMiscRegNoEffect(MISCREG_FSR), 63,10)) {
-                            thread->setMiscRegNoEffect(MISCREG_FSR, shared_data->fsr);
-                            diffFsr = false;
-                        }
-                    }
-                    //if(shared_data->ccr != thread->readMiscRegNoEffect(MISCREG_CCR))
-                    if(shared_data->ccr !=
-                            thread->readIntReg(NumIntArchRegs + 2))
-                        diffCcr = true;
-                    if(shared_data->gl != thread->readMiscRegNoEffect(MISCREG_GL))
-                        diffGl = true;
-                    if(shared_data->asi != thread->readMiscRegNoEffect(MISCREG_ASI))
-                        diffAsi = true;
-                    if(shared_data->pil != thread->readMiscRegNoEffect(MISCREG_PIL))
-                        diffPil = true;
-                    if(shared_data->cwp != thread->readMiscRegNoEffect(MISCREG_CWP))
-                        diffCwp = true;
-                    //if(shared_data->cansave != thread->readMiscRegNoEffect(MISCREG_CANSAVE))
-                    if(shared_data->cansave !=
-                            thread->readIntReg(NumIntArchRegs + 3))
-                        diffCansave = true;
-                    //if(shared_data->canrestore !=
-                    //     thread->readMiscRegNoEffect(MISCREG_CANRESTORE))
-                    if(shared_data->canrestore !=
-                            thread->readIntReg(NumIntArchRegs + 4))
-                        diffCanrestore = true;
-                    //if(shared_data->otherwin != thread->readMiscRegNoEffect(MISCREG_OTHERWIN))
-                    if(shared_data->otherwin !=
-                            thread->readIntReg(NumIntArchRegs + 6))
-                        diffOtherwin = true;
-                    //if(shared_data->cleanwin != thread->readMiscRegNoEffect(MISCREG_CLEANWIN))
-                    if(shared_data->cleanwin !=
-                            thread->readIntReg(NumIntArchRegs + 5))
-                        diffCleanwin = true;
-
-                    for (int i = 0; i < 64; i++) {
-                        if (shared_data->itb[i] !=  thread->getITBPtr()->TteRead(i))
-                                diffTlb = true;
-                        if (shared_data->dtb[i] !=  thread->getDTBPtr()->TteRead(i))
-                                diffTlb = true;
-                    }
-
-                    if (diffPC || diffCC || diffInst || diffIntRegs ||
-                         diffFpRegs || diffTpc || diffTnpc || diffTstate ||
-                         diffTt || diffHpstate || diffHtstate || diffHtba ||
-                         diffPstate || diffY || diffCcr || diffTl || diffFsr ||
-                         diffGl || diffAsi || diffPil || diffCwp || diffCansave ||
-                         diffCanrestore || diffOtherwin || diffCleanwin || diffTlb)
-                       {
-
-                        outs << "Differences found between M5 and Legion:";
-                        if (diffPC)
-                            outs << " [PC]";
-                        if (diffCC)
-                            outs << " [CC]";
-                        if (diffInst)
-                            outs << " [Instruction]";
-                        if (diffIntRegs)
-                            outs << " [IntRegs]";
-                        if (diffFpRegs)
-                            outs << " [FpRegs]";
-                        if (diffTpc)
-                            outs << " [Tpc]";
-                        if (diffTnpc)
-                            outs << " [Tnpc]";
-                        if (diffTstate)
-                            outs << " [Tstate]";
-                        if (diffTt)
-                            outs << " [Tt]";
-                        if (diffHpstate)
-                            outs << " [Hpstate]";
-                        if (diffHtstate)
-                            outs << " [Htstate]";
-                        if (diffHtba)
-                            outs << " [Htba]";
-                        if (diffPstate)
-                            outs << " [Pstate]";
-                        if (diffY)
-                            outs << " [Y]";
-                        if (diffFsr)
-                            outs << " [FSR]";
-                        if (diffCcr)
-                            outs << " [Ccr]";
-                        if (diffTl)
-                            outs << " [Tl]";
-                        if (diffGl)
-                            outs << " [Gl]";
-                        if (diffAsi)
-                            outs << " [Asi]";
-                        if (diffPil)
-                            outs << " [Pil]";
-                        if (diffCwp)
-                            outs << " [Cwp]";
-                        if (diffCansave)
-                            outs << " [Cansave]";
-                        if (diffCanrestore)
-                            outs << " [Canrestore]";
-                        if (diffOtherwin)
-                            outs << " [Otherwin]";
-                        if (diffCleanwin)
-                            outs << " [Cleanwin]";
-                        if (diffTlb)
-                            outs << " [Tlb]";
-                        outs << endl << endl;
-
-                        outs << right << setfill(' ') << setw(15)
-                             << "M5 PC: " << "0x"<< setw(16) << setfill('0')
-                             << hex << m5Pc << endl;
-                        outs << setfill(' ') << setw(15)
-                             << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex
-                             << lgnPc << endl << endl;
-
-                        outs << right << setfill(' ') << setw(15)
-                             << "M5 CC: " << "0x"<< setw(16) << setfill('0')
-                             << hex << thread->getCpuPtr()->instCount() << endl;
-                        outs << setfill(' ') << setw(15)
-                             << "Legion CC: " << "0x"<< setw(16) << setfill('0') << hex
-                             << shared_data->cycle_count << endl << endl;
-
-                        outs << setfill(' ') << setw(15)
-                             << "M5 Inst: "  << "0x"<< setw(8)
-                             << setfill('0') << hex << staticInst->machInst
-                             << staticInst->disassemble(m5Pc, debugSymbolTable)
-                             << endl;
-
-                        predecoder.setTC(thread);
-                        predecoder.moreBytes(m5Pc, m5Pc, 0,
-                                shared_data->instruction);
-
-                        assert(predecoder.extMachInstReady());
-
-                        StaticInstPtr legionInst =
-                            StaticInst::decode(predecoder.getExtMachInst(), lgnPc);
-                        outs << setfill(' ') << setw(15)
-                             << " Legion Inst: "
-                             << "0x" << setw(8) << setfill('0') << hex
-                             << shared_data->instruction
-                             << legionInst->disassemble(lgnPc, debugSymbolTable)
-                             << endl << endl;
-
-                        printSectionHeader(outs, "General State");
-                        printColumnLabels(outs);
-                        printRegPair(outs, "HPstate",
-                                thread->readMiscRegNoEffect(MISCREG_HPSTATE),
-                                shared_data->hpstate | (1 << 11));
-                        printRegPair(outs, "Htba",
-                                thread->readMiscRegNoEffect(MISCREG_HTBA),
-                                shared_data->htba);
-                        printRegPair(outs, "Pstate",
-                                thread->readMiscRegNoEffect(MISCREG_PSTATE),
-                                shared_data->pstate);
-                        printRegPair(outs, "Y",
-                                //thread->readMiscRegNoEffect(MISCREG_Y),
-                                thread->readIntReg(NumIntArchRegs + 1),
-                                shared_data->y);
-                        printRegPair(outs, "FSR",
-                                thread->readMiscRegNoEffect(MISCREG_FSR),
-                                shared_data->fsr);
-                        printRegPair(outs, "Ccr",
-                                //thread->readMiscRegNoEffect(MISCREG_CCR),
-                                thread->readIntReg(NumIntArchRegs + 2),
-                                shared_data->ccr);
-                        printRegPair(outs, "Tl",
-                                thread->readMiscRegNoEffect(MISCREG_TL),
-                                shared_data->tl);
-                        printRegPair(outs, "Gl",
-                                thread->readMiscRegNoEffect(MISCREG_GL),
-                                shared_data->gl);
-                        printRegPair(outs, "Asi",
-                                thread->readMiscRegNoEffect(MISCREG_ASI),
-                                shared_data->asi);
-                        printRegPair(outs, "Pil",
-                                thread->readMiscRegNoEffect(MISCREG_PIL),
-                                shared_data->pil);
-                        printRegPair(outs, "Cwp",
-                                thread->readMiscRegNoEffect(MISCREG_CWP),
-                                shared_data->cwp);
-                        printRegPair(outs, "Cansave",
-                                //thread->readMiscRegNoEffect(MISCREG_CANSAVE),
-                                thread->readIntReg(NumIntArchRegs + 3),
-                                shared_data->cansave);
-                        printRegPair(outs, "Canrestore",
-                                //thread->readMiscRegNoEffect(MISCREG_CANRESTORE),
-                                thread->readIntReg(NumIntArchRegs + 4),
-                                shared_data->canrestore);
-                        printRegPair(outs, "Otherwin",
-                                //thread->readMiscRegNoEffect(MISCREG_OTHERWIN),
-                                thread->readIntReg(NumIntArchRegs + 6),
-                                shared_data->otherwin);
-                        printRegPair(outs, "Cleanwin",
-                                //thread->readMiscRegNoEffect(MISCREG_CLEANWIN),
-                                thread->readIntReg(NumIntArchRegs + 5),
-                                shared_data->cleanwin);
-                        outs << endl;
-                        for (int i = 1; i <= MaxTL; i++) {
-                            printLevelHeader(outs, i);
-                            printColumnLabels(outs);
-                            thread->setMiscRegNoEffect(MISCREG_TL, i);
-                            printRegPair(outs, "Tpc",
-                                    thread->readMiscRegNoEffect(MISCREG_TPC),
-                                    shared_data->tpc[i-1]);
-                            printRegPair(outs, "Tnpc",
-                                    thread->readMiscRegNoEffect(MISCREG_TNPC),
-                                    shared_data->tnpc[i-1]);
-                            printRegPair(outs, "Tstate",
-                                    thread->readMiscRegNoEffect(MISCREG_TSTATE),
-                                    shared_data->tstate[i-1]);
-                            printRegPair(outs, "Tt",
-                                    thread->readMiscRegNoEffect(MISCREG_TT),
-                                    shared_data->tt[i-1]);
-                            printRegPair(outs, "Htstate",
-                                    thread->readMiscRegNoEffect(MISCREG_HTSTATE),
-                                    shared_data->htstate[i-1]);
-                        }
-                        thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
-                        outs << endl;
-
-                        printSectionHeader(outs, "General Purpose Registers");
-                        static const char * regtypes[4] = {"%g", "%o", "%l", "%i"};
-                        for(int y = 0; y < 4; y++) {
-                            for(int x = 0; x < 8; x++) {
-                                char label[8];
-                                sprintf(label, "%s%d", regtypes[y], x);
-                                printRegPair(outs, label,
-                                        thread->readIntReg(y*8+x),
-                                        shared_data->intregs[y*8+x]);
-                            }
-                        }
-                        if (diffFpRegs) {
-                            for (int x = 0; x < 32; x++) {
-                                char label[8];
-                                sprintf(label, "%%f%d", x);
-                                printRegPair(outs, label,
-                                 thread->readFloatRegBits(x*2,FloatRegFile::DoubleWidth),
-                                 shared_data->fpregs[x]);
-                            }
-                        }
-                        if (diffTlb) {
-                            printColumnLabels(outs);
-                            char label[8];
-                            for (int x = 0; x < 64; x++) {
-                                if (shared_data->itb[x] !=  ULL(0xFFFFFFFFFFFFFFFF) ||
-                                    thread->getITBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF))  {
-                                        sprintf(label, "I-TLB:%02d", x);
-                                        printRegPair(outs, label, thread->getITBPtr()->TteRead(x),
-                                                shared_data->itb[x]);
-                                }
-                            }
-                            for (int x = 0; x < 64; x++) {
-                                if (shared_data->dtb[x] !=  ULL(0xFFFFFFFFFFFFFFFF) ||
-                                    thread->getDTBPtr()->TteRead(x) != ULL(0xFFFFFFFFFFFFFFFF))  {
-                                        sprintf(label, "D-TLB:%02d", x);
-                                        printRegPair(outs, label, thread->getDTBPtr()->TteRead(x),
-                                                shared_data->dtb[x]);
-                                }
-                            }
-                            thread->getITBPtr()->dumpAll();
-                            thread->getDTBPtr()->dumpAll();
-                        }
-
-                        diffcount++;
-                        if (diffcount > 3)
-                            fatal("Differences found between Legion and M5\n");
-                    } else
-                        diffcount = 0;
+    //
+    //  End of line...
+    //
+    outs << endl;
+}
 
-                    compared = true;
-                    shared_data->flags = OWN_LEGION;
-                }
-            } // while
-        } // if not microop
+void
+Trace::ExeTracerRecord::dump()
+{
+    /*
+     * The behavior this check tries to achieve is that if ExecMacro is on,
+     * the macroop will be printed. If it's on and microops are also on, it's
+     * printed before the microops start printing to give context. If the
+     * microops aren't printed, then it's printed only when the final microop
+     * finishes. Macroops then behave like regular instructions and don't
+     * complete/print when they fault.
+     */
+    if (Debug::ExecMacro && staticInst->isMicroop() &&
+        ((Debug::ExecMicro &&
+            macroStaticInst && staticInst->isFirstMicroop()) ||
+            (!Debug::ExecMicro &&
+             macroStaticInst && staticInst->isLastMicroop()))) {
+        traceInst(macroStaticInst, false);
+    }
+    if (Debug::ExecMicro || !staticInst->isMicroop()) {
+        traceInst(staticInst, true);
     }
-#endif
 }
 
-/* namespace Trace */ }
+} // namespace Trace
+
+////////////////////////////////////////////////////////////////////////
+//
+//  ExeTracer Simulation Object
+//
+Trace::ExeTracer *
+ExeTracerParams::create()
+{
+    return new Trace::ExeTracer(this);
+}