Changed BaseCPU::ProfileEvent's interval member to be of type Tick. This was done...
[gem5.git] / src / cpu / simple / base.hh
index c39bfa9cd43ae5acaa4f5c4fd770818104d270ad..aeae1a3d81e0913a58791657eaaf027eb0d48b6e 100644 (file)
@@ -33,6 +33,7 @@
 #ifndef __CPU_SIMPLE_BASE_HH__
 #define __CPU_SIMPLE_BASE_HH__
 
+#include "arch/predecoder.hh"
 #include "base/statistics.hh"
 #include "config/full_system.hh"
 #include "cpu/base.hh"
@@ -43,6 +44,7 @@
 #include "mem/port.hh"
 #include "mem/request.hh"
 #include "sim/eventq.hh"
+#include "sim/system.hh"
 
 // forward declarations
 #if FULL_SYSTEM
@@ -54,15 +56,19 @@ namespace TheISA
 }
 class MemObject;
 
-class RemoteGDB;
-class GDBListener;
-
 #else
 
 class Process;
 
 #endif // FULL_SYSTEM
 
+class RemoteGDB;
+class GDBListener;
+
+namespace TheISA
+{
+    class Predecoder;
+}
 class ThreadContext;
 class Checkpoint;
 
@@ -70,11 +76,12 @@ namespace Trace {
     class InstRecord;
 }
 
+class BaseSimpleCPUParams;
+
 
 class BaseSimpleCPU : public BaseCPU
 {
   protected:
-    typedef TheISA::MachInst MachInst;
     typedef TheISA::MiscReg MiscReg;
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
@@ -82,6 +89,14 @@ class BaseSimpleCPU : public BaseCPU
   protected:
     Trace::InstRecord *traceData;
 
+    inline void checkPcEventQueue() {
+        Addr oldpc;
+        do {
+            oldpc = thread->readPC();
+            system->pcEventQueue.service(tc);
+        } while (oldpc != thread->readPC());
+    }
+
   public:
     void post_interrupt(int int_num, int index);
 
@@ -94,16 +109,7 @@ class BaseSimpleCPU : public BaseCPU
     };
 
   public:
-    struct Params : public BaseCPU::Params
-    {
-#if FULL_SYSTEM
-        TheISA::ITB *itb;
-        TheISA::DTB *dtb;
-#else
-        Process *process;
-#endif
-    };
-    BaseSimpleCPU(Params *params);
+    BaseSimpleCPU(BaseSimpleCPUParams *params);
     virtual ~BaseSimpleCPU();
 
   public:
@@ -114,6 +120,24 @@ class BaseSimpleCPU : public BaseCPU
      * objects to modify this thread's state.
      */
     ThreadContext *tc;
+  protected:
+    int cpuId;
+
+    enum Status {
+        Idle,
+        Running,
+        IcacheRetry,
+        IcacheWaitResponse,
+        IcacheWaitSwitch,
+        DcacheRetry,
+        DcacheWaitResponse,
+        DcacheWaitSwitch,
+        SwitchedOut
+    };
+
+    Status _status;
+
+  public:
 
 #if FULL_SYSTEM
     Addr dbg_vtophys(Addr addr);
@@ -122,14 +146,20 @@ class BaseSimpleCPU : public BaseCPU
 #endif
 
     // current instruction
-    MachInst inst;
+    TheISA::MachInst inst;
 
-    // Static data storage
-    TheISA::IntReg dataReg;
+    // The predecoder
+    TheISA::Predecoder predecoder;
 
     StaticInstPtr curStaticInst;
     StaticInstPtr curMacroStaticInst;
 
+    //This is the offset from the current pc that fetch should be performed at
+    Addr fetchOffset;
+    //This flag says to stay at the current pc. This is useful for
+    //instructions which go beyond MachInst boundaries.
+    bool stayAtPC;
+
     void checkForInterrupts();
     Fault setupFetchRequest(Request *req);
     void preExecute();
@@ -148,11 +178,22 @@ class BaseSimpleCPU : public BaseCPU
     Counter startNumInst;
     Stats::Scalar<> numInsts;
 
+    void countInst()
+    {
+        numInst++;
+        numInsts++;
+
+        thread->funcExeInst++;
+    }
+
     virtual Counter totalInstructions() const
     {
         return numInst - startNumInst;
     }
 
+    // Mask to align PCs to MachInst sized boundaries
+    static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1);
+
     // number of simulated memory references
     Stats::Scalar<> numMemRefs;
 
@@ -186,7 +227,8 @@ class BaseSimpleCPU : public BaseCPU
     // These functions are only used in CPU models that split
     // effective address computation from the actual memory access.
     void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
-    Addr getEA()       { panic("BaseSimpleCPU::getEA() not implemented\n"); }
+    Addr getEA()       { panic("BaseSimpleCPU::getEA() not implemented\n");
+        M5_DUMMY_RETURN}
 
     void prefetch(Addr addr, unsigned flags)
     {
@@ -198,6 +240,7 @@ class BaseSimpleCPU : public BaseCPU
         // need to do this...
     }
 
+
     Fault copySrcTranslate(Addr src);
 
     Fault copy(Addr dest);
@@ -276,21 +319,30 @@ class BaseSimpleCPU : public BaseCPU
     }
 
     uint64_t readPC() { return thread->readPC(); }
+    uint64_t readMicroPC() { return thread->readMicroPC(); }
     uint64_t readNextPC() { return thread->readNextPC(); }
+    uint64_t readNextMicroPC() { return thread->readNextMicroPC(); }
     uint64_t readNextNPC() { return thread->readNextNPC(); }
 
     void setPC(uint64_t val) { thread->setPC(val); }
+    void setMicroPC(uint64_t val) { thread->setMicroPC(val); }
     void setNextPC(uint64_t val) { thread->setNextPC(val); }
+    void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); }
     void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
 
+    MiscReg readMiscRegNoEffect(int misc_reg)
+    {
+        return thread->readMiscRegNoEffect(misc_reg);
+    }
+
     MiscReg readMiscReg(int misc_reg)
     {
         return thread->readMiscReg(misc_reg);
     }
 
-    MiscReg readMiscRegWithEffect(int misc_reg)
+    void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
     {
-        return thread->readMiscRegWithEffect(misc_reg);
+        return thread->setMiscRegNoEffect(misc_reg, val);
     }
 
     void setMiscReg(int misc_reg, const MiscReg &val)
@@ -298,11 +350,68 @@ class BaseSimpleCPU : public BaseCPU
         return thread->setMiscReg(misc_reg, val);
     }
 
-    void setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+    MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+        return thread->readMiscRegNoEffect(reg_idx);
+    }
+
+    MiscReg readMiscRegOperand(const StaticInst *si, int idx)
+    {
+        int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+        return thread->readMiscReg(reg_idx);
+    }
+
+    void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+        return thread->setMiscRegNoEffect(reg_idx, val);
+    }
+
+    void setMiscRegOperand(
+            const StaticInst *si, int idx, const MiscReg &val)
+    {
+        int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
+        return thread->setMiscReg(reg_idx, val);
+    }
+
+    void demapPage(Addr vaddr, uint64_t asn)
+    {
+        thread->demapPage(vaddr, asn);
+    }
+
+    void demapInstPage(Addr vaddr, uint64_t asn)
+    {
+        thread->demapInstPage(vaddr, asn);
+    }
+
+    void demapDataPage(Addr vaddr, uint64_t asn)
     {
-        return thread->setMiscRegWithEffect(misc_reg, val);
+        thread->demapDataPage(vaddr, asn);
     }
 
+    unsigned readStCondFailures() {
+        return thread->readStCondFailures();
+    }
+
+    void setStCondFailures(unsigned sc_failures) {
+        thread->setStCondFailures(sc_failures);
+    }
+
+     MiscReg readRegOtherThread(int regIdx, int tid = -1)
+     {
+        panic("Simple CPU models do not support multithreaded "
+              "register access.\n");
+     }
+
+     void setRegOtherThread(int regIdx, const MiscReg &val, int tid = -1)
+     {
+        panic("Simple CPU models do not support multithreaded "
+              "register access.\n");
+     }
+
+    //Fault CacheOp(uint8_t Op, Addr EA);
+
 #if FULL_SYSTEM
     Fault hwrei() { return thread->hwrei(); }
     void ev5_trap(Fault fault) { fault->invoke(tc); }