cpu,o3: Fixed checkpointing bug occuring in the o3 CPU
[gem5.git] / src / cpu / exetrace.hh
index 8cc98b777d72d231cb754dced2e86e673e8655a6..b7e808a2a66a866240bff2630f5544c3a05e735f 100644 (file)
  *          Nathan Binkert
  */
 
-#ifndef __EXETRACE_HH__
-#define __EXETRACE_HH__
+#ifndef __CPU_EXETRACE_HH__
+#define __CPU_EXETRACE_HH__
 
-#include <fstream>
-#include <vector>
-
-#include "sim/host.hh"
-#include "cpu/inst_seq.hh"     // for InstSeqNum
 #include "base/trace.hh"
-#include "cpu/thread_context.hh"
+#include "base/types.hh"
 #include "cpu/static_inst.hh"
+#include "cpu/thread_context.hh"
+#include "debug/ExecEnable.hh"
+#include "params/ExeTracer.hh"
+#include "sim/insttracer.hh"
 
-class BaseCPU;
-
+class ThreadContext;
 
 namespace Trace {
 
-class InstRecord : public Record
+class ExeTracerRecord : public InstRecord
 {
-  protected:
-    typedef TheISA::IntRegFile IntRegFile;
-
-    // The following fields are initialized by the constructor and
-    // thus guaranteed to be valid.
-    BaseCPU *cpu;
-    // need to make this ref-counted so it doesn't go away before we
-    // dump the record
-    StaticInstPtr staticInst;
-    Addr PC;
-    bool misspeculating;
-    unsigned thread;
-
-    // The remaining fields are only valid for particular instruction
-    // types (e.g, addresses for memory ops) or when particular
-    // options are enabled (e.g., tracing full register contents).
-    // Each data field has an associated valid flag to indicate
-    // whether the data field is valid.
-    Addr addr;
-    bool addr_valid;
-
-    union {
-        uint64_t as_int;
-        double as_double;
-    } data;
-    enum {
-        DataInvalid = 0,
-        DataInt8 = 1,  // set to equal number of bytes
-        DataInt16 = 2,
-        DataInt32 = 4,
-        DataInt64 = 8,
-        DataDouble = 3
-    } data_status;
-
-    InstSeqNum fetch_seq;
-    bool fetch_seq_valid;
-
-    InstSeqNum cp_seq;
-    bool cp_seq_valid;
-
-    struct iRegFile {
-        IntRegFile regs;
-    };
-    iRegFile *iregs;
-    bool regs_valid;
-
   public:
-    InstRecord(Tick _cycle, BaseCPU *_cpu,
-               const StaticInstPtr &_staticInst,
-               Addr _pc, bool spec, int _thread)
-        : Record(_cycle), cpu(_cpu), staticInst(_staticInst), PC(_pc),
-          misspeculating(spec), thread(_thread)
+    ExeTracerRecord(Tick _when, ThreadContext *_thread,
+               const StaticInstPtr _staticInst, TheISA::PCState _pc,
+               const StaticInstPtr _macroStaticInst = NULL)
+        : InstRecord(_when, _thread, _staticInst, _pc, _macroStaticInst)
     {
-        data_status = DataInvalid;
-        addr_valid = false;
-        regs_valid = false;
-
-        fetch_seq_valid = false;
-        cp_seq_valid = false;
     }
 
-    virtual ~InstRecord() { }
-
-    virtual void dump(std::ostream &outs);
-
-    void setAddr(Addr a) { addr = a; addr_valid = true; }
-
-    void setData(uint64_t d) { data.as_int = d; data_status = DataInt64; }
-    void setData(uint32_t d) { data.as_int = d; data_status = DataInt32; }
-    void setData(uint16_t d) { data.as_int = d; data_status = DataInt16; }
-    void setData(uint8_t d) { data.as_int = d; data_status = DataInt8; }
-
-    void setData(int64_t d) { setData((uint64_t)d); }
-    void setData(int32_t d) { setData((uint32_t)d); }
-    void setData(int16_t d) { setData((uint16_t)d); }
-    void setData(int8_t d)  { setData((uint8_t)d); }
+    void traceInst(const StaticInstPtr &inst, bool ran);
 
-    void setData(double d) { data.as_double = d; data_status = DataDouble; }
-
-    void setFetchSeq(InstSeqNum seq)
-    { fetch_seq = seq; fetch_seq_valid = true; }
-
-    void setCPSeq(InstSeqNum seq)
-    { cp_seq = seq; cp_seq_valid = true; }
-
-    void setRegs(const IntRegFile &regs);
-
-    void finalize() { theLog.append(this); }
-
-    enum InstExecFlagBits {
-        TRACE_MISSPEC = 0,
-        PRINT_CYCLE,
-        PRINT_OP_CLASS,
-        PRINT_THREAD_NUM,
-        PRINT_RESULT_DATA,
-        PRINT_EFF_ADDR,
-        PRINT_INT_REGS,
-        PRINT_FETCH_SEQ,
-        PRINT_CP_SEQ,
-        PRINT_REG_DELTA,
-        PC_SYMBOL,
-        INTEL_FORMAT,
-        NUM_BITS
-    };
-
-    static std::vector<bool> flags;
-    static std::string trace_system;
-
-    static void setParams();
-
-    static bool traceMisspec() { return flags[TRACE_MISSPEC]; }
+    void dump();
+    virtual void dumpTicks(std::ostream &outs);
 };
 
-
-inline void
-InstRecord::setRegs(const IntRegFile &regs)
+class ExeTracer : public InstTracer
 {
-    if (!iregs)
-      iregs = new iRegFile;
-
-    memcpy(&iregs->regs, &regs, sizeof(IntRegFile));
-    regs_valid = true;
-}
+  public:
+    typedef ExeTracerParams Params;
+    ExeTracer(const Params *params) : InstTracer(params)
+    {}
+
+    InstRecord *
+    getInstRecord(Tick when, ThreadContext *tc,
+            const StaticInstPtr staticInst, TheISA::PCState pc,
+            const StaticInstPtr macroStaticInst = NULL)
+    {
+        if (!Debug::ExecEnable)
+            return NULL;
 
-inline
-InstRecord *
-getInstRecord(Tick cycle, ThreadContext *tc, BaseCPU *cpu,
-              const StaticInstPtr staticInst,
-              Addr pc, int thread = 0)
-{
-    if (DTRACE(InstExec) &&
-        (InstRecord::traceMisspec() || !tc->misspeculating())) {
-        return new InstRecord(cycle, cpu, staticInst, pc,
-                              tc->misspeculating(), thread);
+        return new ExeTracerRecord(when, tc,
+                staticInst, pc, macroStaticInst);
     }
+};
 
-    return NULL;
-}
-
-
-}
+} // namespace Trace
 
-#endif // __EXETRACE_HH__
+#endif // __CPU_EXETRACE_HH__