Tracing: Make tracing aware of macro and micro ops.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 7 Jan 2009 06:34:18 +0000 (22:34 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 7 Jan 2009 06:34:18 +0000 (22:34 -0800)
src/cpu/SConscript
src/cpu/exetrace.cc
src/cpu/exetrace.hh
src/cpu/inteltrace.hh
src/cpu/legiontrace.hh
src/cpu/nativetrace.hh
src/cpu/simple/base.cc
src/sim/insttracer.hh

index 750e1ee4c46e8e3978ba390c1066767d64caa00b..334504660b52743a05de60d5d0a3cd7f8efe996d 100644 (file)
@@ -170,10 +170,12 @@ TraceFlag('ExecSpeculative')
 TraceFlag('ExecSymbol')
 TraceFlag('ExecThread')
 TraceFlag('ExecTicks')
+TraceFlag('ExecMicro')
+TraceFlag('ExecMacro')
 TraceFlag('Fetch')
 TraceFlag('IntrControl')
 TraceFlag('PCEvent')
 TraceFlag('Quiesce')
 
 CompoundFlag('Exec', [ 'ExecEnable', 'ExecTicks', 'ExecOpClass', 'ExecThread',
-    'ExecEffAddr', 'ExecResult', 'ExecSymbol' ])
+    'ExecEffAddr', 'ExecResult', 'ExecSymbol', 'ExecMicro' ])
index 824fbb5f6aea11ee4d1873ac7efae99e6c14e24d..4c0f83a217effadc1725d29d4aa3703e622f008d 100644 (file)
@@ -46,7 +46,7 @@ using namespace TheISA;
 namespace Trace {
 
 void
-Trace::ExeTracerRecord::dump()
+Trace::ExeTracerRecord::traceInst(StaticInstPtr inst, bool ran)
 {
     ostream &outs = Trace::output();
 
@@ -61,7 +61,6 @@ Trace::ExeTracerRecord::dump()
     if (IsOn(ExecThread))
         outs << "T" << thread->threadId() << " : ";
 
-
     std::string sym_str;
     Addr sym_addr;
     if (debugSymbolTable
@@ -69,36 +68,47 @@ Trace::ExeTracerRecord::dump()
         && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)) {
         if (PC != sym_addr)
             sym_str += csprintf("+%d", PC - sym_addr);
-        outs << "@" << sym_str << " : ";
+        outs << "@" << sym_str;
     }
     else {
-        outs << "0x" << hex << PC << " : ";
+        outs << "0x" << hex << PC;
     }
 
+    if (inst->isMicroop()) {
+        outs << "." << setw(2) << dec << upc;
+    } else {
+        outs << "   ";
+    }
+
+    outs << " : ";
+
     //
     //  Print decoded instruction
     //
 
     outs << setw(26) << left;
-    outs << staticInst->disassemble(PC, debugSymbolTable);
-    outs << " : ";
+    outs << inst->disassemble(PC, debugSymbolTable);
 
-    if (IsOn(ExecOpClass)) {
-        outs << Enums::OpClassStrings[staticInst->opClass()] << " : ";
-    }
+    if (ran) {
+        outs << " : ";
 
-    if (IsOn(ExecResult) && data_status != DataInvalid) {
-        ccprintf(outs, " D=%#018x", data.as_int);
-    }
+        if (IsOn(ExecOpClass)) {
+            outs << Enums::OpClassStrings[inst->opClass()] << " : ";
+        }
 
-    if (IsOn(ExecEffAddr) && addr_valid)
-        outs << " A=0x" << hex << addr;
+        if (IsOn(ExecResult) && data_status != DataInvalid) {
+            ccprintf(outs, " D=%#018x", data.as_int);
+        }
 
-    if (IsOn(ExecFetchSeq) && fetch_seq_valid)
-        outs << "  FetchSeq=" << dec << fetch_seq;
+        if (IsOn(ExecEffAddr) && addr_valid)
+            outs << " A=0x" << hex << addr;
 
-    if (IsOn(ExecCPSeq) && cp_seq_valid)
-        outs << "  CPSeq=" << dec << cp_seq;
+        if (IsOn(ExecFetchSeq) && fetch_seq_valid)
+            outs << "  FetchSeq=" << dec << fetch_seq;
+
+        if (IsOn(ExecCPSeq) && cp_seq_valid)
+            outs << "  CPSeq=" << dec << cp_seq;
+    }
 
     //
     //  End of line...
@@ -106,6 +116,29 @@ Trace::ExeTracerRecord::dump()
     outs << endl;
 }
 
+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 (IsOn(ExecMacro) && staticInst->isMicroop() &&
+            (IsOn(ExecMicro) &&
+             macroStaticInst && staticInst->isFirstMicroop()) ||
+            (!IsOn(ExecMicro) &&
+             macroStaticInst && staticInst->isLastMicroop())) {
+        traceInst(macroStaticInst, false);
+    }
+    if (IsOn(ExecMicro) || !staticInst->isMicroop()) {
+        traceInst(staticInst, true);
+    }
+}
+
 /* namespace Trace */ }
 
 ////////////////////////////////////////////////////////////////////////
index 84660432b01bf7d413375dee41cc2d874c8481b5..e5b22c8819efb40f49cf37bf7ad12bc0e6394c65 100644 (file)
@@ -47,11 +47,15 @@ class ExeTracerRecord : public InstRecord
 {
   public:
     ExeTracerRecord(Tick _when, ThreadContext *_thread,
-               const StaticInstPtr &_staticInst, Addr _pc, bool spec)
-        : InstRecord(_when, _thread, _staticInst, _pc, spec)
+               const StaticInstPtr _staticInst, Addr _pc, bool spec,
+               const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
+        : InstRecord(_when, _thread, _staticInst, _pc, spec,
+                _macroStaticInst, _upc)
     {
     }
 
+    void traceInst(StaticInstPtr inst, bool ran);
+
     void dump();
 };
 
@@ -64,7 +68,8 @@ class ExeTracer : public InstTracer
 
     InstRecord *
     getInstRecord(Tick when, ThreadContext *tc,
-            const StaticInstPtr staticInst, Addr pc)
+            const StaticInstPtr staticInst, Addr pc,
+            const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0)
     {
         if (!IsOn(ExecEnable))
             return NULL;
@@ -76,7 +81,7 @@ class ExeTracer : public InstTracer
             return NULL;
 
         return new ExeTracerRecord(when, tc,
-                staticInst, pc, tc->misspeculating());
+                staticInst, pc, tc->misspeculating(), macroStaticInst, upc);
     }
 };
 
index 5d5bcda8ec4618603d1acadd440a536e4edf65c2..e34658b584cf9c0219f776c8fc1dc5160e3fc36e 100644 (file)
@@ -47,8 +47,10 @@ class IntelTraceRecord : public InstRecord
 {
   public:
     IntelTraceRecord(Tick _when, ThreadContext *_thread,
-               const StaticInstPtr &_staticInst, Addr _pc, bool spec)
-        : InstRecord(_when, _thread, _staticInst, _pc, spec)
+               const StaticInstPtr _staticInst, Addr _pc, bool spec,
+               const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
+        : InstRecord(_when, _thread, _staticInst, _pc, spec,
+                _macroStaticInst, _upc)
     {
     }
 
@@ -64,7 +66,8 @@ class IntelTrace : public InstTracer
 
     IntelTraceRecord *
     getInstRecord(Tick when, ThreadContext *tc,
-            const StaticInstPtr staticInst, Addr pc)
+            const StaticInstPtr staticInst, Addr pc,
+            const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0)
     {
         if (!IsOn(ExecEnable))
             return NULL;
@@ -76,7 +79,7 @@ class IntelTrace : public InstTracer
             return NULL;
 
         return new IntelTraceRecord(when, tc,
-                staticInst, pc, tc->misspeculating());
+                staticInst, pc, tc->misspeculating(), macroStaticInst, upc);
     }
 };
 
index 97193ff1abaa4e5a48373d9361b46878a673fa75..9962063e4b606d20a9509cc912e1b30a0ce0719b 100644 (file)
@@ -46,8 +46,10 @@ class LegionTraceRecord : public InstRecord
 {
   public:
     LegionTraceRecord(Tick _when, ThreadContext *_thread,
-               const StaticInstPtr &_staticInst, Addr _pc, bool spec)
-        : InstRecord(_when, _thread, _staticInst, _pc, spec)
+               const StaticInstPtr _staticInst, Addr _pc, bool spec,
+               const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
+        : InstRecord(_when, _thread, _staticInst, _pc, spec,
+                _macroStaticInst, _upc)
     {
     }
 
@@ -63,13 +65,14 @@ class LegionTrace : public InstTracer
 
     LegionTraceRecord *
     getInstRecord(Tick when, ThreadContext *tc,
-            const StaticInstPtr staticInst, Addr pc)
+            const StaticInstPtr staticInst, Addr pc,
+            const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0)
     {
         if (tc->misspeculating())
             return NULL;
 
         return new LegionTraceRecord(when, tc,
-                staticInst, pc, tc->misspeculating());
+                staticInst, pc, tc->misspeculating(), macroStaticInst, upc);
     }
 };
 
index ab038c4c3ff6eae9b302a943b3f0cd57a414189f..9e912d92f42aa37764d1fb718c43331ed1a9f508 100644 (file)
@@ -54,8 +54,11 @@ class NativeTraceRecord : public InstRecord
   public:
     NativeTraceRecord(NativeTrace * _parent,
                Tick _when, ThreadContext *_thread,
-               const StaticInstPtr &_staticInst, Addr _pc, bool spec)
-        : InstRecord(_when, _thread, _staticInst, _pc, spec), parent(_parent)
+               const StaticInstPtr _staticInst, Addr _pc, bool spec,
+               const StaticInstPtr _macroStaticInst = NULL, MicroPC _upc = 0)
+        : InstRecord(_when, _thread, _staticInst, _pc, spec,
+                _macroStaticInst, _upc),
+        parent(_parent)
     {
     }
 
@@ -192,13 +195,14 @@ class NativeTrace : public InstTracer
 
     NativeTraceRecord *
     getInstRecord(Tick when, ThreadContext *tc,
-            const StaticInstPtr staticInst, Addr pc)
+            const StaticInstPtr staticInst, Addr pc,
+            const StaticInstPtr macroStaticInst = NULL, MicroPC upc = 0)
     {
         if (tc->misspeculating())
             return NULL;
 
         return new NativeTraceRecord(this, when, tc,
-                staticInst, pc, tc->misspeculating());
+                staticInst, pc, tc->misspeculating(), macroStaticInst, upc);
     }
 
     void
index b3379cddb3a39b821e52b48ad6d4cc2f9f581426..3c154afb6b10fbab71698edbe0f94b5a69ac96c4 100644 (file)
@@ -418,8 +418,9 @@ BaseSimpleCPU::preExecute()
     if(curStaticInst)
     {
 #if TRACING_ON
-        traceData = tracer->getInstRecord(curTick, tc, curStaticInst,
-                                         thread->readPC());
+        traceData = tracer->getInstRecord(curTick, tc,
+                curStaticInst, thread->readPC(),
+                curMacroStaticInst, thread->readMicroPC());
 
         DPRINTF(Decode,"Decode: Decoded %s instruction: 0x%x\n",
                 curStaticInst->getName(), curStaticInst->machInst);
index 39a5536b031448368957e5c88f7b718681cc08ba..9fb5f9f228d5af3ffa8f898b30576bd6e08635dd 100644 (file)
@@ -55,6 +55,8 @@ class InstRecord
     // dump the record
     StaticInstPtr staticInst;
     Addr PC;
+    StaticInstPtr macroStaticInst;
+    MicroPC upc;
     bool misspeculating;
 
     // The remaining fields are only valid for particular instruction
@@ -86,10 +88,13 @@ class InstRecord
 
   public:
     InstRecord(Tick _when, ThreadContext *_thread,
-               const StaticInstPtr &_staticInst,
-               Addr _pc, bool spec)
+               const StaticInstPtr _staticInst,
+               Addr _pc, bool spec,
+               const StaticInstPtr _macroStaticInst = NULL,
+               MicroPC _upc = 0)
         : when(_when), thread(_thread),
           staticInst(_staticInst), PC(_pc),
+          macroStaticInst(_macroStaticInst), upc(_upc),
           misspeculating(spec)
     {
         data_status = DataInvalid;
@@ -137,7 +142,9 @@ class InstTracer : public SimObject
 
     virtual InstRecord *
         getInstRecord(Tick when, ThreadContext *tc,
-                const StaticInstPtr staticInst, Addr pc) = 0;
+                const StaticInstPtr staticInst, Addr pc,
+                const StaticInstPtr macroStaticInst = NULL,
+                MicroPC _upc = 0) = 0;
 };