inorder cpu: add missing DPRINTF argument
[gem5.git] / src / cpu / decode_cache.hh
index 6ed820332adb311ff99bf7cd8bb91679b9a9f734..34387419fb0807021b0a9a98955a8b34dc7ceb58 100644 (file)
 #include "arch/types.hh"
 #include "base/hashmap.hh"
 #include "config/the_isa.hh"
-#include "cpu/static_inst.hh"
+#include "cpu/static_inst_fwd.hh"
 
-typedef StaticInstPtr (*DecodeInstFunc)(TheISA::ExtMachInst);
+namespace TheISA
+{
+    class Decoder;
+}
 
-template <DecodeInstFunc decodeInstFunc>
-class DecodeCache
+namespace DecodeCache
 {
-  private:
-    typedef TheISA::ExtMachInst ExtMachInst;
 
-    /// Hash of decoded instructions.
-    typedef m5::hash_map<ExtMachInst, StaticInstPtr> InstMap;
-    InstMap instMap;
-    struct DecodePage {
-        StaticInstPtr insts[TheISA::PageBytes];
-    };
+/// Hash for decoded instructions.
+typedef m5::hash_map<TheISA::ExtMachInst, StaticInstPtr> InstMap;
 
-    /// A store of DecodePages. Basically a slightly smarter hash_map.
-    class DecodePages
+/// A sparse map from an Addr to a Value, stored in page chunks.
+template<class Value>
+class AddrMap
+{
+  protected:
+    // A pages worth of cache entries.
+    struct CachePage {
+        Value items[TheISA::PageBytes];
+    };
+    // A map of cache pages which allows a sparse mapping.
+    typedef typename m5::hash_map<Addr, CachePage *> PageMap;
+    typedef typename PageMap::iterator PageIt;
+    // Mini cache of recent lookups.
+    PageIt recent[2];
+    PageMap pageMap;
+
+    /// Update the mini cache of recent lookups.
+    /// @param recentest The most recent result;
+    void
+    update(PageIt recentest)
     {
-      protected:
-        typedef typename m5::hash_map<Addr, DecodePage *> PageMap;
-        typedef typename PageMap::iterator PageIt;
-        PageIt recent[2];
-        PageMap pageMap;
-
-        /// Update the small cache of recent lookups.
-        /// @param recentest The most recent result;
-        void
-        update(PageIt recentest)
-        {
-            recent[1] = recent[0];
-            recent[0] = recentest;
-        }
+        recent[1] = recent[0];
+        recent[0] = recentest;
+    }
 
-        void
-        addPage(Addr addr, DecodePage *page)
-        {
-            Addr page_addr = addr & ~(TheISA::PageBytes - 1);
-            typename PageMap::value_type to_insert(page_addr, page);
-            update(pageMap.insert(to_insert).first);
+    /// Attempt to find the CacheePage which goes with a particular
+    /// address. First check the small cache of recent results, then
+    /// actually look in the hash_map.
+    /// @param addr The address to look up.
+    CachePage *
+    getPage(Addr addr)
+    {
+        Addr page_addr = addr & ~(TheISA::PageBytes - 1);
+
+        // Check against recent lookups.
+        if (recent[0] != pageMap.end()) {
+            if (recent[0]->first == page_addr)
+                return recent[0]->second;
+            if (recent[1] != pageMap.end() &&
+                    recent[1]->first == page_addr) {
+                update(recent[1]);
+                // recent[1] has just become recent[0].
+                return recent[0]->second;
+            }
         }
 
-      public:
-        /// Constructor
-        DecodePages()
-        {
-            recent[0] = recent[1] = pageMap.end();
+        // Actually look in the has_map.
+        PageIt it = pageMap.find(page_addr);
+        if (it != pageMap.end()) {
+            update(it);
+            return it->second;
         }
 
-        /// Attempt to find the DecodePage which goes with a particular
-        /// address. First check the small cache of recent results, then
-        /// actually look in the hash_map.
-        /// @param addr The address to look up.
-        DecodePage *
-        getPage(Addr addr)
-        {
-            Addr page_addr = addr & ~(TheISA::PageBytes - 1);
-
-            // Check against recent lookups.
-            if (recent[0] != pageMap.end()) {
-                if (recent[0]->first == page_addr)
-                    return recent[0]->second;
-                if (recent[1] != pageMap.end() &&
-                        recent[1]->first == page_addr) {
-                    update(recent[1]);
-                    // recent[1] has just become recent[0].
-                    return recent[0]->second;
-                }
-            }
-
-            // Actually look in the has_map.
-            PageIt it = pageMap.find(page_addr);
-            if (it != pageMap.end()) {
-                update(it);
-                return it->second;
-            }
-
-            // Didn't find an existing page, so add a new one.
-            DecodePage *newPage = new DecodePage;
-            addPage(page_addr, newPage);
-            return newPage;
-        }
-    } decodePages;
+        // Didn't find an existing page, so add a new one.
+        CachePage *newPage = new CachePage;
+        page_addr = page_addr & ~(TheISA::PageBytes - 1);
+        typename PageMap::value_type to_insert(page_addr, newPage);
+        update(pageMap.insert(to_insert).first);
+        return newPage;
+    }
 
   public:
-    /// Decode a machine instruction.
-    /// @param mach_inst The binary instruction to decode.
-    /// @retval A pointer to the corresponding StaticInst object.
-    StaticInstPtr
-    decode(ExtMachInst mach_inst, Addr addr)
+    /// Constructor
+    AddrMap()
     {
-        // Try to find a matching address based table of instructions.
-        DecodePage *page = decodePages.getPage(addr);
-
-        // Use the table to decode the instruction. It will fall back to other
-        // mechanisms if it needs to.
-        Addr offset = addr & (TheISA::PageBytes - 1);
-        StaticInstPtr si = page->insts[offset];
-        if (si && (si->machInst == mach_inst))
-            return si;
-
-        InstMap::iterator iter = instMap.find(mach_inst);
-        if (iter != instMap.end()) {
-            si = iter->second;
-            page->insts[offset] = si;
-            return si;
-        }
+        recent[0] = recent[1] = pageMap.end();
+    }
 
-        si = decodeInstFunc(mach_inst);
-        instMap[mach_inst] = si;
-        page->insts[offset] = si;
-        return si;
+    Value &
+    lookup(Addr addr)
+    {
+        CachePage *page = getPage(addr);
+        return page->items[addr & (TheISA::PageBytes - 1)];
     }
 };
 
+} // namespace DecodeCache
+
 #endif // __CPU_DECODE_CACHE_HH__