static_inst.hh revision 508
112837Sgabeblack@google.com/*
212837Sgabeblack@google.com * Copyright (c) 2003 The Regents of The University of Michigan
312837Sgabeblack@google.com * All rights reserved.
412837Sgabeblack@google.com *
512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412837Sgabeblack@google.com * this software without specific prior written permission.
1512837Sgabeblack@google.com *
1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712837Sgabeblack@google.com */
2812837Sgabeblack@google.com
2912837Sgabeblack@google.com#ifndef __STATIC_INST_HH__
3012837Sgabeblack@google.com#define __STATIC_INST_HH__
3112837Sgabeblack@google.com
3212837Sgabeblack@google.com#include <bitset>
3313785Sgabeblack@google.com#include <string>
3412837Sgabeblack@google.com
3512837Sgabeblack@google.com#include "sim/host.hh"
3612837Sgabeblack@google.com#include "base/hashmap.hh"
3713087Sgabeblack@google.com#include "base/refcnt.hh"
3812837Sgabeblack@google.com
3912837Sgabeblack@google.com#include "cpu/full_cpu/op_class.hh"
4012837Sgabeblack@google.com#include "targetarch/isa_traits.hh"
4112914Sgabeblack@google.com
4212914Sgabeblack@google.com// forward declarations
4312914Sgabeblack@google.comclass ExecContext;
4412914Sgabeblack@google.comclass SpecExecContext;
4512914Sgabeblack@google.comclass SimpleCPU;
4612914Sgabeblack@google.comclass FullCPU;
4712914Sgabeblack@google.comclass DynInst;
4812951Sgabeblack@google.comclass SymbolTable;
4912951Sgabeblack@google.com
5012951Sgabeblack@google.comnamespace Trace {
5112982Sgabeblack@google.com    class InstRecord;
5212951Sgabeblack@google.com}
5312952Sgabeblack@google.com
5412952Sgabeblack@google.com/**
5512952Sgabeblack@google.com * Base, ISA-independent static instruction class.
5612952Sgabeblack@google.com *
5712952Sgabeblack@google.com * The main component of this class is the vector of flags and the
5812952Sgabeblack@google.com * associated methods for reading them.  Any object that can rely
5912951Sgabeblack@google.com * solely on these flags can process instructions without being
6012951Sgabeblack@google.com * recompiled for multiple ISAs.
6112951Sgabeblack@google.com */
6213785Sgabeblack@google.comclass StaticInstBase : public RefCounted
6313785Sgabeblack@google.com{
6413785Sgabeblack@google.com  protected:
6512837Sgabeblack@google.com
6612837Sgabeblack@google.com    /// Set of boolean static instruction properties.
6712837Sgabeblack@google.com    ///
6812837Sgabeblack@google.com    /// Notes:
6912837Sgabeblack@google.com    /// - The IsInteger and IsFloating flags are based on the class of
7012837Sgabeblack@google.com    /// registers accessed by the instruction.  Although most
7112837Sgabeblack@google.com    /// instructions will have exactly one of these two flags set, it
7212837Sgabeblack@google.com    /// is possible for an instruction to have neither (e.g., direct
7312837Sgabeblack@google.com    /// unconditional branches, memory barriers) or both (e.g., an
7412837Sgabeblack@google.com    /// FP/int conversion).
7512837Sgabeblack@google.com    /// - If IsMemRef is set, then exactly one of IsLoad or IsStore
7612837Sgabeblack@google.com    /// will be set.  Prefetches are marked as IsLoad, even if they
7712837Sgabeblack@google.com    /// prefetch exclusive copies.
7812837Sgabeblack@google.com    /// - If IsControl is set, then exactly one of IsDirectControl or
7912837Sgabeblack@google.com    /// IsIndirect Control will be set, and exactly one of
8012837Sgabeblack@google.com    /// IsCondControl or IsUncondControl will be set.
8112837Sgabeblack@google.com    ///
8212837Sgabeblack@google.com    enum Flags {
8312837Sgabeblack@google.com        IsNop,		///< Is a no-op (no effect at all).
8412951Sgabeblack@google.com
8513091Sgabeblack@google.com        IsInteger,	///< References integer regs.
8613091Sgabeblack@google.com        IsFloating,	///< References FP regs.
8712951Sgabeblack@google.com
8812837Sgabeblack@google.com        IsMemRef,	///< References memory (load, store, or prefetch).
8913382Sgabeblack@google.com        IsLoad,		///< Reads from memory (load or prefetch).
9013091Sgabeblack@google.com        IsStore,	///< Writes to memory.
9113091Sgabeblack@google.com        IsInstPrefetch,	///< Instruction-cache prefetch.
9213091Sgabeblack@google.com        IsDataPrefetch,	///< Data-cache prefetch.
9313091Sgabeblack@google.com
9413091Sgabeblack@google.com        IsControl,		///< Control transfer instruction.
9512837Sgabeblack@google.com        IsDirectControl,	///< PC relative control transfer.
9612837Sgabeblack@google.com        IsIndirectControl,	///< Register indirect control transfer.
9712837Sgabeblack@google.com        IsCondControl,		///< Conditional control transfer.
9812837Sgabeblack@google.com        IsUncondControl,	///< Unconditional control transfer.
9912837Sgabeblack@google.com        IsCall,			///< Subroutine call.
10012837Sgabeblack@google.com        IsReturn,		///< Subroutine return.
10112837Sgabeblack@google.com
10213785Sgabeblack@google.com        IsThreadSync,		///< Thread synchronization operation.
10313785Sgabeblack@google.com
10413785Sgabeblack@google.com        NumFlags
10513785Sgabeblack@google.com    };
10612982Sgabeblack@google.com
10713191Sgabeblack@google.com    /// Flag values for this instruction.
10812982Sgabeblack@google.com    std::bitset<NumFlags> flags;
10912837Sgabeblack@google.com
11012837Sgabeblack@google.com    /// See opClass().
11112951Sgabeblack@google.com    OpClass _opClass;
11212837Sgabeblack@google.com
11312837Sgabeblack@google.com    /// See numSrcRegs().
11412837Sgabeblack@google.com    int8_t _numSrcRegs;
11512837Sgabeblack@google.com
11612837Sgabeblack@google.com    /// See numDestRegs().
11712837Sgabeblack@google.com    int8_t _numDestRegs;
11812837Sgabeblack@google.com
11912837Sgabeblack@google.com    /// The following are used to track physical register usage
12012837Sgabeblack@google.com    /// for machines with separate int & FP reg files.
12112837Sgabeblack@google.com    //@{
12212837Sgabeblack@google.com    int8_t _numFPDestRegs;
12312837Sgabeblack@google.com    int8_t _numIntDestRegs;
12412837Sgabeblack@google.com    //@}
12512837Sgabeblack@google.com
12612837Sgabeblack@google.com    /// Constructor.
12712837Sgabeblack@google.com    /// It's important to initialize everything here to a sane
12812837Sgabeblack@google.com    /// default, since the decoder generally only overrides
12912837Sgabeblack@google.com    /// the fields that are meaningful for the particular
13012837Sgabeblack@google.com    /// instruction.
13112837Sgabeblack@google.com    StaticInstBase(OpClass __opClass)
13212837Sgabeblack@google.com        : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
13312837Sgabeblack@google.com          _numFPDestRegs(0), _numIntDestRegs(0)
13412837Sgabeblack@google.com    {
13512837Sgabeblack@google.com    }
13612837Sgabeblack@google.com
13712837Sgabeblack@google.com  public:
13812837Sgabeblack@google.com
13912837Sgabeblack@google.com    /// @name Register information.
14012837Sgabeblack@google.com    /// The sum of numFPDestRegs() and numIntDestRegs() equals
14112837Sgabeblack@google.com    /// numDestRegs().  The former two functions are used to track
14212837Sgabeblack@google.com    /// physical register usage for machines with separate int & FP
14312837Sgabeblack@google.com    /// reg files.
14412837Sgabeblack@google.com    //@{
14512837Sgabeblack@google.com    /// Number of source registers.
14612837Sgabeblack@google.com    int8_t numSrcRegs()  const { return _numSrcRegs; }
14712837Sgabeblack@google.com    /// Number of destination registers.
14812837Sgabeblack@google.com    int8_t numDestRegs() const { return _numDestRegs; }
14912837Sgabeblack@google.com    /// Number of floating-point destination regs.
15012837Sgabeblack@google.com    int8_t numFPDestRegs()  const { return _numFPDestRegs; }
15112837Sgabeblack@google.com    /// Number of integer destination regs.
15212837Sgabeblack@google.com    int8_t numIntDestRegs() const { return _numIntDestRegs; }
15312837Sgabeblack@google.com    //@}
15412837Sgabeblack@google.com
15512837Sgabeblack@google.com    /// @name Flag accessors.
15612837Sgabeblack@google.com    /// These functions are used to access the values of the various
15712837Sgabeblack@google.com    /// instruction property flags.  See StaticInstBase::Flags for descriptions
15812837Sgabeblack@google.com    /// of the individual flags.
15912837Sgabeblack@google.com    //@{
16012837Sgabeblack@google.com
16112837Sgabeblack@google.com    bool isNop() 	  const { return flags[IsNop]; }
16212837Sgabeblack@google.com
16312837Sgabeblack@google.com    bool isMemRef()    	  const { return flags[IsMemRef]; }
16412837Sgabeblack@google.com    bool isLoad()	  const { return flags[IsLoad]; }
16512837Sgabeblack@google.com    bool isStore()	  const { return flags[IsStore]; }
16612837Sgabeblack@google.com    bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
16712837Sgabeblack@google.com    bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
16812837Sgabeblack@google.com
16912837Sgabeblack@google.com    bool isInteger()	  const { return flags[IsInteger]; }
17012837Sgabeblack@google.com    bool isFloating()	  const { return flags[IsFloating]; }
17112837Sgabeblack@google.com
17212837Sgabeblack@google.com    bool isControl()	  const { return flags[IsControl]; }
17312837Sgabeblack@google.com    bool isCall()	  const { return flags[IsCall]; }
17412837Sgabeblack@google.com    bool isReturn()	  const { return flags[IsReturn]; }
17512837Sgabeblack@google.com    bool isDirectCtrl()	  const { return flags[IsDirectControl]; }
17612837Sgabeblack@google.com    bool isIndirectCtrl() const { return flags[IsIndirectControl]; }
17712837Sgabeblack@google.com    bool isCondCtrl()	  const { return flags[IsCondControl]; }
17813292Sgabeblack@google.com    bool isUncondCtrl()	  const { return flags[IsUncondControl]; }
17913292Sgabeblack@google.com
18013292Sgabeblack@google.com    bool isThreadSync()   const { return flags[IsThreadSync]; }
18113292Sgabeblack@google.com    //@}
18213292Sgabeblack@google.com
18313292Sgabeblack@google.com    /// Operation class.  Used to select appropriate function unit in issue.
18412837Sgabeblack@google.com    OpClass opClass()     const { return _opClass; }
18512837Sgabeblack@google.com};
18612837Sgabeblack@google.com
18712837Sgabeblack@google.com
18812837Sgabeblack@google.com// forward declaration
18912837Sgabeblack@google.comtemplate <class ISA>
19012837Sgabeblack@google.comclass StaticInstPtr;
19112928Sgabeblack@google.com
19212928Sgabeblack@google.com/**
19312928Sgabeblack@google.com * Generic yet ISA-dependent static instruction class.
19412928Sgabeblack@google.com *
19512864Sgabeblack@google.com * This class builds on StaticInstBase, defining fields and interfaces
19613191Sgabeblack@google.com * that are generic across all ISAs but that differ in details
19712864Sgabeblack@google.com * according to the specific ISA being used.
19812837Sgabeblack@google.com */
19912837Sgabeblack@google.comtemplate <class ISA>
20012837Sgabeblack@google.comclass StaticInst : public StaticInstBase
20112837Sgabeblack@google.com{
20212837Sgabeblack@google.com  public:
20312837Sgabeblack@google.com
20412837Sgabeblack@google.com    /// Binary machine instruction type.
20512837Sgabeblack@google.com    typedef typename ISA::MachInst MachInst;
20612837Sgabeblack@google.com    /// Memory address type.
20712837Sgabeblack@google.com    typedef typename ISA::Addr	   Addr;
20812837Sgabeblack@google.com    /// Logical register index type.
20912837Sgabeblack@google.com    typedef typename ISA::RegIndex RegIndex;
21012837Sgabeblack@google.com
21112837Sgabeblack@google.com    enum {
21212837Sgabeblack@google.com        MaxInstSrcRegs = ISA::MaxInstSrcRegs,	//< Max source regs
21312837Sgabeblack@google.com        MaxInstDestRegs = ISA::MaxInstDestRegs,	//< Max dest regs
21412837Sgabeblack@google.com    };
21512837Sgabeblack@google.com
21612837Sgabeblack@google.com
21712837Sgabeblack@google.com    /// Return logical index (architectural reg num) of i'th destination reg.
21812837Sgabeblack@google.com    /// Only the entries from 0 through numDestRegs()-1 are valid.
21912837Sgabeblack@google.com    RegIndex destRegIdx(int i)	{ return _destRegIdx[i]; }
22012837Sgabeblack@google.com
22112837Sgabeblack@google.com    /// Return logical index (architectural reg num) of i'th source reg.
22212837Sgabeblack@google.com    /// Only the entries from 0 through numSrcRegs()-1 are valid.
22312837Sgabeblack@google.com    RegIndex srcRegIdx(int i)	{ return _srcRegIdx[i]; }
22412837Sgabeblack@google.com
22512837Sgabeblack@google.com    /// Pointer to a statically allocated "null" instruction object.
22612929Sgabeblack@google.com    /// Used to give eaCompInst() and memAccInst() something to return
22712929Sgabeblack@google.com    /// when called on non-memory instructions.
22812929Sgabeblack@google.com    static StaticInstPtr<ISA> nullStaticInstPtr;
22912837Sgabeblack@google.com
23012837Sgabeblack@google.com    /**
23112837Sgabeblack@google.com     * Memory references only: returns "fake" instruction representing
23212837Sgabeblack@google.com     * the effective address part of the memory operation.  Used to
23312837Sgabeblack@google.com     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
23412837Sgabeblack@google.com     * just the EA computation.
23512837Sgabeblack@google.com     */
23612837Sgabeblack@google.com    virtual StaticInstPtr<ISA> eaCompInst() { return nullStaticInstPtr; }
23712837Sgabeblack@google.com
23812837Sgabeblack@google.com    /**
23912837Sgabeblack@google.com     * Memory references only: returns "fake" instruction representing
24012837Sgabeblack@google.com     * the memory access part of the memory operation.  Used to
24112837Sgabeblack@google.com     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
24212837Sgabeblack@google.com     * just the memory access (not the EA computation).
24312914Sgabeblack@google.com     */
24412909Sgabeblack@google.com    virtual StaticInstPtr<ISA> memAccInst() { return nullStaticInstPtr; }
24512914Sgabeblack@google.com
24612914Sgabeblack@google.com    /// The binary machine instruction.
24712914Sgabeblack@google.com    const MachInst machInst;
24812914Sgabeblack@google.com
24912909Sgabeblack@google.com  protected:
25012837Sgabeblack@google.com
25112837Sgabeblack@google.com    /// See destRegIdx().
25212837Sgabeblack@google.com    RegIndex _destRegIdx[MaxInstDestRegs];
25312837Sgabeblack@google.com    /// See srcRegIdx().
25412837Sgabeblack@google.com    RegIndex _srcRegIdx[MaxInstSrcRegs];
25512837Sgabeblack@google.com
25612951Sgabeblack@google.com    /**
25712951Sgabeblack@google.com     * Base mnemonic (e.g., "add").  Used by generateDisassembly()
25812837Sgabeblack@google.com     * methods.  Also useful to readily identify instructions from
25912837Sgabeblack@google.com     * within the debugger when #cachedDisassembly has not been
26012837Sgabeblack@google.com     * initialized.
26112837Sgabeblack@google.com     */
26212837Sgabeblack@google.com    const char *mnemonic;
26312837Sgabeblack@google.com
26412837Sgabeblack@google.com    /**
26512837Sgabeblack@google.com     * String representation of disassembly (lazily evaluated via
26612837Sgabeblack@google.com     * disassemble()).
26712837Sgabeblack@google.com     */
26812837Sgabeblack@google.com    std::string *cachedDisassembly;
26912837Sgabeblack@google.com
27012837Sgabeblack@google.com    /**
27112837Sgabeblack@google.com     * Internal function to generate disassembly string.
27212837Sgabeblack@google.com     */
27312837Sgabeblack@google.com    virtual std::string generateDisassembly(Addr pc,
27412837Sgabeblack@google.com                                            const SymbolTable *symtab) = 0;
27512837Sgabeblack@google.com
27612837Sgabeblack@google.com    /// Constructor.
27712837Sgabeblack@google.com    StaticInst(const char *_mnemonic, MachInst _machInst, OpClass __opClass)
27812837Sgabeblack@google.com        : StaticInstBase(__opClass),
27912837Sgabeblack@google.com          machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
28012837Sgabeblack@google.com    {
28112837Sgabeblack@google.com    }
28212837Sgabeblack@google.com
28312837Sgabeblack@google.com  public:
28412837Sgabeblack@google.com
28512837Sgabeblack@google.com    virtual ~StaticInst()
28612837Sgabeblack@google.com    {
28712837Sgabeblack@google.com        if (cachedDisassembly)
28812837Sgabeblack@google.com            delete cachedDisassembly;
28912837Sgabeblack@google.com    }
29012929Sgabeblack@google.com
29112929Sgabeblack@google.com    /**
29212929Sgabeblack@google.com     * Execute this instruction under SimpleCPU model.
29312837Sgabeblack@google.com     */
29412837Sgabeblack@google.com    virtual Fault execute(SimpleCPU *cpu, ExecContext *xc,
29512837Sgabeblack@google.com                          Trace::InstRecord *traceData) = 0;
29612837Sgabeblack@google.com
29712837Sgabeblack@google.com    /**
29812837Sgabeblack@google.com     * Execute this instruction under detailed FullCPU model.
29912837Sgabeblack@google.com     */
30012837Sgabeblack@google.com    virtual Fault execute(FullCPU *cpu, SpecExecContext *xc, DynInst *dynInst,
30112952Sgabeblack@google.com                          Trace::InstRecord *traceData) = 0;
30212952Sgabeblack@google.com
30312952Sgabeblack@google.com    /**
30412952Sgabeblack@google.com     * Return the target address for a PC-relative branch.
30512952Sgabeblack@google.com     * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
30612952Sgabeblack@google.com     * should be true).
30712952Sgabeblack@google.com     */
30813135Sgabeblack@google.com    virtual Addr branchTarget(Addr branchPC)
30913135Sgabeblack@google.com    {
31012952Sgabeblack@google.com        panic("StaticInst::branchTarget() called on instruction "
31112952Sgabeblack@google.com              "that is not a PC-relative branch.");
31212952Sgabeblack@google.com    }
31312952Sgabeblack@google.com
31412952Sgabeblack@google.com    /**
31512952Sgabeblack@google.com     * Return the target address for an indirect branch (jump).  The
31612952Sgabeblack@google.com     * register value is read from the supplied execution context, so
31712952Sgabeblack@google.com     * the result is valid only if the execution context is about to
31813135Sgabeblack@google.com     * execute the branch in question.  Invalid if not an indirect
31913135Sgabeblack@google.com     * branch (i.e. isIndirectCtrl() should be true).
32012952Sgabeblack@google.com     */
32112952Sgabeblack@google.com    virtual Addr branchTarget(ExecContext *xc)
32212952Sgabeblack@google.com    {
32312952Sgabeblack@google.com        panic("StaticInst::branchTarget() called on instruction "
32412952Sgabeblack@google.com              "that is not an indirect branch.");
32512952Sgabeblack@google.com    }
32612952Sgabeblack@google.com
32712952Sgabeblack@google.com    /**
32813210Sgabeblack@google.com     * Return true if the instruction is a control transfer, and if so,
32913210Sgabeblack@google.com     * return the target address as well.
33012952Sgabeblack@google.com     */
33112837Sgabeblack@google.com    bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt);
33212909Sgabeblack@google.com
33312909Sgabeblack@google.com    /**
33412909Sgabeblack@google.com     * Return string representation of disassembled instruction.
33512909Sgabeblack@google.com     * The default version of this function will call the internal
33612909Sgabeblack@google.com     * virtual generateDisassembly() function to get the string,
33712914Sgabeblack@google.com     * then cache it in #cachedDisassembly.  If the disassembly
33812914Sgabeblack@google.com     * should not be cached, this function should be overridden directly.
33912914Sgabeblack@google.com     */
34012914Sgabeblack@google.com    virtual const std::string &disassemble(Addr pc,
34112909Sgabeblack@google.com                                           const SymbolTable *symtab = 0)
34212837Sgabeblack@google.com    {
34312837Sgabeblack@google.com        if (!cachedDisassembly)
34412930Sgabeblack@google.com            cachedDisassembly =
34512930Sgabeblack@google.com                new std::string(generateDisassembly(pc, symtab));
34612930Sgabeblack@google.com
34712837Sgabeblack@google.com        return *cachedDisassembly;
34812837Sgabeblack@google.com    }
34912837Sgabeblack@google.com
35012837Sgabeblack@google.com    /// Decoded instruction cache type.
35112837Sgabeblack@google.com    /// For now we're using a generic hash_map; this seems to work
35212837Sgabeblack@google.com    /// pretty well.
35312901Sgabeblack@google.com    typedef m5::hash_map<MachInst, StaticInstPtr<ISA> > DecodeCache;
35412901Sgabeblack@google.com
35512901Sgabeblack@google.com    /// A cache of decoded instruction objects.
35612901Sgabeblack@google.com    static DecodeCache decodeCache;
35712901Sgabeblack@google.com
35812901Sgabeblack@google.com    /**
35912907Sgabeblack@google.com     * Dump some basic stats on the decode cache hash map.
36013087Sgabeblack@google.com     * Only gets called if DECODE_CACHE_HASH_STATS is defined.
36113087Sgabeblack@google.com     */
36213087Sgabeblack@google.com    static void dumpDecodeCacheStats();
36313087Sgabeblack@google.com
36412907Sgabeblack@google.com    /// Decode a machine instruction.
36512907Sgabeblack@google.com    /// @param mach_inst The binary instruction to decode.
36613087Sgabeblack@google.com    /// @retval A pointer to the corresponding StaticInst object.
36713087Sgabeblack@google.com    static
36813087Sgabeblack@google.com    StaticInstPtr<ISA> decode(MachInst mach_inst)
36913087Sgabeblack@google.com    {
37012907Sgabeblack@google.com#ifdef DECODE_CACHE_HASH_STATS
37112907Sgabeblack@google.com        // Simple stats on decode hash_map.  Turns out the default
37213087Sgabeblack@google.com        // hash function is as good as anything I could come up with.
37313087Sgabeblack@google.com        const int dump_every_n = 10000000;
37412907Sgabeblack@google.com        static int decodes_til_dump = dump_every_n;
37512837Sgabeblack@google.com
37612837Sgabeblack@google.com        if (--decodes_til_dump == 0) {
37712837Sgabeblack@google.com            dumpDecodeCacheStats();
378            decodes_til_dump = dump_every_n;
379        }
380#endif
381
382        typename DecodeCache::iterator iter = decodeCache.find(mach_inst);
383        if (iter != decodeCache.end()) {
384            return iter->second;
385        }
386
387        StaticInstPtr<ISA> si = ISA::decodeInst(mach_inst);
388        decodeCache[mach_inst] = si;
389        return si;
390    }
391};
392
393typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
394
395/// Reference-counted pointer to a StaticInst object.
396/// This type should be used instead of "StaticInst<ISA> *" so that
397/// StaticInst objects can be properly reference-counted.
398template <class ISA>
399class StaticInstPtr : public RefCountingPtr<StaticInst<ISA> >
400{
401  public:
402    /// Constructor.
403    StaticInstPtr()
404        : RefCountingPtr<StaticInst<ISA> >()
405    {
406    }
407
408    /// Conversion from "StaticInst<ISA> *".
409    StaticInstPtr(StaticInst<ISA> *p)
410        : RefCountingPtr<StaticInst<ISA> >(p)
411    {
412    }
413
414    /// Copy constructor.
415    StaticInstPtr(const StaticInstPtr &r)
416        : RefCountingPtr<StaticInst<ISA> >(r)
417    {
418    }
419
420    /// Construct directly from machine instruction.
421    /// Calls StaticInst<ISA>::decode().
422    StaticInstPtr(typename ISA::MachInst mach_inst)
423        : RefCountingPtr<StaticInst<ISA> >(StaticInst<ISA>::decode(mach_inst))
424    {
425    }
426
427    /// Convert to pointer to StaticInstBase class.
428    operator const StaticInstBasePtr()
429    {
430        return get();
431    }
432};
433
434#endif // __STATIC_INST_HH__
435