diff options
Diffstat (limited to 'src/cpu/static_inst.hh')
-rw-r--r-- | src/cpu/static_inst.hh | 160 |
1 files changed, 146 insertions, 14 deletions
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index a58ac85d6..b0a19c151 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -63,6 +63,7 @@ class AtomicSimpleCPU; class TimingSimpleCPU; class InorderCPU; class SymbolTable; +class AddrDecodePage; namespace Trace { class InstRecord; @@ -143,11 +144,11 @@ class StaticInstBase : public RefCounted IsUnverifiable, ///< Can't be verified by a checker //Flags for microcode - IsMacroOp, ///< Is a macroop containing microops - IsMicroOp, ///< Is a microop + 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 + 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 @@ -242,11 +243,11 @@ 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 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]; } //@} @@ -349,6 +350,7 @@ class StaticInst : public StaticInstBase : StaticInstBase(__opClass), machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0) { + memset(&recentDecodes, 0, 2 * sizeof(cacheElement)); } public: @@ -369,7 +371,7 @@ 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. @@ -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; } |