Modified instruction decode method.
authorVincentius Robby <acolyte@umich.edu>
Thu, 14 Jun 2007 20:52:19 +0000 (16:52 -0400)
committerVincentius Robby <acolyte@umich.edu>
Thu, 14 Jun 2007 20:52:19 +0000 (16:52 -0400)
Make code compatible with new decode method.

src/arch/alpha/remote_gdb.cc:
src/cpu/base_dyn_inst_impl.hh:
src/cpu/exetrace.cc:
src/cpu/simple/base.cc:
    Make code compatible with new decode method.
src/cpu/static_inst.cc:
src/cpu/static_inst.hh:
    Modified instruction decode method.

--HG--
extra : convert_revision : a9a6d3a16fff59bc95d0606ea344bd57e71b8d0a

src/arch/alpha/remote_gdb.cc
src/cpu/base_dyn_inst_impl.hh
src/cpu/exetrace.cc
src/cpu/simple/base.cc
src/cpu/static_inst.cc
src/cpu/static_inst.hh

index a68e5218ea773740ac26d35b8938828421151478..ea5db36f487b5cca0607f4a462787ebcbfa55bfc 100644 (file)
@@ -284,7 +284,7 @@ RemoteGDB::setSingleStep()
     // User was stopped at pc, e.g. the instruction at pc was not
     // executed.
     MachInst inst = read<MachInst>(pc);
-    StaticInstPtr si(inst);
+    StaticInstPtr si(inst, pc);
     if (si->hasBranchTarget(pc, context, bpc)) {
         // Don't bother setting a breakpoint on the taken branch if it
         // is the same as the next pc
index a1c866336c747f70dc84b7a592f3cebbc3a6612e..216cc08ea7757963d5040b57bd20a1009e7fc700 100644 (file)
@@ -66,7 +66,7 @@ BaseDynInst<Impl>::BaseDynInst(TheISA::ExtMachInst machInst,
                                Addr inst_PC, Addr inst_NPC,
                                Addr pred_PC, Addr pred_NPC,
                                InstSeqNum seq_num, ImplCPU *cpu)
-  : staticInst(machInst), traceData(NULL), cpu(cpu)
+  : staticInst(machInst, inst_PC), traceData(NULL), cpu(cpu)
 {
     seqNum = seq_num;
 
index 98b8c247ccf82dd61c86d08ef18443f5c2ad9704..9b87f2e8ae61bcef074e4a1ecd4865a56b638fa5 100644 (file)
@@ -656,7 +656,7 @@ Trace::InstRecord::dump()
                         assert(predecoder.extMachInstReady());
 
                         StaticInstPtr legionInst =
-                            StaticInst::decode(predecoder.getExtMachInst());
+                            StaticInst::decode(predecoder.getExtMachInst(), lgnPc);
                         outs << setfill(' ') << setw(15)
                              << " Legion Inst: "
                              << "0x" << setw(8) << setfill('0') << hex
index b97eabf3341ef290842d50c19f2cfe8b039b9789..b7f60522fc6618e962bc282339fa83bfb1473535 100644 (file)
@@ -392,7 +392,8 @@ BaseSimpleCPU::preExecute()
             thread->setNextPC(thread->readPC() + predecoder.getInstSize());
 #endif // X86_ISA
             stayAtPC = false;
-            instPtr = StaticInst::decode(predecoder.getExtMachInst());
+            instPtr = StaticInst::decode(predecoder.getExtMachInst(),
+                                         thread->readPC());
         } else {
             stayAtPC = true;
             fetchOffset += sizeof(MachInst);
@@ -437,7 +438,7 @@ BaseSimpleCPU::postExecute()
     if (thread->profile) {
         bool usermode = TheISA::inUserMode(tc);
         thread->profilePC = usermode ? 1 : thread->readPC();
-        StaticInstPtr si(inst);
+        StaticInstPtr si(inst, thread->readPC());
         ProfileNode *node = thread->profile->consume(tc, si);
         if (node)
             thread->profileNode = node;
index a5580d7075c4cb7254a6d4ed5ef12299aa5dc976..52a7ede03a6a96566586c3ba93a2fcb829e4e6f4 100644 (file)
@@ -37,6 +37,8 @@ StaticInstPtr StaticInst::nullStaticInstPtr;
 
 // Define the decode cache hash map.
 StaticInst::DecodeCache StaticInst::decodeCache;
+StaticInst::AddrDecodeCache StaticInst::addrDecodeCache;
+StaticInst::cacheElement StaticInst::recentDecodes[2];
 
 void
 StaticInst::dumpDecodeCacheStats()
index b11e74c6e887561ec3dc1094d6f2b1e5e93c1eb0..b0a19c151fe8a85442ff6c3fc7ad71eb71220eb2 100644 (file)
@@ -63,6 +63,7 @@ class AtomicSimpleCPU;
 class TimingSimpleCPU;
 class InorderCPU;
 class SymbolTable;
+class AddrDecodePage;
 
 namespace Trace {
     class InstRecord;
@@ -349,6 +350,7 @@ class StaticInst : public StaticInstBase
         : StaticInstBase(__opClass),
           machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
     {
+        memset(&recentDecodes, 0, 2 * sizeof(cacheElement));
     }
 
   public:
@@ -437,11 +439,52 @@ 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;
+    } ;
+
+    /// 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 +515,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 +527,55 @@ 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
+    inline 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.
+    inline 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.
+    inline 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 +589,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;
 }