types: clean up types, especially signed vs unsigned
[gem5.git] / src / cpu / static_inst.hh
index a58ac85d61b84b938e50240e57674a6187530b00..b1298e0e9ec5e2607e36903a5418fa88250a9dc9 100644 (file)
 
 #include "arch/isa_traits.hh"
 #include "arch/utility.hh"
-#include "sim/faults.hh"
 #include "base/bitfield.hh"
 #include "base/hashmap.hh"
 #include "base/misc.hh"
 #include "base/refcnt.hh"
+#include "base/types.hh"
 #include "cpu/op_class.hh"
-#include "cpu/o3/dyn_inst.hh"
 #include "sim/faults.hh"
-#include "sim/host.hh"
+#include "sim/faults.hh"
 
 // forward declarations
 struct AlphaSimpleImpl;
@@ -54,8 +53,11 @@ class ThreadContext;
 class DynInst;
 class Packet;
 
-template <class Impl>
-class OzoneDynInst;
+class O3CPUImpl;
+template <class Impl> class BaseO3DynInst;
+typedef BaseO3DynInst<O3CPUImpl> O3DynInst;
+template <class Impl> class OzoneDynInst;
+class InOrderDynInst;
 
 class CheckerCPU;
 class FastCPU;
@@ -63,12 +65,33 @@ class AtomicSimpleCPU;
 class TimingSimpleCPU;
 class InorderCPU;
 class SymbolTable;
+class AddrDecodePage;
 
 namespace Trace {
     class InstRecord;
 }
 
-typedef uint32_t MicroPC;
+typedef uint16_t MicroPC;
+
+static const MicroPC MicroPCRomBit = 1 << (sizeof(MicroPC) * 8 - 1);
+
+static inline MicroPC
+romMicroPC(MicroPC upc)
+{
+    return upc | MicroPCRomBit;
+}
+
+static inline MicroPC
+normalMicroPC(MicroPC upc)
+{
+    return upc & ~MicroPCRomBit;
+}
+
+static inline bool
+isRomMicroPC(MicroPC upc)
+{
+    return MicroPCRomBit & upc;
+}
 
 /**
  * Base, ISA-independent static instruction class.
@@ -104,37 +127,40 @@ 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.
+        IsIndexed,      ///< Accesses memory with an indexed address computation
+        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.
+        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,14 +168,18 @@ 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
+        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
         //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,
 
         NumFlags
     };
@@ -208,26 +238,26 @@ class StaticInstBase : public RefCounted
     /// 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 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]; }
@@ -242,15 +272,17 @@ class StaticInstBase : public RefCounted
     bool isQuiesce() const { return flags[IsQuiesce]; }
     bool isIprAccess() const { return flags[IsIprAccess]; }
     bool isUnverifiable() const { return flags[IsUnverifiable]; }
-    bool isMacroOp() const { return flags[IsMacroOp]; }
-    bool isMicroOp() const { return flags[IsMicroOp]; }
+    bool isSyscall() const { return flags[IsSyscall]; }
+    bool isMacroop() const { return flags[IsMacroop]; }
+    bool isMicroop() const { return flags[IsMicroop]; }
     bool isDelayedCommit() const { return flags[IsDelayedCommit]; }
-    bool isLastMicroOp() const { return flags[IsLastMicroOp]; }
-    bool isFirstMicroOp() const { return flags[IsFirstMicroOp]; }
+    bool isLastMicroop() const { return flags[IsLastMicroop]; }
+    bool isFirstMicroop() const { return flags[IsFirstMicroop]; }
     //This flag doesn't do anything yet
     bool isMicroBranch() const { return flags[IsMicroBranch]; }
     //@}
 
+    void setLastMicroop() { flags[IsLastMicroop] = true; }
     /// Operation class.  Used to select appropriate function unit in issue.
     OpClass opClass()     const { return _opClass; }
 };
@@ -278,8 +310,8 @@ class StaticInst : public StaticInstBase
     typedef TheISA::RegIndex RegIndex;
 
     enum {
-        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,       //< Max source regs
-        MaxInstDestRegs = TheISA::MaxInstDestRegs,     //< Max dest regs
+        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,        //< Max source regs
+        MaxInstDestRegs = TheISA::MaxInstDestRegs,      //< Max dest regs
     };
 
 
@@ -348,16 +380,10 @@ class StaticInst : public StaticInstBase
     StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass)
         : StaticInstBase(__opClass),
           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
@@ -369,19 +395,14 @@ class StaticInst : public StaticInstBase
      * 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 micropc);
 
     /**
      * 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 Addr branchTarget(Addr branchPC) const;
 
     /**
      * Return the target address for an indirect branch (jump).  The
@@ -390,12 +411,7 @@ 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 Addr branchTarget(ThreadContext *tc) const;
 
     /**
      * Return true if the instruction is a control transfer, and if so,
@@ -411,14 +427,7 @@ 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;
-    }
+        const SymbolTable *symtab = 0) const;
 
     /// Decoded instruction cache type.
     /// For now we're using a generic hash_map; this seems to work
@@ -437,11 +446,55 @@ class StaticInst : public StaticInstBase
     /// 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);
+    //This is defined as inlined below.
+    static StaticInstPtr decode(ExtMachInst mach_inst, Addr addr);
 
     /// Return name of machine instruction
     std::string getName() { return mnemonic; }
+
+    /// Decoded instruction cache type, for address decoding.
+    /// A generic hash_map is used.
+    typedef m5::hash_map<Addr, AddrDecodePage *> AddrDecodeCache;
+
+    /// A cache of decoded instruction objects from addresses.
+    static AddrDecodeCache addrDecodeCache;
+
+    struct cacheElement
+    {
+        Addr page_addr;
+        AddrDecodePage *decodePage;
+
+        cacheElement() : decodePage(NULL) { }
+    };
+
+    /// An array of recently decoded instructions.
+    // might not use an array if there is only two elements
+    static struct cacheElement recentDecodes[2];
+
+    /// Updates the recently decoded instructions entries
+    /// @param page_addr The page address recently used.
+    /// @param decodePage Pointer to decoding page containing the decoded
+    ///                   instruction.
+    static inline void
+    updateCache(Addr page_addr, AddrDecodePage *decodePage)
+    {
+        recentDecodes[1].page_addr = recentDecodes[0].page_addr;
+        recentDecodes[1].decodePage = recentDecodes[0].decodePage;
+        recentDecodes[0].page_addr = page_addr;
+        recentDecodes[0].decodePage = decodePage;
+    }
+
+    /// Searches the decoded instruction cache for instruction decoding.
+    /// If it is not found, then we decode the instruction.
+    /// Otherwise, we get the instruction from the cache and move it into
+    /// the address-to-instruction decoding page.
+    /// @param mach_inst The binary instruction to decode.
+    /// @param addr The address that contained the binary instruction.
+    /// @param decodePage Pointer to decoding page containing the instruction.
+    /// @retval A pointer to the corresponding StaticInst object.
+    //This is defined as inlined below.
+    static StaticInstPtr searchCache(ExtMachInst mach_inst, Addr addr,
+                                     AddrDecodePage *decodePage);
 };
 
 typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
@@ -472,8 +525,8 @@ class StaticInstPtr : public RefCountingPtr<StaticInst>
 
     /// Construct directly from machine instruction.
     /// Calls StaticInst::decode().
-    explicit StaticInstPtr(TheISA::ExtMachInst mach_inst)
-        : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
+    explicit StaticInstPtr(TheISA::ExtMachInst mach_inst, Addr addr)
+        : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst, addr))
     {
     }
 
@@ -484,8 +537,60 @@ class StaticInstPtr : public RefCountingPtr<StaticInst>
     }
 };
 
+/// A page of a list of decoded instructions from an address.
+class AddrDecodePage
+{
+  typedef TheISA::ExtMachInst ExtMachInst;
+  protected:
+    StaticInstPtr instructions[TheISA::PageBytes];
+    bool valid[TheISA::PageBytes];
+    Addr lowerMask;
+
+  public:
+    /// Constructor
+    AddrDecodePage()
+    {
+        lowerMask = TheISA::PageBytes - 1;
+        memset(valid, 0, TheISA::PageBytes);
+    }
+
+    /// Checks if the instruction is already decoded and the machine
+    /// instruction in the cache matches the current machine instruction
+    /// related to the address
+    /// @param mach_inst The binary instruction to check
+    /// @param addr The address containing the instruction
+    bool
+    decoded(ExtMachInst mach_inst, Addr addr)
+    {
+        return (valid[addr & lowerMask] &&
+                (instructions[addr & lowerMask]->machInst == mach_inst));
+    }
+
+    /// Returns the instruction object. decoded should be called first
+    /// to check if the instruction is valid.
+    /// @param addr The address of the instruction.
+    /// @retval A pointer to the corresponding StaticInst object.
+    StaticInstPtr
+    getInst(Addr addr)
+    {
+        return instructions[addr & lowerMask];
+    }
+
+    /// Inserts a pointer to a StaticInst object into the list of decoded
+    /// instructions on the page.
+    /// @param addr The address of the instruction.
+    /// @param si A pointer to the corresponding StaticInst object.
+    void
+    insert(Addr addr, StaticInstPtr &si)
+    {
+        instructions[addr & lowerMask] = si;
+        valid[addr & lowerMask] = true;
+    }
+};
+
+
 inline StaticInstPtr
-StaticInst::decode(StaticInst::ExtMachInst mach_inst)
+StaticInst::decode(StaticInst::ExtMachInst mach_inst, Addr addr)
 {
 #ifdef DECODE_CACHE_HASH_STATS
     // Simple stats on decode hash_map.  Turns out the default
@@ -499,12 +604,54 @@ StaticInst::decode(StaticInst::ExtMachInst mach_inst)
     }
 #endif
 
+    Addr page_addr = addr & ~(TheISA::PageBytes - 1);
+
+    // checks recently decoded addresses
+    if (recentDecodes[0].decodePage &&
+        page_addr == recentDecodes[0].page_addr) {
+        if (recentDecodes[0].decodePage->decoded(mach_inst, addr))
+            return recentDecodes[0].decodePage->getInst(addr);
+
+        return searchCache(mach_inst, addr, recentDecodes[0].decodePage);
+    }
+
+    if (recentDecodes[1].decodePage &&
+        page_addr == recentDecodes[1].page_addr) {
+        if (recentDecodes[1].decodePage->decoded(mach_inst, addr))
+            return recentDecodes[1].decodePage->getInst(addr);
+
+        return searchCache(mach_inst, addr, recentDecodes[1].decodePage);
+    }
+
+    // searches the page containing the address to decode
+    AddrDecodeCache::iterator iter = addrDecodeCache.find(page_addr);
+    if (iter != addrDecodeCache.end()) {
+        updateCache(page_addr, iter->second);
+        if (iter->second->decoded(mach_inst, addr))
+            return iter->second->getInst(addr);
+
+        return searchCache(mach_inst, addr, iter->second);
+    }
+
+    // creates a new object for a page of decoded instructions
+    AddrDecodePage *decodePage = new AddrDecodePage;
+    addrDecodeCache[page_addr] = decodePage;
+    updateCache(page_addr, decodePage);
+    return searchCache(mach_inst, addr, decodePage);
+}
+
+inline StaticInstPtr
+StaticInst::searchCache(ExtMachInst mach_inst, Addr addr,
+                        AddrDecodePage *decodePage)
+{
     DecodeCache::iterator iter = decodeCache.find(mach_inst);
     if (iter != decodeCache.end()) {
+        decodePage->insert(addr, iter->second);
         return iter->second;
     }
 
     StaticInstPtr si = TheISA::decodeInst(mach_inst);
+    decodePage->insert(addr, si);
     decodeCache[mach_inst] = si;
     return si;
 }