kvm, mem: Refactor some Event subclasses into lambdas
[gem5.git] / src / cpu / exetrace.cc
index e34ae3731773b1531972ee41052803adb9027b36..bbde89c006b029971e4dfb19e871c2ea4b06ea4c 100644 (file)
  *          Steve Raasch
  */
 
-#include <fstream>
+#include "cpu/exetrace.hh"
+
 #include <iomanip>
-#include <sys/ipc.h>
-#include <sys/shm.h>
 
-#include "arch/regfile.hh"
+#include "arch/isa_traits.hh"
 #include "arch/utility.hh"
 #include "base/loader/symtab.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;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-//  Methods for the InstRecord object
-//
 
-#if THE_ISA == SPARC_ISA
-
-inline char * genCenteredLabel(int length, char * buffer, char * label)
+void
+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)
+void
+Trace::ExeTracerRecord::traceInst(const StaticInstPtr &inst, bool ran)
 {
-    ccprintf(os, "  %16s  |  %#018x   %s   %#-018x  \n",
-            title, a, (a == b) ? "|" : "X", b);
-}
+    ostream &outs = Trace::output();
 
-inline void printColumnLabels(ostream & os)
-{
-    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");
-}
+    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 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::ExecTicks)
+        dumpTicks(outs);
 
-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");
-}
+    outs << thread->getCpuPtr()->name() << " ";
 
-#endif
+    if (Debug::ExecAsid)
+        outs << "A" << dec << TheISA::getExecutingAsid(thread) << " ";
 
-void
-Trace::InstRecord::dump(ostream &outs)
-{
-    DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst);
-    if (flags[PRINT_REG_DELTA])
-    {
-#if 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->readMiscReg(SparcISA::MISCREG_CCR);
-            if(newVal != ccr)
-            {
-                outs << " CCR = " << newVal;
-                ccr = newVal;
-            }
-            newVal = thread->readIntReg(SparcISA::NumIntArchRegs + 1);
-            //newVal = thread->readMiscReg(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;
     }
-    else if (flags[INTEL_FORMAT]) {
-#if FULL_SYSTEM
-        bool is_trace_system = (thread->getCpuPtr()->system->name() == trace_system);
-#else
-        bool is_trace_system = true;
-#endif
-        if (is_trace_system) {
-            ccprintf(outs, "%7d ) ", cycle);
-            outs << "0x" << hex << PC << ":\t";
-            if (staticInst->isLoad()) {
-                outs << "<RD 0x" << hex << addr;
-                outs << ">";
-            } else if (staticInst->isStore()) {
-                outs << "<WR 0x" << hex << addr;
-                outs << ">";
-            }
-            outs << endl;
-        }
+
+    if (inst->isMicroop()) {
+        outs << "." << setw(2) << dec << pc.microPC();
     } else {
-        if (flags[PRINT_CYCLE])
-            ccprintf(outs, "%7d: ", cycle);
+        outs << "   ";
+    }
 
-        outs << thread->getCpuPtr()->name() << " ";
+    outs << " : ";
 
-        if (flags[TRACE_MISSPEC])
-            outs << (misspeculating ? "-" : "+") << " ";
+    //
+    //  Print decoded instruction
+    //
 
-        if (flags[PRINT_THREAD_NUM])
-            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)
-            && flags[PC_SYMBOL]) {
-            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 (flags[PRINT_OP_CLASS]) {
-            outs << opClassStrings[staticInst->opClass()] << " : ";
+        if (Debug::ExecResult && !predicate) {
+            outs << "Predicated False";
         }
 
-        if (flags[PRINT_RESULT_DATA] && 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 (flags[PRINT_EFF_ADDR] && addr_valid)
+        if (Debug::ExecEffAddr && getMemValid())
             outs << " A=0x" << hex << addr;
 
-        if (flags[PRINT_INT_REGS] && 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 (flags[PRINT_FETCH_SEQ] && fetch_seq_valid)
+        if (Debug::ExecFetchSeq && fetch_seq_valid)
             outs << "  FetchSeq=" << dec << fetch_seq;
 
-        if (flags[PRINT_CP_SEQ] && 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
-    // Compare
-    if (flags[LEGION_LOCKSTEP])
-    {
-        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;
-
-        // We took a trap on a micro-op...
-        if (wasMicro && !staticInst->isMicroOp())
-        {
-            // let's skip comparing this cycle
-            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->readMiscReg(MISCREG_TL);
-                    if (oldTl != shared_data->tl)
-                        diffTl = true;
-                    for (int i = 1; i <= MaxTL; i++) {
-                        thread->setMiscReg(MISCREG_TL, i);
-                        if (thread->readMiscReg(MISCREG_TPC) !=
-                                shared_data->tpc[i-1])
-                            diffTpc = true;
-                        if (thread->readMiscReg(MISCREG_TNPC) !=
-                                shared_data->tnpc[i-1])
-                            diffTnpc = true;
-                        if (thread->readMiscReg(MISCREG_TSTATE) !=
-                                shared_data->tstate[i-1])
-                            diffTstate = true;
-                        if (thread->readMiscReg(MISCREG_TT) !=
-                                shared_data->tt[i-1])
-                            diffTt = true;
-                        if (thread->readMiscReg(MISCREG_HTSTATE) !=
-                                shared_data->htstate[i-1])
-                            diffHtstate = true;
-                    }
-                    thread->setMiscReg(MISCREG_TL, oldTl);
-
-                    if(shared_data->tba != thread->readMiscReg(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->readMiscReg(MISCREG_HPSTATE))
-                        diffHpstate = true;
-                    if(shared_data->htba != thread->readMiscReg(MISCREG_HTBA))
-                        diffHtba = true;
-                    if(shared_data->pstate != thread->readMiscReg(MISCREG_PSTATE))
-                        diffPstate = true;
-                    //if(shared_data->y != thread->readMiscReg(MISCREG_Y))
-                    if(shared_data->y !=
-                            thread->readIntReg(NumIntArchRegs + 1))
-                        diffY = true;
-                    if(shared_data->fsr != thread->readMiscReg(MISCREG_FSR))
-                        diffFsr = true;
-                    //if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
-                    if(shared_data->ccr !=
-                            thread->readIntReg(NumIntArchRegs + 2))
-                        diffCcr = true;
-                    if(shared_data->gl != thread->readMiscReg(MISCREG_GL))
-                        diffGl = true;
-                    if(shared_data->asi != thread->readMiscReg(MISCREG_ASI))
-                        diffAsi = true;
-                    if(shared_data->pil != thread->readMiscReg(MISCREG_PIL))
-                        diffPil = true;
-                    if(shared_data->cwp != thread->readMiscReg(MISCREG_CWP))
-                        diffCwp = true;
-                    //if(shared_data->cansave != thread->readMiscReg(MISCREG_CANSAVE))
-                    if(shared_data->cansave !=
-                            thread->readIntReg(NumIntArchRegs + 3))
-                        diffCansave = true;
-                    //if(shared_data->canrestore !=
-                    //     thread->readMiscReg(MISCREG_CANRESTORE))
-                    if(shared_data->canrestore !=
-                            thread->readIntReg(NumIntArchRegs + 4))
-                        diffCanrestore = true;
-                    //if(shared_data->otherwin != thread->readMiscReg(MISCREG_OTHERWIN))
-                    if(shared_data->otherwin !=
-                            thread->readIntReg(NumIntArchRegs + 6))
-                        diffOtherwin = true;
-                    //if(shared_data->cleanwin != thread->readMiscReg(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)
-                        && !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
-                        && !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
-                            && shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
-                       ) {
-
-                        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;
-
-                        StaticInstPtr legionInst =
-                            StaticInst::decode(makeExtMI(shared_data->instruction,
-                                        thread));
-                        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->readMiscReg(MISCREG_HPSTATE),
-                                shared_data->hpstate | (1 << 11));
-                        printRegPair(outs, "Htba",
-                                thread->readMiscReg(MISCREG_HTBA),
-                                shared_data->htba);
-                        printRegPair(outs, "Pstate",
-                                thread->readMiscReg(MISCREG_PSTATE),
-                                shared_data->pstate);
-                        printRegPair(outs, "Y",
-                                //thread->readMiscReg(MISCREG_Y),
-                                thread->readIntReg(NumIntArchRegs + 1),
-                                shared_data->y);
-                        printRegPair(outs, "FSR",
-                                thread->readMiscReg(MISCREG_FSR),
-                                shared_data->fsr);
-                        printRegPair(outs, "Ccr",
-                                //thread->readMiscReg(MISCREG_CCR),
-                                thread->readIntReg(NumIntArchRegs + 2),
-                                shared_data->ccr);
-                        printRegPair(outs, "Tl",
-                                thread->readMiscReg(MISCREG_TL),
-                                shared_data->tl);
-                        printRegPair(outs, "Gl",
-                                thread->readMiscReg(MISCREG_GL),
-                                shared_data->gl);
-                        printRegPair(outs, "Asi",
-                                thread->readMiscReg(MISCREG_ASI),
-                                shared_data->asi);
-                        printRegPair(outs, "Pil",
-                                thread->readMiscReg(MISCREG_PIL),
-                                shared_data->pil);
-                        printRegPair(outs, "Cwp",
-                                thread->readMiscReg(MISCREG_CWP),
-                                shared_data->cwp);
-                        printRegPair(outs, "Cansave",
-                                //thread->readMiscReg(MISCREG_CANSAVE),
-                                thread->readIntReg(NumIntArchRegs + 3),
-                                shared_data->cansave);
-                        printRegPair(outs, "Canrestore",
-                                //thread->readMiscReg(MISCREG_CANRESTORE),
-                                thread->readIntReg(NumIntArchRegs + 4),
-                                shared_data->canrestore);
-                        printRegPair(outs, "Otherwin",
-                                //thread->readMiscReg(MISCREG_OTHERWIN),
-                                thread->readIntReg(NumIntArchRegs + 6),
-                                shared_data->otherwin);
-                        printRegPair(outs, "Cleanwin",
-                                //thread->readMiscReg(MISCREG_CLEANWIN),
-                                thread->readIntReg(NumIntArchRegs + 5),
-                                shared_data->cleanwin);
-                        outs << endl;
-                        for (int i = 1; i <= MaxTL; i++) {
-                            printLevelHeader(outs, i);
-                            printColumnLabels(outs);
-                            thread->setMiscReg(MISCREG_TL, i);
-                            printRegPair(outs, "Tpc",
-                                    thread->readMiscReg(MISCREG_TPC),
-                                    shared_data->tpc[i-1]);
-                            printRegPair(outs, "Tnpc",
-                                    thread->readMiscReg(MISCREG_TNPC),
-                                    shared_data->tnpc[i-1]);
-                            printRegPair(outs, "Tstate",
-                                    thread->readMiscReg(MISCREG_TSTATE),
-                                    shared_data->tstate[i-1]);
-                            printRegPair(outs, "Tt",
-                                    thread->readMiscReg(MISCREG_TT),
-                                    shared_data->tt[i-1]);
-                            printRegPair(outs, "Htstate",
-                                    thread->readMiscReg(MISCREG_HTSTATE),
-                                    shared_data->htstate[i-1]);
-                        }
-                        thread->setMiscReg(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,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 > 2)
-                            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
 }
 
-
-vector<bool> Trace::InstRecord::flags(NUM_BITS);
-string Trace::InstRecord::trace_system;
+} // namespace Trace
 
 ////////////////////////////////////////////////////////////////////////
 //
-// Parameter space for per-cycle execution address tracing options.
-// Derive from ParamContext so we can override checkParams() function.
+//  ExeTracer Simulation Object
 //
-class ExecutionTraceParamContext : public ParamContext
+Trace::ExeTracer *
+ExeTracerParams::create()
 {
-  public:
-    ExecutionTraceParamContext(const string &_iniSection)
-        : ParamContext(_iniSection)
-        {
-        }
-
-    void checkParams();        // defined at bottom of file
-};
-
-ExecutionTraceParamContext exeTraceParams("exetrace");
-
-Param<bool> exe_trace_spec(&exeTraceParams, "speculative",
-                           "capture speculative instructions", true);
-
-Param<bool> exe_trace_print_cycle(&exeTraceParams, "print_cycle",
-                                  "print cycle number", true);
-Param<bool> exe_trace_print_opclass(&exeTraceParams, "print_opclass",
-                                  "print op class", true);
-Param<bool> exe_trace_print_thread(&exeTraceParams, "print_thread",
-                                  "print thread number", true);
-Param<bool> exe_trace_print_effaddr(&exeTraceParams, "print_effaddr",
-                                  "print effective address", true);
-Param<bool> exe_trace_print_data(&exeTraceParams, "print_data",
-                                  "print result data", true);
-Param<bool> exe_trace_print_iregs(&exeTraceParams, "print_iregs",
-                                  "print all integer regs", false);
-Param<bool> exe_trace_print_fetchseq(&exeTraceParams, "print_fetchseq",
-                                  "print fetch sequence number", false);
-Param<bool> exe_trace_print_cp_seq(&exeTraceParams, "print_cpseq",
-                                  "print correct-path sequence number", false);
-Param<bool> exe_trace_print_reg_delta(&exeTraceParams, "print_reg_delta",
-                                  "print which registers changed to what", false);
-Param<bool> exe_trace_pc_symbol(&exeTraceParams, "pc_symbol",
-                                  "Use symbols for the PC if available", true);
-Param<bool> exe_trace_intel_format(&exeTraceParams, "intel_format",
-                                   "print trace in intel compatible format", false);
-Param<bool> exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep",
-                                   "Compare sim state to legion state every cycle",
-                                   false);
-Param<string> exe_trace_system(&exeTraceParams, "trace_system",
-                                   "print trace of which system (client or server)",
-                                   "client");
-
-
-//
-// Helper function for ExecutionTraceParamContext::checkParams() just
-// to get us into the InstRecord namespace
-//
-void
-Trace::InstRecord::setParams()
-{
-    flags[TRACE_MISSPEC]     = exe_trace_spec;
-
-    flags[PRINT_CYCLE]       = exe_trace_print_cycle;
-    flags[PRINT_OP_CLASS]    = exe_trace_print_opclass;
-    flags[PRINT_THREAD_NUM]  = exe_trace_print_thread;
-    flags[PRINT_RESULT_DATA] = exe_trace_print_effaddr;
-    flags[PRINT_EFF_ADDR]    = exe_trace_print_data;
-    flags[PRINT_INT_REGS]    = exe_trace_print_iregs;
-    flags[PRINT_FETCH_SEQ]   = exe_trace_print_fetchseq;
-    flags[PRINT_CP_SEQ]      = exe_trace_print_cp_seq;
-    flags[PRINT_REG_DELTA]   = exe_trace_print_reg_delta;
-    flags[PC_SYMBOL]         = exe_trace_pc_symbol;
-    flags[INTEL_FORMAT]      = exe_trace_intel_format;
-    flags[LEGION_LOCKSTEP]   = exe_trace_legion_lockstep;
-    trace_system            = exe_trace_system;
-
-    // If were going to be in lockstep with Legion
-    // Setup shared memory, and get otherwise ready
-    if (flags[LEGION_LOCKSTEP]) {
-        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;
-    }
+    return new Trace::ExeTracer(this);
 }
-
-void
-ExecutionTraceParamContext::checkParams()
-{
-    Trace::InstRecord::setParams();
-}
-