Merged in new FastCPU stuff with existing code.
[gem5.git] / cpu / simple_cpu / simple_cpu.hh
index 666fe490b1806a5640f18afd59ed8db00101e72a..1c6b18d039ae0acbcf77d9e34a89d89e023128ed 100644 (file)
 #include "base/loader/symtab.hh"
 #include "cpu/pc_event.hh"
 #include "base/statistics.hh"
-
+#include "cpu/exec_context.hh"
+#include "cpu/static_inst.hh"
 
 // forward declarations
 #ifdef FULL_SYSTEM
 class Processor;
 class Kernel;
-class AlphaItb;
-class AlphaDtb;
+class AlphaITB;
+class AlphaDTB;
 class PhysicalMemory;
 
 class RemoteGDB;
 class GDBListener;
+
+#else
+
+class Process;
+
 #endif // FULL_SYSTEM
 
 class MemInterface;
@@ -75,6 +81,22 @@ class SimpleCPU : public BaseCPU
 
     TickEvent tickEvent;
 
+    /// Schedule tick event, regardless of its current state.
+    void scheduleTickEvent(int delay)
+    {
+        if (tickEvent.squashed())
+            tickEvent.reschedule(curTick + delay);
+        else if (!tickEvent.scheduled())
+            tickEvent.schedule(curTick + delay);
+    }
+
+    /// Unschedule tick event, regardless of its current state.
+    void unscheduleTickEvent()
+    {
+        if (tickEvent.scheduled())
+            tickEvent.squash();
+    }
+
   private:
     Trace::InstRecord *traceData;
     template<typename T>
@@ -115,9 +137,9 @@ class SimpleCPU : public BaseCPU
               System *_system,
               Counter max_insts_any_thread, Counter max_insts_all_threads,
               Counter max_loads_any_thread, Counter max_loads_all_threads,
-              AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem,
+              AlphaITB *itb, AlphaDTB *dtb, FunctionalMemory *mem,
               MemInterface *icache_interface, MemInterface *dcache_interface,
-              Tick freq);
+              bool _def_reg, Tick freq);
 
 #else
 
@@ -126,11 +148,13 @@ class SimpleCPU : public BaseCPU
               Counter max_insts_all_threads,
               Counter max_loads_any_thread,
               Counter max_loads_all_threads,
-              MemInterface *icache_interface, MemInterface *dcache_interface);
+              MemInterface *icache_interface, MemInterface *dcache_interface,
+              bool _def_reg);
 
 #endif
 
     virtual ~SimpleCPU();
+    virtual void init();
 
     // execution context
     ExecContext *xc;
@@ -150,6 +174,8 @@ class SimpleCPU : public BaseCPU
     // L1 data cache
     MemInterface *dcacheInterface;
 
+    bool defer_registration;
+
     // current instruction
     MachInst inst;
 
@@ -172,9 +198,10 @@ class SimpleCPU : public BaseCPU
 
     Status status() const { return _status; }
 
-    virtual void execCtxStatusChg(int thread_num);
-
-    void setStatus(Status new_status);
+    virtual void activateContext(int thread_num, int delay);
+    virtual void suspendContext(int thread_num);
+    virtual void deallocateContext(int thread_num);
+    virtual void haltContext(int thread_num);
 
     // statistics
     virtual void regStats();
@@ -183,25 +210,30 @@ class SimpleCPU : public BaseCPU
     // number of simulated instructions
     Counter numInst;
     Counter startNumInst;
-    Statistics::Formula numInsts;
+    Stats::Scalar<> numInsts;
+
+    virtual Counter totalInstructions() const
+    {
+        return numInst - startNumInst;
+    }
 
     // number of simulated memory references
-    Statistics::Scalar<> numMemRefs;
+    Stats::Scalar<> numMemRefs;
 
     // number of simulated loads
     Counter numLoad;
     Counter startNumLoad;
 
     // number of idle cycles
-    Statistics::Average<> notIdleFraction;
-    Statistics::Formula idleFraction;
+    Stats::Average<> notIdleFraction;
+    Stats::Formula idleFraction;
 
     // number of cycles stalled for I-cache misses
-    Statistics::Scalar<> icacheStallCycles;
+    Stats::Scalar<> icacheStallCycles;
     Counter lastIcacheStall;
 
     // number of cycles stalled for D-cache misses
-    Statistics::Scalar<> dcacheStallCycles;
+    Stats::Scalar<> dcacheStallCycles;
     Counter lastDcacheStall;
 
     void processCacheCompletion();
@@ -210,22 +242,107 @@ class SimpleCPU : public BaseCPU
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 
     template <class T>
-    Fault read(Addr addr, Tdata, unsigned flags);
+    Fault read(Addr addr, T &data, unsigned flags);
 
     template <class T>
     Fault write(T data, Addr addr, unsigned flags,
                         uint64_t *res);
 
-    Fault prefetch(Addr addr, unsigned flags)
+    void prefetch(Addr addr, unsigned flags)
     {
         // need to do this...
-        return No_Fault;
     }
 
     void writeHint(Addr addr, int size)
     {
         // need to do this...
     }
+
+    Fault copySrcTranslate(Addr src);
+
+    Fault copy(Addr dest);
+
+    // The register accessor methods provide the index of the
+    // instruction's operand (e.g., 0 or 1), not the architectural
+    // register index, to simplify the implementation of register
+    // renaming.  We find the architectural register index by indexing
+    // into the instruction's own operand index table.  Note that a
+    // raw pointer to the StaticInst is provided instead of a
+    // ref-counted StaticInstPtr to redice overhead.  This is fine as
+    // long as these methods don't copy the pointer into any long-term
+    // storage (which is pretty hard to imagine they would have reason
+    // to do).
+
+    uint64_t readIntReg(StaticInst<TheISA> *si, int idx)
+    {
+        return xc->readIntReg(si->srcRegIdx(idx));
+    }
+
+    float readFloatRegSingle(StaticInst<TheISA> *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
+        return xc->readFloatRegSingle(reg_idx);
+    }
+
+    double readFloatRegDouble(StaticInst<TheISA> *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
+        return xc->readFloatRegDouble(reg_idx);
+    }
+
+    uint64_t readFloatRegInt(StaticInst<TheISA> *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
+        return xc->readFloatRegInt(reg_idx);
+    }
+
+    void setIntReg(StaticInst<TheISA> *si, int idx, uint64_t val)
+    {
+        xc->setIntReg(si->destRegIdx(idx), val);
+    }
+
+    void setFloatRegSingle(StaticInst<TheISA> *si, int idx, float val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
+        xc->setFloatRegSingle(reg_idx, val);
+    }
+
+    void setFloatRegDouble(StaticInst<TheISA> *si, int idx, double val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
+        xc->setFloatRegDouble(reg_idx, val);
+    }
+
+    void setFloatRegInt(StaticInst<TheISA> *si, int idx, uint64_t val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
+        xc->setFloatRegInt(reg_idx, val);
+    }
+
+    uint64_t readPC() { return xc->readPC(); }
+    void setNextPC(uint64_t val) { xc->setNextPC(val); }
+
+    uint64_t readUniq() { return xc->readUniq(); }
+    void setUniq(uint64_t val) { xc->setUniq(val); }
+
+    uint64_t readFpcr() { return xc->readFpcr(); }
+    void setFpcr(uint64_t val) { xc->setFpcr(val); }
+
+#ifdef FULL_SYSTEM
+    uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); }
+    Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); }
+    Fault hwrei() { return xc->hwrei(); }
+    int readIntrFlag() { return xc->readIntrFlag(); }
+    void setIntrFlag(int val) { xc->setIntrFlag(val); }
+    bool inPalMode() { return xc->inPalMode(); }
+    void ev5_trap(Fault fault) { xc->ev5_trap(fault); }
+    bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
+#else
+    void syscall() { xc->syscall(); }
+#endif
+
+    bool misspeculating() { return xc->misspeculating(); }
+    ExecContext *xcBase() { return xc; }
 };
 
 #endif // __SIMPLE_CPU_HH__