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 + -
显示快捷键?