static_inst.hh revision 1128
11689SN/A/*
213601Sgiacomo.travaglini@arm.com * Copyright (c) 2003-2004 The Regents of The University of Michigan
39919Ssteve.reinhardt@amd.com * All rights reserved.
48707Sandreas.hansson@arm.com *
58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
148707Sandreas.hansson@arm.com * this software without specific prior written permission.
151689SN/A *
167897Shestness@cs.utexas.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271689SN/A */
281689SN/A
291689SN/A#ifndef __STATIC_INST_HH__
301689SN/A#define __STATIC_INST_HH__
311689SN/A
321689SN/A#include <bitset>
331689SN/A#include <string>
341689SN/A
351689SN/A#include "sim/host.hh"
361689SN/A#include "base/hashmap.hh"
371689SN/A#include "base/refcnt.hh"
381689SN/A
391689SN/A#include "cpu/full_cpu/op_class.hh"
401689SN/A#include "targetarch/isa_traits.hh"
412665Ssaidi@eecs.umich.edu
422665Ssaidi@eecs.umich.edu// forward declarations
432756Sksewell@umich.educlass ExecContext;
447897Shestness@cs.utexas.educlass DynInst;
451689SN/Aclass FastCPU;
461689SN/Aclass SimpleCPU;
472325SN/Aclass InorderCPU;
482325SN/Aclass SymbolTable;
491060SN/A
501060SN/Anamespace Trace {
511060SN/A    class InstRecord;
522292SN/A}
532292SN/A
541681SN/A/**
551060SN/A * Base, ISA-independent static instruction class.
5612109SRekai.GonzalezAlberquilla@arm.com *
572980Sgblack@eecs.umich.edu * The main component of this class is the vector of flags and the
581060SN/A * associated methods for reading them.  Any object that can rely
596658Snate@binkert.org * solely on these flags can process instructions without being
601717SN/A * recompiled for multiple ISAs.
611717SN/A */
622292SN/Aclass StaticInstBase : public RefCounted
632292SN/A{
648229Snate@binkert.org  protected:
658229Snate@binkert.org
668229Snate@binkert.org    /// Set of boolean static instruction properties.
678229Snate@binkert.org    ///
682817Sksewell@umich.edu    /// Notes:
698229Snate@binkert.org    /// - The IsInteger and IsFloating flags are based on the class of
701060SN/A    /// registers accessed by the instruction.  Although most
711060SN/A    /// instructions will have exactly one of these two flags set, it
722316SN/A    /// is possible for an instruction to have neither (e.g., direct
732316SN/A    /// unconditional branches, memory barriers) or both (e.g., an
742680Sktlim@umich.edu    /// FP/int conversion).
752817Sksewell@umich.edu    /// - If IsMemRef is set, then exactly one of IsLoad or IsStore
762817Sksewell@umich.edu    /// will be set.
772843Sktlim@umich.edu    /// - If IsControl is set, then exactly one of IsDirectControl or
782843Sktlim@umich.edu    /// IsIndirect Control will be set, and exactly one of
791060SN/A    /// IsCondControl or IsUncondControl will be set.
801060SN/A    /// - IsSerializing, IsMemBarrier, and IsWriteBarrier are
818737Skoansin.tan@gmail.com    /// implemented as flags since in the current model there's no
825529Snate@binkert.org    /// other way for instructions to inject behavior into the
832733Sktlim@umich.edu    /// pipeline outside of fetch.  Once we go to an exec-in-exec CPU
841060SN/A    /// model we should be able to get rid of these flags and
851060SN/A    /// implement this behavior via the execute() methods.
861060SN/A    ///
875529Snate@binkert.org    enum Flags {
882292SN/A        IsNop,		///< Is a no-op (no effect at all).
892292SN/A
901060SN/A        IsInteger,	///< References integer regs.
911060SN/A        IsFloating,	///< References FP regs.
922348SN/A
932348SN/A        IsMemRef,	///< References memory (load, store, or prefetch).
942348SN/A        IsLoad,		///< Reads from memory (load or prefetch).
952348SN/A        IsStore,	///< Writes to memory.
962348SN/A        IsInstPrefetch,	///< Instruction-cache prefetch.
971060SN/A        IsDataPrefetch,	///< Data-cache prefetch.
982733Sktlim@umich.edu        IsCopy,         ///< Fast Cache block copy
991060SN/A
1001060SN/A        IsControl,		///< Control transfer instruction.
1012325SN/A        IsDirectControl,	///< PC relative control transfer.
1021060SN/A        IsIndirectControl,	///< Register indirect control transfer.
1031061SN/A        IsCondControl,		///< Conditional control transfer.
1044329Sktlim@umich.edu        IsUncondControl,	///< Unconditional control transfer.
1051060SN/A        IsCall,			///< Subroutine call.
10612109SRekai.GonzalezAlberquilla@arm.com        IsReturn,		///< Subroutine return.
10712109SRekai.GonzalezAlberquilla@arm.com
10812109SRekai.GonzalezAlberquilla@arm.com        IsThreadSync,	///< Thread synchronization operation.
10913610Sgiacomo.gabrielli@arm.com
11013610Sgiacomo.gabrielli@arm.com        IsSerializing,	///< Serializes pipeline: won't execute until all
1115595Sgblack@eecs.umich.edu                        /// older instructions have committed.
1122292SN/A        IsMemBarrier,	///< Is a memory barrier
1132292SN/A        IsWriteBarrier,	///< Is a write barrier
1142292SN/A
1152292SN/A        IsNonSpeculative, ///< Should not be executed speculatively
1162817Sksewell@umich.edu
1172829Sksewell@umich.edu        NumFlags
1181060SN/A    };
1191060SN/A
1201060SN/A    /// Flag values for this instruction.
1211060SN/A    std::bitset<NumFlags> flags;
1221060SN/A
1232307SN/A    /// See opClass().
1242307SN/A    OpClass _opClass;
1251060SN/A
1261060SN/A    /// See numSrcRegs().
12712406Sgabeblack@google.com    int8_t _numSrcRegs;
12812406Sgabeblack@google.com
12913590Srekai.gonzalezalberquilla@arm.com    /// See numDestRegs().
1303781Sgblack@eecs.umich.edu    int8_t _numDestRegs;
1312292SN/A
1321060SN/A    /// The following are used to track physical register usage
1331060SN/A    /// for machines with separate int & FP reg files.
1341060SN/A    //@{
1358707Sandreas.hansson@arm.com    int8_t _numFPDestRegs;
1362292SN/A    int8_t _numIntDestRegs;
13712127Sspwilson2@wisc.edu    //@}
1381060SN/A
13913641Sqtt2@cornell.edu    /// Constructor.
14013641Sqtt2@cornell.edu    /// It's important to initialize everything here to a sane
14113641Sqtt2@cornell.edu    /// default, since the decoder generally only overrides
1422292SN/A    /// the fields that are meaningful for the particular
1439180Sandreas.hansson@arm.com    /// instruction.
1441060SN/A    StaticInstBase(OpClass __opClass)
1451060SN/A        : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
1469179Sandreas.hansson@arm.com          _numFPDestRegs(0), _numIntDestRegs(0)
1471060SN/A    {
1489179Sandreas.hansson@arm.com    }
1491060SN/A
1501060SN/A  public:
1512292SN/A
1521060SN/A    /// @name Register information.
1531060SN/A    /// The sum of numFPDestRegs() and numIntDestRegs() equals
1541060SN/A    /// numDestRegs().  The former two functions are used to track
1551060SN/A    /// physical register usage for machines with separate int & FP
1561060SN/A    /// reg files.
1571060SN/A    //@{
1589444SAndreas.Sandberg@ARM.com    /// Number of source registers.
15910913Sandreas.sandberg@arm.com    int8_t numSrcRegs()  const { return _numSrcRegs; }
1609444SAndreas.Sandberg@ARM.com    /// Number of destination registers.
1619444SAndreas.Sandberg@ARM.com    int8_t numDestRegs() const { return _numDestRegs; }
1629444SAndreas.Sandberg@ARM.com    /// Number of floating-point destination regs.
1639444SAndreas.Sandberg@ARM.com    int8_t numFPDestRegs()  const { return _numFPDestRegs; }
1649444SAndreas.Sandberg@ARM.com    /// Number of integer destination regs.
1659444SAndreas.Sandberg@ARM.com    int8_t numIntDestRegs() const { return _numIntDestRegs; }
1669444SAndreas.Sandberg@ARM.com    //@}
1679444SAndreas.Sandberg@ARM.com
1689444SAndreas.Sandberg@ARM.com    /// @name Flag accessors.
1699444SAndreas.Sandberg@ARM.com    /// These functions are used to access the values of the various
1709444SAndreas.Sandberg@ARM.com    /// instruction property flags.  See StaticInstBase::Flags for descriptions
1719444SAndreas.Sandberg@ARM.com    /// of the individual flags.
1729444SAndreas.Sandberg@ARM.com    //@{
1739444SAndreas.Sandberg@ARM.com
1749444SAndreas.Sandberg@ARM.com    bool isNop() 	  const { return flags[IsNop]; }
1759444SAndreas.Sandberg@ARM.com
1769444SAndreas.Sandberg@ARM.com    bool isMemRef()    	  const { return flags[IsMemRef]; }
1779444SAndreas.Sandberg@ARM.com    bool isLoad()	  const { return flags[IsLoad]; }
1789444SAndreas.Sandberg@ARM.com    bool isStore()	  const { return flags[IsStore]; }
1799444SAndreas.Sandberg@ARM.com    bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
1809444SAndreas.Sandberg@ARM.com    bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
1819444SAndreas.Sandberg@ARM.com    bool isCopy()         const { return flags[IsCopy];}
1829444SAndreas.Sandberg@ARM.com
18314085Sgiacomo.travaglini@arm.com    bool isInteger()	  const { return flags[IsInteger]; }
1849444SAndreas.Sandberg@ARM.com    bool isFloating()	  const { return flags[IsFloating]; }
1851060SN/A
1862292SN/A    bool isControl()	  const { return flags[IsControl]; }
1875595Sgblack@eecs.umich.edu    bool isCall()	  const { return flags[IsCall]; }
1882292SN/A    bool isReturn()	  const { return flags[IsReturn]; }
1891755SN/A    bool isDirectCtrl()	  const { return flags[IsDirectControl]; }
1901060SN/A    bool isIndirectCtrl() const { return flags[IsIndirectControl]; }
1912292SN/A    bool isCondCtrl()	  const { return flags[IsCondControl]; }
19211169Sandreas.hansson@arm.com    bool isUncondCtrl()	  const { return flags[IsUncondControl]; }
1931684SN/A
19410023Smatt.horsnell@ARM.com    bool isThreadSync()   const { return flags[IsThreadSync]; }
19510023Smatt.horsnell@ARM.com    bool isSerializing()  const { return flags[IsSerializing]; }
19610023Smatt.horsnell@ARM.com    bool isMemBarrier()   const { return flags[IsMemBarrier]; }
19710023Smatt.horsnell@ARM.com    bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
19811169Sandreas.hansson@arm.com    bool isNonSpeculative() const { return flags[IsNonSpeculative]; }
19910023Smatt.horsnell@ARM.com    //@}
2005358Sgblack@eecs.umich.edu
2015358Sgblack@eecs.umich.edu    /// Operation class.  Used to select appropriate function unit in issue.
2025358Sgblack@eecs.umich.edu    OpClass opClass()     const { return _opClass; }
2035358Sgblack@eecs.umich.edu};
2045358Sgblack@eecs.umich.edu
2055358Sgblack@eecs.umich.edu
2065358Sgblack@eecs.umich.edu// forward declaration
2075358Sgblack@eecs.umich.edutemplate <class ISA>
2085358Sgblack@eecs.umich.educlass StaticInstPtr;
2095358Sgblack@eecs.umich.edu
2105358Sgblack@eecs.umich.edu/**
2115358Sgblack@eecs.umich.edu * Generic yet ISA-dependent static instruction class.
2125358Sgblack@eecs.umich.edu *
2135358Sgblack@eecs.umich.edu * This class builds on StaticInstBase, defining fields and interfaces
2145358Sgblack@eecs.umich.edu * that are generic across all ISAs but that differ in details
2155358Sgblack@eecs.umich.edu * according to the specific ISA being used.
2162292SN/A */
2172292SN/Atemplate <class ISA>
2182292SN/Aclass StaticInst : public StaticInstBase
2191684SN/A{
2201684SN/A  public:
2212292SN/A
22211169Sandreas.hansson@arm.com    /// Binary machine instruction type.
2231060SN/A    typedef typename ISA::MachInst MachInst;
22411169Sandreas.hansson@arm.com    /// Memory address type.
2259427SAndreas.Sandberg@ARM.com    typedef typename ISA::Addr	   Addr;
2262834Sksewell@umich.edu    /// Logical register index type.
2272834Sksewell@umich.edu    typedef typename ISA::RegIndex RegIndex;
2282834Sksewell@umich.edu
2292834Sksewell@umich.edu    enum {
2302829Sksewell@umich.edu        MaxInstSrcRegs = ISA::MaxInstSrcRegs,	//< Max source regs
2316221Snate@binkert.org        MaxInstDestRegs = ISA::MaxInstDestRegs,	//< Max dest regs
2322875Sksewell@umich.edu    };
2332875Sksewell@umich.edu
2346221Snate@binkert.org
2352829Sksewell@umich.edu    /// Return logical index (architectural reg num) of i'th destination reg.
2362292SN/A    /// Only the entries from 0 through numDestRegs()-1 are valid.
2376221Snate@binkert.org    RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
2381060SN/A
2392292SN/A    /// Return logical index (architectural reg num) of i'th source reg.
2406221Snate@binkert.org    /// Only the entries from 0 through numSrcRegs()-1 are valid.
2412292SN/A    RegIndex srcRegIdx(int i)  const { return _srcRegIdx[i]; }
2422292SN/A
24311169Sandreas.hansson@arm.com    /// Pointer to a statically allocated "null" instruction object.
2448834Satgutier@umich.edu    /// Used to give eaCompInst() and memAccInst() something to return
2458834Satgutier@umich.edu    /// when called on non-memory instructions.
24611169Sandreas.hansson@arm.com    static StaticInstPtr<ISA> nullStaticInstPtr;
2472292SN/A
2482292SN/A    /**
24911169Sandreas.hansson@arm.com     * Memory references only: returns "fake" instruction representing
2502292SN/A     * the effective address part of the memory operation.  Used to
2512292SN/A     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
25211169Sandreas.hansson@arm.com     * just the EA computation.
2532292SN/A     */
2542292SN/A    virtual const
2552292SN/A    StaticInstPtr<ISA> &eaCompInst() const { return nullStaticInstPtr; }
2562292SN/A
25711169Sandreas.hansson@arm.com    /**
2582292SN/A     * Memory references only: returns "fake" instruction representing
2592292SN/A     * the memory access part of the memory operation.  Used to
2602292SN/A     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
2612292SN/A     * just the memory access (not the EA computation).
2629444SAndreas.Sandberg@ARM.com     */
26310913Sandreas.sandberg@arm.com    virtual const
2649444SAndreas.Sandberg@ARM.com    StaticInstPtr<ISA> &memAccInst() const { return nullStaticInstPtr; }
26511168Sandreas.hansson@arm.com
26611168Sandreas.hansson@arm.com    /// The binary machine instruction.
2672864Sktlim@umich.edu    const MachInst machInst;
26813641Sqtt2@cornell.edu
26913641Sqtt2@cornell.edu  protected:
27013641Sqtt2@cornell.edu
27113641Sqtt2@cornell.edu    /// See destRegIdx().
27213641Sqtt2@cornell.edu    RegIndex _destRegIdx[MaxInstDestRegs];
27313641Sqtt2@cornell.edu    /// See srcRegIdx().
27413641Sqtt2@cornell.edu    RegIndex _srcRegIdx[MaxInstSrcRegs];
27513641Sqtt2@cornell.edu
27613641Sqtt2@cornell.edu    /**
27713641Sqtt2@cornell.edu     * Base mnemonic (e.g., "add").  Used by generateDisassembly()
27813641Sqtt2@cornell.edu     * methods.  Also useful to readily identify instructions from
27913641Sqtt2@cornell.edu     * within the debugger when #cachedDisassembly has not been
28013641Sqtt2@cornell.edu     * initialized.
28113641Sqtt2@cornell.edu     */
28213641Sqtt2@cornell.edu    const char *mnemonic;
2832864Sktlim@umich.edu
2845595Sgblack@eecs.umich.edu    /**
2855595Sgblack@eecs.umich.edu     * String representation of disassembly (lazily evaluated via
2862292SN/A     * disassemble()).
28711877Sbrandon.potter@amd.com     */
2882292SN/A    std::string *cachedDisassembly;
2892843Sktlim@umich.edu
2902843Sktlim@umich.edu    /**
29111168Sandreas.hansson@arm.com     * Internal function to generate disassembly string.
2922843Sktlim@umich.edu     */
2932843Sktlim@umich.edu    virtual std::string generateDisassembly(Addr pc,
29411168Sandreas.hansson@arm.com                                            const SymbolTable *symtab) = 0;
2952292SN/A
2969444SAndreas.Sandberg@ARM.com    /// Constructor.
2979444SAndreas.Sandberg@ARM.com    StaticInst(const char *_mnemonic, MachInst _machInst, OpClass __opClass)
2989444SAndreas.Sandberg@ARM.com        : StaticInstBase(__opClass),
2999444SAndreas.Sandberg@ARM.com          machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
3009444SAndreas.Sandberg@ARM.com    {
3019444SAndreas.Sandberg@ARM.com    }
3029444SAndreas.Sandberg@ARM.com
3039444SAndreas.Sandberg@ARM.com  public:
3042843Sktlim@umich.edu
3052843Sktlim@umich.edu    virtual ~StaticInst()
30611169Sandreas.hansson@arm.com    {
3072316SN/A        if (cachedDisassembly)
3082348SN/A            delete cachedDisassembly;
30911169Sandreas.hansson@arm.com    }
3101060SN/A
31111169Sandreas.hansson@arm.com    /**
3129523SAndreas.Sandberg@ARM.com     * Execute this instruction under SimpleCPU model.
3131060SN/A     */
3142316SN/A    virtual Fault execute(SimpleCPU *xc, Trace::InstRecord *traceData) = 0;
3152316SN/A
3161060SN/A         /**
3175595Sgblack@eecs.umich.edu     * Execute this instruction under InorderCPU model.
31810417Sandreas.hansson@arm.com     */
3195595Sgblack@eecs.umich.edu    virtual Fault execute(InorderCPU *xc, Trace::InstRecord *traceData) = 0;
32013601Sgiacomo.travaglini@arm.com
32113601Sgiacomo.travaglini@arm.com
32213601Sgiacomo.travaglini@arm.com    /**
32313601Sgiacomo.travaglini@arm.com     * Execute this instruction under FastCPU model.
32413601Sgiacomo.travaglini@arm.com     */
32513601Sgiacomo.travaglini@arm.com    virtual Fault execute(FastCPU *xc, Trace::InstRecord *traceData) = 0;
32613601Sgiacomo.travaglini@arm.com
32713601Sgiacomo.travaglini@arm.com    /**
3285595Sgblack@eecs.umich.edu     * Execute this instruction under detailed FullCPU model.
3295595Sgblack@eecs.umich.edu     */
3305595Sgblack@eecs.umich.edu    virtual Fault execute(DynInst *xc, Trace::InstRecord *traceData) = 0;
3315595Sgblack@eecs.umich.edu
33210379Sandreas.hansson@arm.com    /**
3335595Sgblack@eecs.umich.edu     * Return the target address for a PC-relative branch.
3345595Sgblack@eecs.umich.edu     * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
3355595Sgblack@eecs.umich.edu     * should be true).
3365595Sgblack@eecs.umich.edu     */
3372348SN/A    virtual Addr branchTarget(Addr branchPC) const
3385595Sgblack@eecs.umich.edu    {
3395595Sgblack@eecs.umich.edu        panic("StaticInst::branchTarget() called on instruction "
34013557Sgabeblack@google.com              "that is not a PC-relative branch.");
3415595Sgblack@eecs.umich.edu    }
3425595Sgblack@eecs.umich.edu
3435595Sgblack@eecs.umich.edu    /**
3445595Sgblack@eecs.umich.edu     * Return the target address for an indirect branch (jump).  The
34513557Sgabeblack@google.com     * register value is read from the supplied execution context, so
3465595Sgblack@eecs.umich.edu     * the result is valid only if the execution context is about to
3475595Sgblack@eecs.umich.edu     * execute the branch in question.  Invalid if not an indirect
34813582Sgabeblack@google.com     * branch (i.e. isIndirectCtrl() should be true).
3495595Sgblack@eecs.umich.edu     */
3505595Sgblack@eecs.umich.edu    virtual Addr branchTarget(ExecContext *xc) const
3515595Sgblack@eecs.umich.edu    {
3525595Sgblack@eecs.umich.edu        panic("StaticInst::branchTarget() called on instruction "
35313582Sgabeblack@google.com              "that is not an indirect branch.");
3545595Sgblack@eecs.umich.edu    }
35513557Sgabeblack@google.com
3561060SN/A    /**
35713611Sgabeblack@google.com     * Return true if the instruction is a control transfer, and if so,
3582455SN/A     * return the target address as well.
35912109SRekai.GonzalezAlberquilla@arm.com     */
36012109SRekai.GonzalezAlberquilla@arm.com    bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt);
36112109SRekai.GonzalezAlberquilla@arm.com
36212109SRekai.GonzalezAlberquilla@arm.com    /**
36312109SRekai.GonzalezAlberquilla@arm.com     * Return string representation of disassembled instruction.
36412109SRekai.GonzalezAlberquilla@arm.com     * The default version of this function will call the internal
36512109SRekai.GonzalezAlberquilla@arm.com     * virtual generateDisassembly() function to get the string,
36613601Sgiacomo.travaglini@arm.com     * then cache it in #cachedDisassembly.  If the disassembly
36713601Sgiacomo.travaglini@arm.com     * should not be cached, this function should be overridden directly.
36813601Sgiacomo.travaglini@arm.com     */
36913601Sgiacomo.travaglini@arm.com    virtual const std::string &disassemble(Addr pc,
37013601Sgiacomo.travaglini@arm.com                                           const SymbolTable *symtab = 0)
37113601Sgiacomo.travaglini@arm.com    {
37213601Sgiacomo.travaglini@arm.com        if (!cachedDisassembly)
37312109SRekai.GonzalezAlberquilla@arm.com            cachedDisassembly =
37412109SRekai.GonzalezAlberquilla@arm.com                new std::string(generateDisassembly(pc, symtab));
37512109SRekai.GonzalezAlberquilla@arm.com
37612109SRekai.GonzalezAlberquilla@arm.com        return *cachedDisassembly;
37712109SRekai.GonzalezAlberquilla@arm.com    }
37812109SRekai.GonzalezAlberquilla@arm.com
37912109SRekai.GonzalezAlberquilla@arm.com    /// Decoded instruction cache type.
38012109SRekai.GonzalezAlberquilla@arm.com    /// For now we're using a generic hash_map; this seems to work
38112109SRekai.GonzalezAlberquilla@arm.com    /// pretty well.
38212109SRekai.GonzalezAlberquilla@arm.com    typedef m5::hash_map<MachInst, StaticInstPtr<ISA> > DecodeCache;
38312109SRekai.GonzalezAlberquilla@arm.com
38412109SRekai.GonzalezAlberquilla@arm.com    /// A cache of decoded instruction objects.
38512109SRekai.GonzalezAlberquilla@arm.com    static DecodeCache decodeCache;
38612109SRekai.GonzalezAlberquilla@arm.com
38712109SRekai.GonzalezAlberquilla@arm.com    /**
38812109SRekai.GonzalezAlberquilla@arm.com     * Dump some basic stats on the decode cache hash map.
38912109SRekai.GonzalezAlberquilla@arm.com     * Only gets called if DECODE_CACHE_HASH_STATS is defined.
39012109SRekai.GonzalezAlberquilla@arm.com     */
39112109SRekai.GonzalezAlberquilla@arm.com    static void dumpDecodeCacheStats();
39212109SRekai.GonzalezAlberquilla@arm.com
39312109SRekai.GonzalezAlberquilla@arm.com    /// Decode a machine instruction.
39412109SRekai.GonzalezAlberquilla@arm.com    /// @param mach_inst The binary instruction to decode.
39512109SRekai.GonzalezAlberquilla@arm.com    /// @retval A pointer to the corresponding StaticInst object.
39612109SRekai.GonzalezAlberquilla@arm.com    static
39712109SRekai.GonzalezAlberquilla@arm.com    StaticInstPtr<ISA> decode(MachInst mach_inst)
39812109SRekai.GonzalezAlberquilla@arm.com    {
39912109SRekai.GonzalezAlberquilla@arm.com#ifdef DECODE_CACHE_HASH_STATS
40012109SRekai.GonzalezAlberquilla@arm.com        // Simple stats on decode hash_map.  Turns out the default
40112109SRekai.GonzalezAlberquilla@arm.com        // hash function is as good as anything I could come up with.
40212109SRekai.GonzalezAlberquilla@arm.com        const int dump_every_n = 10000000;
40312109SRekai.GonzalezAlberquilla@arm.com        static int decodes_til_dump = dump_every_n;
40412109SRekai.GonzalezAlberquilla@arm.com
40512109SRekai.GonzalezAlberquilla@arm.com        if (--decodes_til_dump == 0) {
40613610Sgiacomo.gabrielli@arm.com            dumpDecodeCacheStats();
40713610Sgiacomo.gabrielli@arm.com            decodes_til_dump = dump_every_n;
40813610Sgiacomo.gabrielli@arm.com        }
40913610Sgiacomo.gabrielli@arm.com#endif
41013622Sgabeblack@google.com
4119920Syasuko.eckert@amd.com        typename DecodeCache::iterator iter = decodeCache.find(mach_inst);
41213557Sgabeblack@google.com        if (iter != decodeCache.end()) {
4131060SN/A            return iter->second;
41413611Sgabeblack@google.com        }
4152455SN/A
41612109SRekai.GonzalezAlberquilla@arm.com        StaticInstPtr<ISA> si = ISA::decodeInst(mach_inst);
41712109SRekai.GonzalezAlberquilla@arm.com        decodeCache[mach_inst] = si;
41812109SRekai.GonzalezAlberquilla@arm.com        return si;
41912109SRekai.GonzalezAlberquilla@arm.com    }
42013610Sgiacomo.gabrielli@arm.com};
42113610Sgiacomo.gabrielli@arm.com
42213622Sgabeblack@google.comtypedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
4239920Syasuko.eckert@amd.com
42413557Sgabeblack@google.com/// Reference-counted pointer to a StaticInst object.
4251060SN/A/// This type should be used instead of "StaticInst<ISA> *" so that
42613611Sgabeblack@google.com/// StaticInst objects can be properly reference-counted.
4272292SN/Atemplate <class ISA>
42812109SRekai.GonzalezAlberquilla@arm.comclass StaticInstPtr : public RefCountingPtr<StaticInst<ISA> >
42912109SRekai.GonzalezAlberquilla@arm.com{
43012109SRekai.GonzalezAlberquilla@arm.com  public:
43112109SRekai.GonzalezAlberquilla@arm.com    /// Constructor.
43212109SRekai.GonzalezAlberquilla@arm.com    StaticInstPtr()
43312109SRekai.GonzalezAlberquilla@arm.com        : RefCountingPtr<StaticInst<ISA> >()
43412109SRekai.GonzalezAlberquilla@arm.com    {
43512109SRekai.GonzalezAlberquilla@arm.com    }
43612109SRekai.GonzalezAlberquilla@arm.com
43712109SRekai.GonzalezAlberquilla@arm.com    /// Conversion from "StaticInst<ISA> *".
43812109SRekai.GonzalezAlberquilla@arm.com    StaticInstPtr(StaticInst<ISA> *p)
43912109SRekai.GonzalezAlberquilla@arm.com        : RefCountingPtr<StaticInst<ISA> >(p)
44012109SRekai.GonzalezAlberquilla@arm.com    {
44112109SRekai.GonzalezAlberquilla@arm.com    }
44212109SRekai.GonzalezAlberquilla@arm.com
44312109SRekai.GonzalezAlberquilla@arm.com    /// Copy constructor.
44412109SRekai.GonzalezAlberquilla@arm.com    StaticInstPtr(const StaticInstPtr &r)
44512109SRekai.GonzalezAlberquilla@arm.com        : RefCountingPtr<StaticInst<ISA> >(r)
44612109SRekai.GonzalezAlberquilla@arm.com    {
44712109SRekai.GonzalezAlberquilla@arm.com    }
44812109SRekai.GonzalezAlberquilla@arm.com
44912109SRekai.GonzalezAlberquilla@arm.com    /// Construct directly from machine instruction.
45012109SRekai.GonzalezAlberquilla@arm.com    /// Calls StaticInst<ISA>::decode().
45112109SRekai.GonzalezAlberquilla@arm.com    StaticInstPtr(typename ISA::MachInst mach_inst)
45212109SRekai.GonzalezAlberquilla@arm.com        : RefCountingPtr<StaticInst<ISA> >(StaticInst<ISA>::decode(mach_inst))
45312109SRekai.GonzalezAlberquilla@arm.com    {
45412109SRekai.GonzalezAlberquilla@arm.com    }
45512109SRekai.GonzalezAlberquilla@arm.com
45613610Sgiacomo.gabrielli@arm.com    /// Convert to pointer to StaticInstBase class.
45713610Sgiacomo.gabrielli@arm.com    operator const StaticInstBasePtr()
45813610Sgiacomo.gabrielli@arm.com    {
45913610Sgiacomo.gabrielli@arm.com        return get();
46013610Sgiacomo.gabrielli@arm.com    }
46113622Sgabeblack@google.com};
4629920Syasuko.eckert@amd.com
4632348SN/A#endif // __STATIC_INST_HH__
4642348SN/A