O3: Track if the RAS has been pushed or not to pop the RAS if neccessary.
[gem5.git] / src / cpu / static_inst.hh
index b11e74c6e887561ec3dc1094d6f2b1e5e93c1eb0..db2cd817d85cdffcb737694921015888a7f251e5 100644 (file)
 #include <bitset>
 #include <string>
 
-#include "arch/isa_traits.hh"
-#include "arch/utility.hh"
-#include "sim/faults.hh"
-#include "base/bitfield.hh"
-#include "base/hashmap.hh"
+#include "arch/registers.hh"
+#include "arch/types.hh"
 #include "base/misc.hh"
 #include "base/refcnt.hh"
+#include "base/types.hh"
+#include "config/the_isa.hh"
 #include "cpu/op_class.hh"
-#include "cpu/o3/dyn_inst.hh"
-#include "sim/faults.hh"
-#include "sim/host.hh"
+#include "cpu/static_inst_fwd.hh"
+#include "sim/fault_fwd.hh"
 
 // forward declarations
 struct AlphaSimpleImpl;
@@ -54,8 +52,11 @@ class ThreadContext;
 class DynInst;
 class Packet;
 
-template <class Impl>
-class OzoneDynInst;
+struct O3CPUImpl;
+template <class Impl> class BaseO3DynInst;
+typedef BaseO3DynInst<O3CPUImpl> O3DynInst;
+template <class Impl> class OzoneDynInst;
+class InOrderDynInst;
 
 class CheckerCPU;
 class FastCPU;
@@ -68,8 +69,6 @@ namespace Trace {
     class InstRecord;
 }
 
-typedef uint32_t MicroPC;
-
 /**
  * Base, ISA-independent static instruction class.
  *
@@ -78,9 +77,18 @@ typedef uint32_t MicroPC;
  * solely on these flags can process instructions without being
  * recompiled for multiple ISAs.
  */
-class StaticInstBase : public RefCounted
+class StaticInst : public RefCounted
 {
-  protected:
+  public:
+    /// Binary extended machine instruction type.
+    typedef TheISA::ExtMachInst ExtMachInst;
+    /// Logical register index type.
+    typedef TheISA::RegIndex RegIndex;
+
+    enum {
+        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,        //< Max source regs
+        MaxInstDestRegs = TheISA::MaxInstDestRegs       //< Max dest regs
+    };
 
     /// Set of boolean static instruction properties.
     ///
@@ -104,37 +112,39 @@ class StaticInstBase : public RefCounted
     /// implement this behavior via the execute() methods.
     ///
     enum Flags {
-        IsNop,         ///< Is a no-op (no effect at all).
+        IsNop,          ///< Is a no-op (no effect at all).
 
-        IsInteger,     ///< References integer regs.
-        IsFloating,    ///< References FP regs.
+        IsInteger,      ///< References integer regs.
+        IsFloating,     ///< References FP regs.
 
-        IsMemRef,      ///< References memory (load, store, or prefetch).
-        IsLoad,                ///< Reads from memory (load or prefetch).
-        IsStore,       ///< Writes to memory.
+        IsMemRef,       ///< References memory (load, store, or prefetch).
+        IsLoad,         ///< Reads from memory (load or prefetch).
+        IsStore,        ///< Writes to memory.
         IsStoreConditional,    ///< Store conditional instruction.
-        IsInstPrefetch,        ///< Instruction-cache prefetch.
-        IsDataPrefetch,        ///< Data-cache prefetch.
-        IsCopy,         ///< Fast Cache block copy
-
-        IsControl,             ///< Control transfer instruction.
-        IsDirectControl,       ///< PC relative control transfer.
-        IsIndirectControl,     ///< Register indirect control transfer.
-        IsCondControl,         ///< Conditional control transfer.
-        IsUncondControl,       ///< Unconditional control transfer.
-        IsCall,                        ///< Subroutine call.
-        IsReturn,              ///< Subroutine return.
+        IsIndexed,      ///< Accesses memory with an indexed address computation
+        IsInstPrefetch, ///< Instruction-cache prefetch.
+        IsDataPrefetch, ///< Data-cache prefetch.
+
+        IsControl,              ///< Control transfer instruction.
+        IsDirectControl,        ///< PC relative control transfer.
+        IsIndirectControl,      ///< Register indirect control transfer.
+        IsCondControl,          ///< Conditional control transfer.
+        IsUncondControl,        ///< Unconditional control transfer.
+        IsCall,                 ///< Subroutine call.
+        IsReturn,               ///< Subroutine return.
 
         IsCondDelaySlot,///< Conditional Delay-Slot Instruction
 
-        IsThreadSync,  ///< Thread synchronization operation.
+        IsThreadSync,   ///< Thread synchronization operation.
 
-        IsSerializing, ///< Serializes pipeline: won't execute until all
+        IsSerializing,  ///< Serializes pipeline: won't execute until all
                         /// older instructions have committed.
         IsSerializeBefore,
         IsSerializeAfter,
-        IsMemBarrier,  ///< Is a memory barrier
-        IsWriteBarrier,        ///< Is a write barrier
+        IsMemBarrier,   ///< Is a memory barrier
+        IsWriteBarrier, ///< Is a write barrier
+        IsReadBarrier,  ///< Is a read barrier
+        IsERET, /// <- Causes the IFU to stall (MIPS ISA)
 
         IsNonSpeculative, ///< Should not be executed speculatively
         IsQuiesce,      ///< Is a quiesce instruction
@@ -142,18 +152,24 @@ class StaticInstBase : public RefCounted
         IsIprAccess,    ///< Accesses IPRs
         IsUnverifiable, ///< Can't be verified by a checker
 
+        IsSyscall,      ///< Causes a system call to be emulated in syscall
+                        /// emulation mode.
+
         //Flags for microcode
         IsMacroop,      ///< Is a macroop containing microops
-        IsMicroop,     ///< Is a microop
-        IsDelayedCommit,       ///< This microop doesn't commit right away
-        IsLastMicroop, ///< This microop ends a microop sequence
-        IsFirstMicroop,        ///< This microop begins a microop sequence
+        IsMicroop,      ///< Is a microop
+        IsDelayedCommit,        ///< This microop doesn't commit right away
+        IsLastMicroop,  ///< This microop ends a microop sequence
+        IsFirstMicroop, ///< This microop begins a microop sequence
         //This flag doesn't do anything yet
-        IsMicroBranch, ///< This microop branches within the microcode for a macroop
-
+        IsMicroBranch,  ///< This microop branches within the microcode for a macroop
+        IsDspOp,
+        IsSquashAfter, ///< Squash all uncommitted state after executed
         NumFlags
     };
 
+  protected:
+
     /// Flag values for this instruction.
     std::bitset<NumFlags> flags;
 
@@ -173,17 +189,6 @@ class StaticInstBase : public RefCounted
     int8_t _numIntDestRegs;
     //@}
 
-    /// Constructor.
-    /// It's important to initialize everything here to a sane
-    /// default, since the decoder generally only overrides
-    /// the fields that are meaningful for the particular
-    /// instruction.
-    StaticInstBase(OpClass __opClass)
-        : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
-          _numFPDestRegs(0), _numIntDestRegs(0)
-    {
-    }
-
   public:
 
     /// @name Register information.
@@ -204,30 +209,31 @@ class StaticInstBase : public RefCounted
 
     /// @name Flag accessors.
     /// These functions are used to access the values of the various
-    /// instruction property flags.  See StaticInstBase::Flags for descriptions
+    /// instruction property flags.  See StaticInst::Flags for descriptions
     /// of the individual flags.
     //@{
 
-    bool isNop()         const { return flags[IsNop]; }
+    bool isNop()          const { return flags[IsNop]; }
 
-    bool isMemRef()              const { return flags[IsMemRef]; }
-    bool isLoad()        const { return flags[IsLoad]; }
-    bool isStore()       const { return flags[IsStore]; }
-    bool isStoreConditional()    const { return flags[IsStoreConditional]; }
+    bool isMemRef()       const { return flags[IsMemRef]; }
+    bool isLoad()         const { return flags[IsLoad]; }
+    bool isStore()        const { return flags[IsStore]; }
+    bool isStoreConditional()     const { return flags[IsStoreConditional]; }
     bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
     bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
-    bool isCopy()         const { return flags[IsCopy];}
+    bool isPrefetch()     const { return isInstPrefetch() ||
+                                         isDataPrefetch(); }
 
-    bool isInteger()     const { return flags[IsInteger]; }
-    bool isFloating()    const { return flags[IsFloating]; }
+    bool isInteger()      const { return flags[IsInteger]; }
+    bool isFloating()     const { return flags[IsFloating]; }
 
-    bool isControl()     const { return flags[IsControl]; }
-    bool isCall()        const { return flags[IsCall]; }
-    bool isReturn()      const { return flags[IsReturn]; }
-    bool isDirectCtrl()          const { return flags[IsDirectControl]; }
+    bool isControl()      const { return flags[IsControl]; }
+    bool isCall()         const { return flags[IsCall]; }
+    bool isReturn()       const { return flags[IsReturn]; }
+    bool isDirectCtrl()   const { return flags[IsDirectControl]; }
     bool isIndirectCtrl() const { return flags[IsIndirectControl]; }
-    bool isCondCtrl()    const { return flags[IsCondControl]; }
-    bool isUncondCtrl()          const { return flags[IsUncondControl]; }
+    bool isCondCtrl()     const { return flags[IsCondControl]; }
+    bool isUncondCtrl()   const { return flags[IsUncondControl]; }
     bool isCondDelaySlot() const { return flags[IsCondDelaySlot]; }
 
     bool isThreadSync()   const { return flags[IsThreadSync]; }
@@ -236,12 +242,14 @@ class StaticInstBase : public RefCounted
                                       flags[IsSerializeAfter]; }
     bool isSerializeBefore() const { return flags[IsSerializeBefore]; }
     bool isSerializeAfter() const { return flags[IsSerializeAfter]; }
+    bool isSquashAfter() const { return flags[IsSquashAfter]; }
     bool isMemBarrier()   const { return flags[IsMemBarrier]; }
     bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
     bool isNonSpeculative() const { return flags[IsNonSpeculative]; }
     bool isQuiesce() const { return flags[IsQuiesce]; }
     bool isIprAccess() const { return flags[IsIprAccess]; }
     bool isUnverifiable() const { return flags[IsUnverifiable]; }
+    bool isSyscall() const { return flags[IsSyscall]; }
     bool isMacroop() const { return flags[IsMacroop]; }
     bool isMicroop() const { return flags[IsMicroop]; }
     bool isDelayedCommit() const { return flags[IsDelayedCommit]; }
@@ -251,36 +259,12 @@ class StaticInstBase : public RefCounted
     bool isMicroBranch() const { return flags[IsMicroBranch]; }
     //@}
 
+    void setLastMicroop() { flags[IsLastMicroop] = true; }
+    void setDelayedCommit() { flags[IsDelayedCommit] = true; }
+    void setFlag(Flags f) { flags[f] = true; }
+
     /// Operation class.  Used to select appropriate function unit in issue.
     OpClass opClass()     const { return _opClass; }
-};
-
-
-// forward declaration
-class StaticInstPtr;
-
-/**
- * Generic yet ISA-dependent static instruction class.
- *
- * This class builds on StaticInstBase, defining fields and interfaces
- * that are generic across all ISAs but that differ in details
- * according to the specific ISA being used.
- */
-class StaticInst : public StaticInstBase
-{
-  public:
-
-    /// Binary machine instruction type.
-    typedef TheISA::MachInst MachInst;
-    /// Binary extended machine instruction type.
-    typedef TheISA::ExtMachInst ExtMachInst;
-    /// Logical register index type.
-    typedef TheISA::RegIndex RegIndex;
-
-    enum {
-        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,       //< Max source regs
-        MaxInstDestRegs = TheISA::MaxInstDestRegs,     //< Max dest regs
-    };
 
 
     /// Return logical index (architectural reg num) of i'th destination reg.
@@ -345,19 +329,18 @@ class StaticInst : public StaticInstBase
     generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
 
     /// Constructor.
+    /// It's important to initialize everything here to a sane
+    /// default, since the decoder generally only overrides
+    /// the fields that are meaningful for the particular
+    /// instruction.
     StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass)
-        : StaticInstBase(__opClass),
+        : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
+          _numFPDestRegs(0), _numIntDestRegs(0),
           machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
-    {
-    }
+    { }
 
   public:
-
-    virtual ~StaticInst()
-    {
-        if (cachedDisassembly)
-            delete cachedDisassembly;
-    }
+    virtual ~StaticInst();
 
 /**
  * The execute() signatures are auto-generated by scons based on the
@@ -365,23 +348,20 @@ class StaticInst : public StaticInstBase
  */
 #include "cpu/static_inst_exec_sigs.hh"
 
+    virtual void advancePC(TheISA::PCState &pcState) const = 0;
+
     /**
      * Return the microop that goes with a particular micropc. This should
      * only be defined/used in macroops which will contain microops
      */
-    virtual StaticInstPtr fetchMicroop(MicroPC micropc);
+    virtual StaticInstPtr fetchMicroop(MicroPC upc) const;
 
     /**
      * Return the target address for a PC-relative branch.
      * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
      * should be true).
      */
-    virtual Addr branchTarget(Addr branchPC) const
-    {
-        panic("StaticInst::branchTarget() called on instruction "
-              "that is not a PC-relative branch.");
-        M5_DUMMY_RETURN
-    }
+    virtual TheISA::PCState branchTarget(const TheISA::PCState &pc) const;
 
     /**
      * Return the target address for an indirect branch (jump).  The
@@ -390,18 +370,14 @@ class StaticInst : public StaticInstBase
      * execute the branch in question.  Invalid if not an indirect
      * branch (i.e. isIndirectCtrl() should be true).
      */
-    virtual Addr branchTarget(ThreadContext *tc) const
-    {
-        panic("StaticInst::branchTarget() called on instruction "
-              "that is not an indirect branch.");
-    }
-        M5_DUMMY_RETURN
+    virtual TheISA::PCState branchTarget(ThreadContext *tc) const;
 
     /**
      * Return true if the instruction is a control transfer, and if so,
      * return the target address as well.
      */
-    bool hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const;
+    bool hasBranchTarget(const TheISA::PCState &pc, ThreadContext *tc,
+                         TheISA::PCState &tgt) const;
 
     /**
      * Return string representation of disassembled instruction.
@@ -411,102 +387,10 @@ class StaticInst : public StaticInstBase
      * should not be cached, this function should be overridden directly.
      */
     virtual const std::string &disassemble(Addr pc,
-                                           const SymbolTable *symtab = 0) const
-    {
-        if (!cachedDisassembly)
-            cachedDisassembly =
-                new std::string(generateDisassembly(pc, symtab));
-
-        return *cachedDisassembly;
-    }
-
-    /// Decoded instruction cache type.
-    /// For now we're using a generic hash_map; this seems to work
-    /// pretty well.
-    typedef m5::hash_map<ExtMachInst, StaticInstPtr> DecodeCache;
-
-    /// A cache of decoded instruction objects.
-    static DecodeCache decodeCache;
-
-    /**
-     * Dump some basic stats on the decode cache hash map.
-     * Only gets called if DECODE_CACHE_HASH_STATS is defined.
-     */
-    static void dumpDecodeCacheStats();
-
-    /// Decode a machine instruction.
-    /// @param mach_inst The binary instruction to decode.
-    /// @retval A pointer to the corresponding StaticInst object.
-    //This is defined as inline below.
-    static StaticInstPtr decode(ExtMachInst mach_inst);
+        const SymbolTable *symtab = 0) const;
 
     /// Return name of machine instruction
     std::string getName() { return mnemonic; }
 };
 
-typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
-
-/// Reference-counted pointer to a StaticInst object.
-/// This type should be used instead of "StaticInst *" so that
-/// StaticInst objects can be properly reference-counted.
-class StaticInstPtr : public RefCountingPtr<StaticInst>
-{
-  public:
-    /// Constructor.
-    StaticInstPtr()
-        : RefCountingPtr<StaticInst>()
-    {
-    }
-
-    /// Conversion from "StaticInst *".
-    StaticInstPtr(StaticInst *p)
-        : RefCountingPtr<StaticInst>(p)
-    {
-    }
-
-    /// Copy constructor.
-    StaticInstPtr(const StaticInstPtr &r)
-        : RefCountingPtr<StaticInst>(r)
-    {
-    }
-
-    /// Construct directly from machine instruction.
-    /// Calls StaticInst::decode().
-    explicit StaticInstPtr(TheISA::ExtMachInst mach_inst)
-        : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
-    {
-    }
-
-    /// Convert to pointer to StaticInstBase class.
-    operator const StaticInstBasePtr()
-    {
-        return this->get();
-    }
-};
-
-inline StaticInstPtr
-StaticInst::decode(StaticInst::ExtMachInst mach_inst)
-{
-#ifdef DECODE_CACHE_HASH_STATS
-    // Simple stats on decode hash_map.  Turns out the default
-    // hash function is as good as anything I could come up with.
-    const int dump_every_n = 10000000;
-    static int decodes_til_dump = dump_every_n;
-
-    if (--decodes_til_dump == 0) {
-        dumpDecodeCacheStats();
-        decodes_til_dump = dump_every_n;
-    }
-#endif
-
-    DecodeCache::iterator iter = decodeCache.find(mach_inst);
-    if (iter != decodeCache.end()) {
-        return iter->second;
-    }
-
-    StaticInstPtr si = TheISA::decodeInst(mach_inst);
-    decodeCache[mach_inst] = si;
-    return si;
-}
-
 #endif // __CPU_STATIC_INST_HH__