static_inst.hh revision 2312
112855Sgabeblack@google.com/*
212855Sgabeblack@google.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
312855Sgabeblack@google.com * All rights reserved.
412855Sgabeblack@google.com *
512855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612855Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112855Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412855Sgabeblack@google.com * this software without specific prior written permission.
1512855Sgabeblack@google.com *
1612855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712855Sgabeblack@google.com */
2812855Sgabeblack@google.com
2912855Sgabeblack@google.com#ifndef __CPU_STATIC_INST_HH__
3012855Sgabeblack@google.com#define __CPU_STATIC_INST_HH__
3112855Sgabeblack@google.com
3212855Sgabeblack@google.com#include <bitset>
3312855Sgabeblack@google.com#include <string>
3412855Sgabeblack@google.com
3512855Sgabeblack@google.com#include "base/hashmap.hh"
3612855Sgabeblack@google.com#include "base/refcnt.hh"
3712855Sgabeblack@google.com#include "encumbered/cpu/full/op_class.hh"
3812855Sgabeblack@google.com#include "sim/host.hh"
3912855Sgabeblack@google.com#include "arch/isa_traits.hh"
4012855Sgabeblack@google.com
4112855Sgabeblack@google.com// forward declarations
4212855Sgabeblack@google.comstruct AlphaSimpleImpl;
4312855Sgabeblack@google.comstruct OzoneImpl;
4412855Sgabeblack@google.comstruct SimpleImpl;
4512855Sgabeblack@google.comclass ExecContext;
4612855Sgabeblack@google.comclass DynInst;
4712855Sgabeblack@google.com
4812855Sgabeblack@google.comtemplate <class Impl>
4912855Sgabeblack@google.comclass AlphaDynInst;
5012855Sgabeblack@google.com
5112855Sgabeblack@google.comtemplate <class Impl>
5212855Sgabeblack@google.comclass OzoneDynInst;
5312855Sgabeblack@google.com
5412855Sgabeblack@google.comclass CheckerCPU;
5512855Sgabeblack@google.comclass FastCPU;
5612855Sgabeblack@google.comclass SimpleCPU;
5712855Sgabeblack@google.comclass InorderCPU;
5812855Sgabeblack@google.comclass SymbolTable;
5912855Sgabeblack@google.com
6012855Sgabeblack@google.comnamespace Trace {
6112855Sgabeblack@google.com    class InstRecord;
6212855Sgabeblack@google.com}
6312855Sgabeblack@google.com
6412855Sgabeblack@google.com/**
6512855Sgabeblack@google.com * Base, ISA-independent static instruction class.
6612855Sgabeblack@google.com *
6712855Sgabeblack@google.com * The main component of this class is the vector of flags and the
6812855Sgabeblack@google.com * associated methods for reading them.  Any object that can rely
6912855Sgabeblack@google.com * solely on these flags can process instructions without being
7012855Sgabeblack@google.com * recompiled for multiple ISAs.
7112855Sgabeblack@google.com */
7212855Sgabeblack@google.comclass StaticInstBase : public RefCounted
7312855Sgabeblack@google.com{
7412855Sgabeblack@google.com  protected:
7512855Sgabeblack@google.com
7612855Sgabeblack@google.com    /// Set of boolean static instruction properties.
7712855Sgabeblack@google.com    ///
7812855Sgabeblack@google.com    /// Notes:
7912855Sgabeblack@google.com    /// - The IsInteger and IsFloating flags are based on the class of
8012855Sgabeblack@google.com    /// registers accessed by the instruction.  Although most
8112855Sgabeblack@google.com    /// instructions will have exactly one of these two flags set, it
8212855Sgabeblack@google.com    /// is possible for an instruction to have neither (e.g., direct
8312855Sgabeblack@google.com    /// unconditional branches, memory barriers) or both (e.g., an
8412855Sgabeblack@google.com    /// FP/int conversion).
8512855Sgabeblack@google.com    /// - If IsMemRef is set, then exactly one of IsLoad or IsStore
8612855Sgabeblack@google.com    /// will be set.
8712855Sgabeblack@google.com    /// - If IsControl is set, then exactly one of IsDirectControl or
8812855Sgabeblack@google.com    /// IsIndirect Control will be set, and exactly one of
8912855Sgabeblack@google.com    /// IsCondControl or IsUncondControl will be set.
9012855Sgabeblack@google.com    /// - IsSerializing, IsMemBarrier, and IsWriteBarrier are
9112855Sgabeblack@google.com    /// implemented as flags since in the current model there's no
9212855Sgabeblack@google.com    /// other way for instructions to inject behavior into the
9312855Sgabeblack@google.com    /// pipeline outside of fetch.  Once we go to an exec-in-exec CPU
9412855Sgabeblack@google.com    /// model we should be able to get rid of these flags and
9512855Sgabeblack@google.com    /// implement this behavior via the execute() methods.
9612855Sgabeblack@google.com    ///
9712855Sgabeblack@google.com    enum Flags {
9812855Sgabeblack@google.com        IsNop,		///< Is a no-op (no effect at all).
9912855Sgabeblack@google.com
10012855Sgabeblack@google.com        IsInteger,	///< References integer regs.
10112855Sgabeblack@google.com        IsFloating,	///< References FP regs.
10212855Sgabeblack@google.com
10312855Sgabeblack@google.com        IsMemRef,	///< References memory (load, store, or prefetch).
10412855Sgabeblack@google.com        IsLoad,		///< Reads from memory (load or prefetch).
10512855Sgabeblack@google.com        IsStore,	///< Writes to memory.
10612855Sgabeblack@google.com        IsInstPrefetch,	///< Instruction-cache prefetch.
10712855Sgabeblack@google.com        IsDataPrefetch,	///< Data-cache prefetch.
10812855Sgabeblack@google.com        IsCopy,         ///< Fast Cache block copy
10912855Sgabeblack@google.com
11012855Sgabeblack@google.com        IsControl,		///< Control transfer instruction.
11112855Sgabeblack@google.com        IsDirectControl,	///< PC relative control transfer.
11212855Sgabeblack@google.com        IsIndirectControl,	///< Register indirect control transfer.
11312855Sgabeblack@google.com        IsCondControl,		///< Conditional control transfer.
11412855Sgabeblack@google.com        IsUncondControl,	///< Unconditional control transfer.
11512855Sgabeblack@google.com        IsCall,			///< Subroutine call.
11612855Sgabeblack@google.com        IsReturn,		///< Subroutine return.
11712855Sgabeblack@google.com
11812855Sgabeblack@google.com        IsCondDelaySlot,///< Conditional Delay-Slot Instruction
11912855Sgabeblack@google.com
12012855Sgabeblack@google.com        IsThreadSync,	///< Thread synchronization operation.
12112855Sgabeblack@google.com
12212855Sgabeblack@google.com        IsSerializing,	///< Serializes pipeline: won't execute until all
12312855Sgabeblack@google.com                        /// older instructions have committed.
12412855Sgabeblack@google.com        IsSerializeBefore,
12512855Sgabeblack@google.com        IsSerializeAfter,
12612855Sgabeblack@google.com        IsMemBarrier,	///< Is a memory barrier
12712855Sgabeblack@google.com        IsWriteBarrier,	///< Is a write barrier
12812855Sgabeblack@google.com
12912855Sgabeblack@google.com        IsNonSpeculative, ///< Should not be executed speculatively
13012855Sgabeblack@google.com        IsQuiesce,
13112855Sgabeblack@google.com
13212855Sgabeblack@google.com        IsUnverifiable,
13312855Sgabeblack@google.com
13412855Sgabeblack@google.com        NumFlags
13512855Sgabeblack@google.com    };
13612855Sgabeblack@google.com
13712855Sgabeblack@google.com    /// Flag values for this instruction.
13812855Sgabeblack@google.com    std::bitset<NumFlags> flags;
13912855Sgabeblack@google.com
14012855Sgabeblack@google.com    /// See opClass().
14112855Sgabeblack@google.com    OpClass _opClass;
14212855Sgabeblack@google.com
14312855Sgabeblack@google.com    /// See numSrcRegs().
14412855Sgabeblack@google.com    int8_t _numSrcRegs;
14512855Sgabeblack@google.com
14612855Sgabeblack@google.com    /// See numDestRegs().
14712855Sgabeblack@google.com    int8_t _numDestRegs;
14812855Sgabeblack@google.com
14912855Sgabeblack@google.com    /// The following are used to track physical register usage
15012855Sgabeblack@google.com    /// for machines with separate int & FP reg files.
15112855Sgabeblack@google.com    //@{
15212855Sgabeblack@google.com    int8_t _numFPDestRegs;
15312855Sgabeblack@google.com    int8_t _numIntDestRegs;
15412855Sgabeblack@google.com    //@}
15512855Sgabeblack@google.com
15612855Sgabeblack@google.com    /// Constructor.
15712855Sgabeblack@google.com    /// It's important to initialize everything here to a sane
15812855Sgabeblack@google.com    /// default, since the decoder generally only overrides
15912855Sgabeblack@google.com    /// the fields that are meaningful for the particular
16012855Sgabeblack@google.com    /// instruction.
16112855Sgabeblack@google.com    StaticInstBase(OpClass __opClass)
16212855Sgabeblack@google.com        : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
16312855Sgabeblack@google.com          _numFPDestRegs(0), _numIntDestRegs(0)
16412855Sgabeblack@google.com    {
16512855Sgabeblack@google.com    }
16612855Sgabeblack@google.com
16712855Sgabeblack@google.com  public:
16812855Sgabeblack@google.com
16912855Sgabeblack@google.com    /// @name Register information.
17012855Sgabeblack@google.com    /// The sum of numFPDestRegs() and numIntDestRegs() equals
17112855Sgabeblack@google.com    /// numDestRegs().  The former two functions are used to track
17212855Sgabeblack@google.com    /// physical register usage for machines with separate int & FP
17312855Sgabeblack@google.com    /// reg files.
17412855Sgabeblack@google.com    //@{
17512855Sgabeblack@google.com    /// Number of source registers.
17612855Sgabeblack@google.com    int8_t numSrcRegs()  const { return _numSrcRegs; }
17712855Sgabeblack@google.com    /// Number of destination registers.
17812855Sgabeblack@google.com    int8_t numDestRegs() const { return _numDestRegs; }
17912855Sgabeblack@google.com    /// Number of floating-point destination regs.
18012855Sgabeblack@google.com    int8_t numFPDestRegs()  const { return _numFPDestRegs; }
18112855Sgabeblack@google.com    /// Number of integer destination regs.
18212855Sgabeblack@google.com    int8_t numIntDestRegs() const { return _numIntDestRegs; }
18312855Sgabeblack@google.com    //@}
18412855Sgabeblack@google.com
18512855Sgabeblack@google.com    /// @name Flag accessors.
18612855Sgabeblack@google.com    /// These functions are used to access the values of the various
18712855Sgabeblack@google.com    /// instruction property flags.  See StaticInstBase::Flags for descriptions
18812855Sgabeblack@google.com    /// of the individual flags.
18912855Sgabeblack@google.com    //@{
19012855Sgabeblack@google.com
19112855Sgabeblack@google.com    bool isNop() 	  const { return flags[IsNop]; }
19212855Sgabeblack@google.com
19312855Sgabeblack@google.com    bool isMemRef()    	  const { return flags[IsMemRef]; }
19412855Sgabeblack@google.com    bool isLoad()	  const { return flags[IsLoad]; }
19512855Sgabeblack@google.com    bool isStore()	  const { return flags[IsStore]; }
19612855Sgabeblack@google.com    bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
19712855Sgabeblack@google.com    bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
19812855Sgabeblack@google.com    bool isCopy()         const { return flags[IsCopy];}
19912855Sgabeblack@google.com
20012855Sgabeblack@google.com    bool isInteger()	  const { return flags[IsInteger]; }
20112855Sgabeblack@google.com    bool isFloating()	  const { return flags[IsFloating]; }
20212855Sgabeblack@google.com
20312855Sgabeblack@google.com    bool isControl()	  const { return flags[IsControl]; }
20412855Sgabeblack@google.com    bool isCall()	  const { return flags[IsCall]; }
20512855Sgabeblack@google.com    bool isReturn()	  const { return flags[IsReturn]; }
20612855Sgabeblack@google.com    bool isDirectCtrl()	  const { return flags[IsDirectControl]; }
20712855Sgabeblack@google.com    bool isIndirectCtrl() const { return flags[IsIndirectControl]; }
20812855Sgabeblack@google.com    bool isCondCtrl()	  const { return flags[IsCondControl]; }
20912855Sgabeblack@google.com    bool isUncondCtrl()	  const { return flags[IsUncondControl]; }
21012855Sgabeblack@google.com
21112855Sgabeblack@google.com    bool isThreadSync()   const { return flags[IsThreadSync]; }
21212855Sgabeblack@google.com    bool isSerializing()  const { return flags[IsSerializing] ||
21312855Sgabeblack@google.com                                      flags[IsSerializeBefore] ||
21412855Sgabeblack@google.com                                      flags[IsSerializeAfter]; }
21512855Sgabeblack@google.com    bool isSerializeBefore() const { return flags[IsSerializeBefore]; }
21612855Sgabeblack@google.com    bool isSerializeAfter() const { return flags[IsSerializeAfter]; }
21712855Sgabeblack@google.com    bool isMemBarrier()   const { return flags[IsMemBarrier]; }
21812855Sgabeblack@google.com    bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
21912855Sgabeblack@google.com    bool isNonSpeculative() const { return flags[IsNonSpeculative]; }
22012855Sgabeblack@google.com    bool isQuiesce() const { return flags[IsQuiesce]; }
22112855Sgabeblack@google.com    bool isUnverifiable() const { return flags[IsUnverifiable]; }
22212855Sgabeblack@google.com    //@}
22312855Sgabeblack@google.com
22412855Sgabeblack@google.com    /// Operation class.  Used to select appropriate function unit in issue.
22512855Sgabeblack@google.com    OpClass opClass()     const { return _opClass; }
22612855Sgabeblack@google.com};
22712855Sgabeblack@google.com
22812855Sgabeblack@google.com
22912855Sgabeblack@google.com// forward declaration
23012855Sgabeblack@google.comclass StaticInstPtr;
23112855Sgabeblack@google.com
23212855Sgabeblack@google.com/**
23312855Sgabeblack@google.com * Generic yet ISA-dependent static instruction class.
23412855Sgabeblack@google.com *
23512855Sgabeblack@google.com * This class builds on StaticInstBase, defining fields and interfaces
23612855Sgabeblack@google.com * that are generic across all ISAs but that differ in details
23712855Sgabeblack@google.com * according to the specific ISA being used.
23812855Sgabeblack@google.com */
23912855Sgabeblack@google.comclass StaticInst : public StaticInstBase
24012855Sgabeblack@google.com{
24112855Sgabeblack@google.com  public:
24212855Sgabeblack@google.com
24312855Sgabeblack@google.com    /// Binary machine instruction type.
24412855Sgabeblack@google.com    typedef TheISA::MachInst MachInst;
24512855Sgabeblack@google.com    /// Binary extended machine instruction type.
24612855Sgabeblack@google.com    typedef TheISA::ExtMachInst ExtMachInst;
24712855Sgabeblack@google.com    /// Logical register index type.
24812855Sgabeblack@google.com    typedef TheISA::RegIndex RegIndex;
24912855Sgabeblack@google.com
25012855Sgabeblack@google.com    enum {
25112855Sgabeblack@google.com        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,	//< Max source regs
25212855Sgabeblack@google.com        MaxInstDestRegs = TheISA::MaxInstDestRegs,	//< Max dest regs
25312855Sgabeblack@google.com    };
25412855Sgabeblack@google.com
25512855Sgabeblack@google.com
25612855Sgabeblack@google.com    /// Return logical index (architectural reg num) of i'th destination reg.
25712855Sgabeblack@google.com    /// Only the entries from 0 through numDestRegs()-1 are valid.
25812855Sgabeblack@google.com    RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
25912855Sgabeblack@google.com
26012855Sgabeblack@google.com    /// Return logical index (architectural reg num) of i'th source reg.
26112855Sgabeblack@google.com    /// Only the entries from 0 through numSrcRegs()-1 are valid.
26212855Sgabeblack@google.com    RegIndex srcRegIdx(int i)  const { return _srcRegIdx[i]; }
26312855Sgabeblack@google.com
26412855Sgabeblack@google.com    /// Pointer to a statically allocated "null" instruction object.
26512855Sgabeblack@google.com    /// Used to give eaCompInst() and memAccInst() something to return
26612855Sgabeblack@google.com    /// when called on non-memory instructions.
26712855Sgabeblack@google.com    static StaticInstPtr nullStaticInstPtr;
26812855Sgabeblack@google.com
26912855Sgabeblack@google.com    /**
27012855Sgabeblack@google.com     * Memory references only: returns "fake" instruction representing
27112855Sgabeblack@google.com     * the effective address part of the memory operation.  Used to
27212855Sgabeblack@google.com     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
27312855Sgabeblack@google.com     * just the EA computation.
27412855Sgabeblack@google.com     */
27512855Sgabeblack@google.com    virtual const
27612855Sgabeblack@google.com    StaticInstPtr &eaCompInst() const { return nullStaticInstPtr; }
27712855Sgabeblack@google.com
27812855Sgabeblack@google.com    /**
27912855Sgabeblack@google.com     * Memory references only: returns "fake" instruction representing
28012855Sgabeblack@google.com     * the memory access part of the memory operation.  Used to
28112855Sgabeblack@google.com     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
28212855Sgabeblack@google.com     * just the memory access (not the EA computation).
28312855Sgabeblack@google.com     */
28412855Sgabeblack@google.com    virtual const
28512855Sgabeblack@google.com    StaticInstPtr &memAccInst() const { return nullStaticInstPtr; }
28612855Sgabeblack@google.com
28712855Sgabeblack@google.com    /// The binary machine instruction.
28812855Sgabeblack@google.com    const ExtMachInst machInst;
28912855Sgabeblack@google.com
29012855Sgabeblack@google.com  protected:
29112855Sgabeblack@google.com
29212855Sgabeblack@google.com    /// See destRegIdx().
29312855Sgabeblack@google.com    RegIndex _destRegIdx[MaxInstDestRegs];
29412855Sgabeblack@google.com    /// See srcRegIdx().
29512855Sgabeblack@google.com    RegIndex _srcRegIdx[MaxInstSrcRegs];
29612855Sgabeblack@google.com
29712855Sgabeblack@google.com    /**
29812855Sgabeblack@google.com     * Base mnemonic (e.g., "add").  Used by generateDisassembly()
29912855Sgabeblack@google.com     * methods.  Also useful to readily identify instructions from
30012855Sgabeblack@google.com     * within the debugger when #cachedDisassembly has not been
30112855Sgabeblack@google.com     * initialized.
30212855Sgabeblack@google.com     */
30312855Sgabeblack@google.com    const char *mnemonic;
30412855Sgabeblack@google.com
30512855Sgabeblack@google.com    /**
30612855Sgabeblack@google.com     * String representation of disassembly (lazily evaluated via
30712855Sgabeblack@google.com     * disassemble()).
30812855Sgabeblack@google.com     */
30912855Sgabeblack@google.com    mutable std::string *cachedDisassembly;
31012855Sgabeblack@google.com
31112855Sgabeblack@google.com    /**
31212855Sgabeblack@google.com     * Internal function to generate disassembly string.
31312855Sgabeblack@google.com     */
31412855Sgabeblack@google.com    virtual std::string
31512855Sgabeblack@google.com    generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
31612855Sgabeblack@google.com
31712855Sgabeblack@google.com    /// Constructor.
31812855Sgabeblack@google.com    StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass)
31912855Sgabeblack@google.com        : StaticInstBase(__opClass),
32012855Sgabeblack@google.com          machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
32112855Sgabeblack@google.com    {
32212855Sgabeblack@google.com    }
32312855Sgabeblack@google.com
32412855Sgabeblack@google.com  public:
32512855Sgabeblack@google.com
32612855Sgabeblack@google.com    virtual ~StaticInst()
32712855Sgabeblack@google.com    {
32812855Sgabeblack@google.com        if (cachedDisassembly)
32912855Sgabeblack@google.com            delete cachedDisassembly;
33012855Sgabeblack@google.com    }
33112855Sgabeblack@google.com
33212855Sgabeblack@google.com/**
33312855Sgabeblack@google.com * The execute() signatures are auto-generated by scons based on the
33412855Sgabeblack@google.com * set of CPU models we are compiling in today.
33512855Sgabeblack@google.com */
33612855Sgabeblack@google.com#include "cpu/static_inst_exec_sigs.hh"
33712855Sgabeblack@google.com
33812855Sgabeblack@google.com    /**
33912855Sgabeblack@google.com     * Return the target address for a PC-relative branch.
34012855Sgabeblack@google.com     * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
34112855Sgabeblack@google.com     * should be true).
34212855Sgabeblack@google.com     */
34312855Sgabeblack@google.com    virtual Addr branchTarget(Addr branchPC) const
34412855Sgabeblack@google.com    {
34512855Sgabeblack@google.com        panic("StaticInst::branchTarget() called on instruction "
34612855Sgabeblack@google.com              "that is not a PC-relative branch.");
34712855Sgabeblack@google.com    }
34812855Sgabeblack@google.com
34912855Sgabeblack@google.com    /**
35012855Sgabeblack@google.com     * Return the target address for an indirect branch (jump).  The
35112855Sgabeblack@google.com     * register value is read from the supplied execution context, so
35212855Sgabeblack@google.com     * the result is valid only if the execution context is about to
35312855Sgabeblack@google.com     * execute the branch in question.  Invalid if not an indirect
35412855Sgabeblack@google.com     * branch (i.e. isIndirectCtrl() should be true).
35512855Sgabeblack@google.com     */
35612855Sgabeblack@google.com    virtual Addr branchTarget(ExecContext *xc) const
35712855Sgabeblack@google.com    {
35812855Sgabeblack@google.com        panic("StaticInst::branchTarget() called on instruction "
35912855Sgabeblack@google.com              "that is not an indirect branch.");
36012855Sgabeblack@google.com    }
36112855Sgabeblack@google.com
36212855Sgabeblack@google.com    /**
36312855Sgabeblack@google.com     * Return true if the instruction is a control transfer, and if so,
36412855Sgabeblack@google.com     * return the target address as well.
36512855Sgabeblack@google.com     */
36612855Sgabeblack@google.com    bool hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const;
36712855Sgabeblack@google.com
36812855Sgabeblack@google.com    /**
36912855Sgabeblack@google.com     * Return string representation of disassembled instruction.
37012855Sgabeblack@google.com     * The default version of this function will call the internal
37112855Sgabeblack@google.com     * virtual generateDisassembly() function to get the string,
37212855Sgabeblack@google.com     * then cache it in #cachedDisassembly.  If the disassembly
37312855Sgabeblack@google.com     * should not be cached, this function should be overridden directly.
37412855Sgabeblack@google.com     */
37512855Sgabeblack@google.com    virtual const std::string &disassemble(Addr pc,
37612855Sgabeblack@google.com                                           const SymbolTable *symtab = 0) const
37712855Sgabeblack@google.com    {
37812855Sgabeblack@google.com        if (!cachedDisassembly)
37912855Sgabeblack@google.com            cachedDisassembly =
38012855Sgabeblack@google.com                new std::string(generateDisassembly(pc, symtab));
38112855Sgabeblack@google.com
38212855Sgabeblack@google.com        return *cachedDisassembly;
38312855Sgabeblack@google.com    }
38412855Sgabeblack@google.com
38512855Sgabeblack@google.com    /// Decoded instruction cache type.
38612855Sgabeblack@google.com    /// For now we're using a generic hash_map; this seems to work
38712855Sgabeblack@google.com    /// pretty well.
38812855Sgabeblack@google.com    typedef m5::hash_map<ExtMachInst, StaticInstPtr> DecodeCache;
38912855Sgabeblack@google.com
39012855Sgabeblack@google.com    /// A cache of decoded instruction objects.
39112855Sgabeblack@google.com    static DecodeCache decodeCache;
39212855Sgabeblack@google.com
39312855Sgabeblack@google.com    /**
39412855Sgabeblack@google.com     * Dump some basic stats on the decode cache hash map.
39512855Sgabeblack@google.com     * Only gets called if DECODE_CACHE_HASH_STATS is defined.
39612855Sgabeblack@google.com     */
39712855Sgabeblack@google.com    static void dumpDecodeCacheStats();
39812855Sgabeblack@google.com
39912855Sgabeblack@google.com    /// Decode a machine instruction.
40012855Sgabeblack@google.com    /// @param mach_inst The binary instruction to decode.
40112855Sgabeblack@google.com    /// @retval A pointer to the corresponding StaticInst object.
40212855Sgabeblack@google.com    //This is defined as inline below.
40312855Sgabeblack@google.com    static StaticInstPtr decode(ExtMachInst mach_inst);
40412855Sgabeblack@google.com};
40512855Sgabeblack@google.com
40612855Sgabeblack@google.comtypedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
40712855Sgabeblack@google.com
40812855Sgabeblack@google.com/// Reference-counted pointer to a StaticInst object.
40912855Sgabeblack@google.com/// This type should be used instead of "StaticInst *" so that
41012855Sgabeblack@google.com/// StaticInst objects can be properly reference-counted.
41112855Sgabeblack@google.comclass StaticInstPtr : public RefCountingPtr<StaticInst>
41212855Sgabeblack@google.com{
41312855Sgabeblack@google.com  public:
41412855Sgabeblack@google.com    /// Constructor.
41512855Sgabeblack@google.com    StaticInstPtr()
41612855Sgabeblack@google.com        : RefCountingPtr<StaticInst>()
41712855Sgabeblack@google.com    {
41812855Sgabeblack@google.com    }
41912855Sgabeblack@google.com
42012855Sgabeblack@google.com    /// Conversion from "StaticInst *".
42112855Sgabeblack@google.com    StaticInstPtr(StaticInst *p)
42212855Sgabeblack@google.com        : RefCountingPtr<StaticInst>(p)
42312855Sgabeblack@google.com    {
42412855Sgabeblack@google.com    }
42512855Sgabeblack@google.com
42612855Sgabeblack@google.com    /// Copy constructor.
42712855Sgabeblack@google.com    StaticInstPtr(const StaticInstPtr &r)
42812855Sgabeblack@google.com        : RefCountingPtr<StaticInst>(r)
42912855Sgabeblack@google.com    {
43012855Sgabeblack@google.com    }
43112855Sgabeblack@google.com
43212855Sgabeblack@google.com    /// Construct directly from machine instruction.
43312855Sgabeblack@google.com    /// Calls StaticInst::decode().
43412855Sgabeblack@google.com    StaticInstPtr(TheISA::ExtMachInst mach_inst)
43512855Sgabeblack@google.com        : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
43612855Sgabeblack@google.com    {
43712855Sgabeblack@google.com    }
43812855Sgabeblack@google.com
43912855Sgabeblack@google.com    /// Convert to pointer to StaticInstBase class.
44012855Sgabeblack@google.com    operator const StaticInstBasePtr()
44112855Sgabeblack@google.com    {
44212855Sgabeblack@google.com        return this->get();
44312855Sgabeblack@google.com    }
44412855Sgabeblack@google.com};
44512855Sgabeblack@google.com
44612855Sgabeblack@google.cominline StaticInstPtr
44712855Sgabeblack@google.comStaticInst::decode(StaticInst::ExtMachInst mach_inst)
44812855Sgabeblack@google.com{
44912855Sgabeblack@google.com#ifdef DECODE_CACHE_HASH_STATS
45012855Sgabeblack@google.com    // Simple stats on decode hash_map.  Turns out the default
45112855Sgabeblack@google.com    // hash function is as good as anything I could come up with.
45212855Sgabeblack@google.com    const int dump_every_n = 10000000;
45312855Sgabeblack@google.com    static int decodes_til_dump = dump_every_n;
45412855Sgabeblack@google.com
45512855Sgabeblack@google.com    if (--decodes_til_dump == 0) {
45612855Sgabeblack@google.com        dumpDecodeCacheStats();
45712855Sgabeblack@google.com        decodes_til_dump = dump_every_n;
45812855Sgabeblack@google.com    }
45912855Sgabeblack@google.com#endif
46012855Sgabeblack@google.com
46112855Sgabeblack@google.com    DecodeCache::iterator iter = decodeCache.find(mach_inst);
46212855Sgabeblack@google.com    if (iter != decodeCache.end()) {
46312855Sgabeblack@google.com        return iter->second;
46412855Sgabeblack@google.com    }
46512855Sgabeblack@google.com
46612855Sgabeblack@google.com    StaticInstPtr si = TheISA::decodeInst(mach_inst);
46712855Sgabeblack@google.com    decodeCache[mach_inst] = si;
46812855Sgabeblack@google.com    return si;
46912855Sgabeblack@google.com}
47012855Sgabeblack@google.com
47112855Sgabeblack@google.com#endif // __CPU_STATIC_INST_HH__
47212855Sgabeblack@google.com