diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/SConscript | 1 | ||||
-rw-r--r-- | src/cpu/decode.cc | 33 | ||||
-rw-r--r-- | src/cpu/decode.hh | 59 | ||||
-rw-r--r-- | src/cpu/decode_cache.hh | 179 | ||||
-rw-r--r-- | src/cpu/inorder/cpu.cc | 8 | ||||
-rw-r--r-- | src/cpu/inorder/cpu.hh | 2 | ||||
-rw-r--r-- | src/cpu/inorder/inorder_dyn_inst.cc | 4 | ||||
-rw-r--r-- | src/cpu/inorder/inorder_dyn_inst.hh | 2 | ||||
-rw-r--r-- | src/cpu/inorder/resources/fetch_unit.cc | 2 | ||||
-rw-r--r-- | src/cpu/inorder/resources/fetch_unit.hh | 3 | ||||
-rw-r--r-- | src/cpu/inorder/thread_context.hh | 2 | ||||
-rw-r--r-- | src/cpu/legiontrace.cc | 5 | ||||
-rw-r--r-- | src/cpu/o3/fetch.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 11 | ||||
-rwxr-xr-x | src/cpu/o3/thread_context.hh | 2 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 2 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 1 | ||||
-rw-r--r-- | src/cpu/simple_thread.hh | 5 | ||||
-rw-r--r-- | src/cpu/static_inst.cc | 24 | ||||
-rw-r--r-- | src/cpu/static_inst.hh | 196 | ||||
-rw-r--r-- | src/cpu/thread_context.hh | 5 |
21 files changed, 317 insertions, 233 deletions
diff --git a/src/cpu/SConscript b/src/cpu/SConscript index b24866ddd..a1074cb8b 100644 --- a/src/cpu/SConscript +++ b/src/cpu/SConscript @@ -114,6 +114,7 @@ SimObject('NativeTrace.py') Source('activity.cc') Source('base.cc') Source('cpuevent.cc') +Source('decode.cc') Source('exetrace.cc') Source('func_unit.cc') Source('inteltrace.cc') diff --git a/src/cpu/decode.cc b/src/cpu/decode.cc new file mode 100644 index 000000000..56a484b07 --- /dev/null +++ b/src/cpu/decode.cc @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Google + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "cpu/decode.hh" + +DecodeCache<TheISA::decodeInst> Decoder::cache; diff --git a/src/cpu/decode.hh b/src/cpu/decode.hh new file mode 100644 index 000000000..653f8eea5 --- /dev/null +++ b/src/cpu/decode.hh @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Google + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __CPU_DECODE_HH__ +#define __CPU_DECODE_HH__ + +#include "arch/isa_traits.hh" +#include "arch/types.hh" +#include "config/the_isa.hh" +#include "cpu/decode_cache.hh" +#include "cpu/static_inst.hh" + +/// The decoder class. This class doesn't do much of anything now, but in the +/// future it will be redefinable per ISA and allow more interesting behavior. +class Decoder +{ + protected: + /// A cache of decoded instruction objects. + static DecodeCache<TheISA::decodeInst> cache; + + public: + /// Decode a machine instruction. + /// @param mach_inst The binary instruction to decode. + /// @retval A pointer to the corresponding StaticInst object. + StaticInstPtr + decode(TheISA::ExtMachInst mach_inst, Addr addr) + { + return cache.decode(mach_inst, addr); + } +}; + +#endif // __CPU_DECODE_HH__ diff --git a/src/cpu/decode_cache.hh b/src/cpu/decode_cache.hh new file mode 100644 index 000000000..1bff315d1 --- /dev/null +++ b/src/cpu/decode_cache.hh @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2011 Google + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __CPU_DECODE_CACHE_HH__ +#define __CPU_DECODE_CACHE_HH__ + +#include "arch/isa_traits.hh" +#include "arch/types.hh" +#include "base/hashmap.hh" +#include "config/the_isa.hh" +#include "cpu/static_inst.hh" + +typedef StaticInstPtr (*DecodeInstFunc)(TheISA::ExtMachInst); + +template <DecodeInstFunc decodeInstFunc> +class DecodeCache +{ + private: + typedef TheISA::ExtMachInst ExtMachInst; + + /// Hash of decoded instructions. + typedef m5::hash_map<ExtMachInst, StaticInstPtr> InstMap; + InstMap instMap; + + /// A table of instructions which are already been decoded, indexed by + /// page offset. + class DecodePage + { + protected: + StaticInstPtr instructions[TheISA::PageBytes]; + + // A helper function to compute the index of an address in the table. + Addr offset(Addr addr) { return addr & (TheISA::PageBytes - 1); } + + public: + /// Decode the given instruction. First attempt to find it in the + /// table, then in the generic decode cache, and finally call the + /// actual decode function. + /// + /// @param mach_inst The predecoded instruction to decode. + /// @param addr The address the instruction came from. + /// @param cache A cache of already decoded instructions. + /// @retval The decoded instruction object. + StaticInstPtr + decode(const ExtMachInst &mach_inst, Addr addr, InstMap &instMap) + { + StaticInstPtr si = instructions[offset(addr)]; + if (si && (si->machInst == mach_inst)) { + return si; + } + + InstMap::iterator iter = instMap.find(mach_inst); + if (iter != instMap.end()) { + si = iter->second; + } else { + si = decodeInstFunc(mach_inst); + instMap[mach_inst] = si; + } + + instructions[offset(addr)] = si; + return si; + } + }; + + /// A store of DecodePages. Basically a slightly smarter hash_map. + class DecodePages + { + 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; + } + + public: + /// Constructor + DecodePages() + { + recent[0] = recent[1] = pageMap.end(); + } + + /// 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 * + findPage(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 it so return NULL. + return NULL; + } + + 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); + } + } decodePages; + + 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) + { + // Try to find a matching address based table of instructions. + DecodePage *page = decodePages.findPage(addr); + if (!page) { + // Nothing was found, so create a new one. + page = new DecodePage; + decodePages.addPage(addr, page); + } + + // Use the table to decode the instruction. It will fall back to other + // mechanisms if it needs to. + return page->decode(mach_inst, addr, instMap); + } +}; + +#endif // __CPU_DECODE_CACHE_HH__ diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index d8552d9d3..07a013afc 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -1766,6 +1766,14 @@ InOrderCPU::getDTBPtr() return dtb_res->tlb(); } +Decoder * +InOrderCPU::getDecoderPtr() +{ + FetchUnit *fetch_res = + dynamic_cast<FetchUnit*>(resPool->getResource(fetchPortIdx)); + return &fetch_res->decoder; +} + Fault InOrderCPU::read(DynInstPtr inst, Addr addr, uint8_t *data, unsigned size, unsigned flags) diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index a5616f8b1..098909cb7 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -305,6 +305,8 @@ class InOrderCPU : public BaseCPU TheISA::TLB *getITBPtr(); TheISA::TLB *getDTBPtr(); + Decoder *getDecoderPtr(); + /** Accessor Type for the SkedCache */ typedef uint32_t SkedID; diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc index 5343206c1..f65d2ea9f 100644 --- a/src/cpu/inorder/inorder_dyn_inst.cc +++ b/src/cpu/inorder/inorder_dyn_inst.cc @@ -94,9 +94,9 @@ InOrderDynInst::cpuId() } void -InOrderDynInst::setMachInst(ExtMachInst machInst) +InOrderDynInst::setStaticInst(StaticInstPtr si) { - staticInst = StaticInst::decode(machInst, pc.instAddr()); + staticInst = si; for (int i = 0; i < this->staticInst->numDestRegs(); i++) { _destRegIdx[i] = this->staticInst->destRegIdx(i); diff --git a/src/cpu/inorder/inorder_dyn_inst.hh b/src/cpu/inorder/inorder_dyn_inst.hh index ecaf23aab..de9de5eff 100644 --- a/src/cpu/inorder/inorder_dyn_inst.hh +++ b/src/cpu/inorder/inorder_dyn_inst.hh @@ -324,7 +324,7 @@ class InOrderDynInst : public FastAlloc, public RefCounted std::string instName() { return (staticInst) ? staticInst->getName() : "undecoded-inst"; } - void setMachInst(ExtMachInst inst); + void setStaticInst(StaticInstPtr si); ExtMachInst getMachInst() { return staticInst->machInst; } diff --git a/src/cpu/inorder/resources/fetch_unit.cc b/src/cpu/inorder/resources/fetch_unit.cc index 8ba6bdc9a..b32134e00 100644 --- a/src/cpu/inorder/resources/fetch_unit.cc +++ b/src/cpu/inorder/resources/fetch_unit.cc @@ -117,7 +117,7 @@ FetchUnit::createMachInst(std::list<FetchBlock*>::iterator fetch_it, ext_inst = predecoder[tid]->getExtMachInst(instPC); inst->pcState(instPC); - inst->setMachInst(ext_inst); + inst->setStaticInst(decoder.decode(ext_inst, instPC.instAddr())); } void diff --git a/src/cpu/inorder/resources/fetch_unit.hh b/src/cpu/inorder/resources/fetch_unit.hh index 250e53e6c..6d734d7e6 100644 --- a/src/cpu/inorder/resources/fetch_unit.hh +++ b/src/cpu/inorder/resources/fetch_unit.hh @@ -39,6 +39,7 @@ #include "arch/predecoder.hh" #include "arch/tlb.hh" #include "config/the_isa.hh" +#include "cpu/decode.hh" #include "cpu/inorder/resources/cache_unit.hh" #include "cpu/inorder/inorder_dyn_inst.hh" #include "cpu/inorder/pipeline_traits.hh" @@ -88,6 +89,8 @@ class FetchUnit : public CacheUnit void trap(Fault fault, ThreadID tid, DynInstPtr inst); + Decoder decoder; + private: void squashCacheRequest(CacheReqPtr req_ptr); diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh index 3b4e8dd7f..7ec17cb77 100644 --- a/src/cpu/inorder/thread_context.hh +++ b/src/cpu/inorder/thread_context.hh @@ -78,6 +78,8 @@ class InOrderThreadContext : public ThreadContext /** @TODO: PERF: Should we bind this to a pointer in constructor? */ TheISA::TLB *getDTBPtr() { return cpu->getDTBPtr(); } + Decoder *getDecoderPtr() { return cpu->getDecoderPtr(); } + System *getSystemPtr() { return cpu->system; } /** Returns a pointer to this CPU. */ diff --git a/src/cpu/legiontrace.cc b/src/cpu/legiontrace.cc index 49b2f513c..484af1008 100644 --- a/src/cpu/legiontrace.cc +++ b/src/cpu/legiontrace.cc @@ -52,6 +52,7 @@ #include "arch/sparc/utility.hh" #include "base/socket.hh" #include "cpu/base.hh" +#include "cpu/decode.hh" #include "cpu/legiontrace.hh" #include "cpu/static_inst.hh" #include "cpu/thread_context.hh" @@ -438,8 +439,8 @@ Trace::LegionTraceRecord::dump() PCState tempPC = pc; StaticInstPtr legionInst = - StaticInst::decode(predecoder.getExtMachInst(tempPC), - lgnPc); + thread->getDecoderPtr()->decode( + predecoder.getExtMachInst(tempPC), lgnPc); outs << setfill(' ') << setw(15) << " Legion Inst: " << "0x" << setw(8) << setfill('0') << hex diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 6d93f2cc8..d09d7f680 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -48,6 +48,7 @@ #include "arch/utility.hh" #include "base/statistics.hh" #include "config/the_isa.hh" +#include "cpu/decode.hh" #include "cpu/pc_event.hh" #include "cpu/timebuf.hh" #include "cpu/translation.hh" @@ -380,6 +381,9 @@ class DefaultFetch return (addr & ~(cacheBlkMask)); } + /** The decoder. */ + Decoder decoder; + private: DynInstPtr buildInst(ThreadID tid, StaticInstPtr staticInst, StaticInstPtr curMacroop, TheISA::PCState thisPC, diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 86f5df9c7..b0ec349dc 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -725,7 +725,7 @@ DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req) DPRINTF(Fetch, "[tid:%i]: Translation faulted, building noop.\n", tid); // We will use a nop in ordier to carry the fault. DynInstPtr instruction = buildInst(tid, - StaticInstPtr(TheISA::NoopMachInst, fetchPC.instAddr()), + decoder.decode(TheISA::NoopMachInst, fetchPC.instAddr()), NULL, fetchPC, fetchPC, false); instruction->setPredTarg(fetchPC); @@ -1287,11 +1287,10 @@ DefaultFetch<Impl>::fetch(bool &status_change) do { if (!(curMacroop || inRom)) { if (predecoder.extMachInstReady()) { - ExtMachInst extMachInst; - - extMachInst = predecoder.getExtMachInst(thisPC); - staticInst = StaticInstPtr(extMachInst, - thisPC.instAddr()); + ExtMachInst extMachInst = + predecoder.getExtMachInst(thisPC); + staticInst = + decoder.decode(extMachInst, thisPC.instAddr()); // Increment stat of fetched instructions. ++fetchedInsts; diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index ef0fdbb4d..38c94439a 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -73,6 +73,8 @@ class O3ThreadContext : public ThreadContext /** Returns a pointer to the DTB. */ TheISA::TLB *getDTBPtr() { return cpu->dtb; } + Decoder *getDecoderPtr() { return &cpu->fetch.decoder; } + /** Returns a pointer to this CPU. */ virtual BaseCPU *getCpuPtr() { return cpu; } diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 699e78764..70e2c39e6 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -383,7 +383,7 @@ BaseSimpleCPU::preExecute() stayAtPC = false; ExtMachInst machInst = predecoder.getExtMachInst(pcState); thread->pcState(pcState); - instPtr = StaticInst::decode(machInst, pcState.instAddr()); + instPtr = thread->decoder.decode(machInst, pcState.instAddr()); } else { stayAtPC = true; fetchOffset += sizeof(MachInst); diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 0cc90645f..b27ebf998 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -38,6 +38,7 @@ #include "config/full_system.hh" #include "config/the_isa.hh" #include "cpu/base.hh" +#include "cpu/decode.hh" #include "cpu/pc_event.hh" #include "cpu/simple_thread.hh" #include "cpu/static_inst.hh" diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index a74616a0d..2b7b89030 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -40,6 +40,7 @@ #include "base/types.hh" #include "config/full_system.hh" #include "config/the_isa.hh" +#include "cpu/decode.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" #include "debug/FloatRegs.hh" @@ -129,6 +130,8 @@ class SimpleThread : public ThreadState TheISA::TLB *itb; TheISA::TLB *dtb; + Decoder decoder; + // constructor: initialize SimpleThread from given process structure #if FULL_SYSTEM SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, @@ -200,6 +203,8 @@ class SimpleThread : public ThreadState TheISA::TLB *getDTBPtr() { return dtb; } + Decoder *getDecoderPtr() { return &decoder; } + System *getSystemPtr() { return system; } #if FULL_SYSTEM diff --git a/src/cpu/static_inst.cc b/src/cpu/static_inst.cc index df59d1fc3..2a7b584eb 100644 --- a/src/cpu/static_inst.cc +++ b/src/cpu/static_inst.cc @@ -36,11 +36,6 @@ StaticInstPtr StaticInst::nullStaticInstPtr; -// Define the decode cache hash map. -StaticInst::DecodeCache StaticInst::decodeCache; -StaticInst::AddrDecodeCache StaticInst::addrDecodeCache; -StaticInst::cacheElement StaticInst::recentDecodes[2]; - using namespace std; StaticInst::~StaticInst() @@ -49,25 +44,6 @@ StaticInst::~StaticInst() delete cachedDisassembly; } -void -StaticInst::dumpDecodeCacheStats() -{ - cerr << "Decode hash table stats @ " << curTick() << ":" << endl; - cerr << "\tnum entries = " << decodeCache.size() << endl; - cerr << "\tnum buckets = " << decodeCache.bucket_count() << endl; - vector<int> hist(100, 0); - int max_hist = 0; - for (int i = 0; i < decodeCache.bucket_count(); ++i) { - int count = decodeCache.elems_in_bucket(i); - if (count > max_hist) - max_hist = count; - hist[count]++; - } - for (int i = 0; i <= max_hist; ++i) { - cerr << "\tbuckets of size " << i << " = " << hist[i] << endl; - } -} - bool StaticInst::hasBranchTarget(const TheISA::PCState &pc, ThreadContext *tc, TheISA::PCState &tgt) const diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh index c41ac38a6..b2773052e 100644 --- a/src/cpu/static_inst.hh +++ b/src/cpu/static_inst.hh @@ -34,10 +34,8 @@ #include <bitset> #include <string> -#include "arch/isa_traits.hh" #include "arch/registers.hh" #include "arch/types.hh" -#include "base/hashmap.hh" #include "base/misc.hh" #include "base/refcnt.hh" #include "base/types.hh" @@ -65,7 +63,6 @@ class AtomicSimpleCPU; class TimingSimpleCPU; class InorderCPU; class SymbolTable; -class AddrDecodePage; namespace Trace { class InstRecord; @@ -285,9 +282,6 @@ class StaticInstPtr; 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. @@ -416,72 +410,8 @@ class StaticInst : public StaticInstBase virtual const std::string &disassemble(Addr pc, const SymbolTable *symtab = 0) const; - /// 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 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; @@ -510,13 +440,6 @@ class StaticInstPtr : public RefCountingPtr<StaticInst> { } - /// Construct directly from machine instruction. - /// Calls StaticInst::decode(). - explicit StaticInstPtr(TheISA::ExtMachInst mach_inst, Addr addr) - : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst, addr)) - { - } - /// Convert to pointer to StaticInstBase class. operator const StaticInstBasePtr() { @@ -524,123 +447,4 @@ 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, Addr addr) -{ -#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 - - 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; -} - #endif // __CPU_STATIC_INST_HH__ diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 0f7228f0c..3b7f8b3c3 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -48,6 +48,7 @@ namespace TheISA } class BaseCPU; class Checkpoint; +class Decoder; class EndQuiesceEvent; class TranslatingPort; class FunctionalPort; @@ -120,6 +121,8 @@ class ThreadContext virtual TheISA::TLB *getDTBPtr() = 0; + virtual Decoder *getDecoderPtr() = 0; + virtual System *getSystemPtr() = 0; #if FULL_SYSTEM @@ -287,6 +290,8 @@ class ProxyThreadContext : public ThreadContext TheISA::TLB *getDTBPtr() { return actualTC->getDTBPtr(); } + Decoder *getDecoderPtr() { return actualTC->getDecoderPtr(); } + System *getSystemPtr() { return actualTC->getSystemPtr(); } #if FULL_SYSTEM |