static_inst.hh
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 654 行 · 第 1/2 页
HH
654 行
protected: /// See destRegIdx(). RegIndex _destRegIdx[MaxInstDestRegs]; /// See srcRegIdx(). RegIndex _srcRegIdx[MaxInstSrcRegs]; /** * Base mnemonic (e.g., "add"). Used by generateDisassembly() * methods. Also useful to readily identify instructions from * within the debugger when #cachedDisassembly has not been * initialized. */ const char *mnemonic; /** * String representation of disassembly (lazily evaluated via * disassemble()). */ mutable std::string *cachedDisassembly; /** * Internal function to generate disassembly string. */ virtual std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0; /// Constructor. StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass) : StaticInstBase(__opClass), machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0) { } public: virtual ~StaticInst() { if (cachedDisassembly) delete cachedDisassembly; }/** * The execute() signatures are auto-generated by scons based on the * set of CPU models we are compiling in today. */#include "cpu/static_inst_exec_sigs.hh" /** * 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); /** * 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 } /** * Return the target address for an indirect branch (jump). The * register value is read from the supplied thread context, so * the result is valid only if the thread context is about to * 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 } /** * Return true if the instruction is a control transfer, and if so, * return the target address as well. */ bool hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const; /** * Return string representation of disassembled instruction. * The default version of this function will call the internal * virtual generateDisassembly() function to get the string, * then cache it in #cachedDisassembly. If the disassembly * 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; } /// 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;/// Reference-counted pointer to a StaticInst object./// This type should be used instead of "StaticInst *" so that/// StaticInst objects can be properly reference-counted.class StaticInstPtr : public RefCountingPtr<StaticInst>{ public: /// Constructor. StaticInstPtr() : RefCountingPtr<StaticInst>() { } /// Conversion from "StaticInst *". StaticInstPtr(StaticInst *p) : RefCountingPtr<StaticInst>(p) { } /// Copy constructor. StaticInstPtr(const StaticInstPtr &r) : RefCountingPtr<StaticInst>(r) { } /// 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() { return this->get(); }};/// 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 StaticInstPtrStaticInst::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 StaticInstPtrStaticInst::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__
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?