static_inst.hh revision 10319:4207f9bfcceb
12SN/A/*
21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32SN/A * Copyright (c) 2013 Advanced Micro Devices, Inc.
42SN/A * All rights reserved.
52SN/A *
62SN/A * Redistribution and use in source and binary forms, with or without
72SN/A * modification, are permitted provided that the following conditions are
82SN/A * met: redistributions of source code must retain the above copyright
92SN/A * notice, this list of conditions and the following disclaimer;
102SN/A * redistributions in binary form must reproduce the above copyright
112SN/A * notice, this list of conditions and the following disclaimer in the
122SN/A * documentation and/or other materials provided with the distribution;
132SN/A * neither the name of the copyright holders nor the names of its
142SN/A * contributors may be used to endorse or promote products derived from
152SN/A * this software without specific prior written permission.
162SN/A *
172SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272665Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu *
292665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt
302SN/A */
312SN/A
324997Sgblack@eecs.umich.edu#ifndef __CPU_STATIC_INST_HH__
331110SN/A#define __CPU_STATIC_INST_HH__
344997Sgblack@eecs.umich.edu
358229Snate@binkert.org#include <bitset>
368229Snate@binkert.org#include <string>
372680Sktlim@umich.edu
387676Snate@binkert.org#include "arch/registers.hh"
394997Sgblack@eecs.umich.edu#include "arch/types.hh"
408229Snate@binkert.org#include "base/misc.hh"
412800Ssaidi@eecs.umich.edu#include "base/refcnt.hh"
422289SN/A#include "base/types.hh"
432SN/A#include "config/the_isa.hh"
445569Snate@binkert.org#include "cpu/op_class.hh"
452167SN/A#include "cpu/static_inst_fwd.hh"
462203SN/A#include "cpu/thread_context.hh"
472203SN/A#include "enums/StaticInstFlags.hh"
482222SN/A#include "sim/fault_fwd.hh"
492166SN/A
502203SN/A// forward declarations
512203SN/Aclass Packet;
522222SN/A
532166SN/Aclass ExecContext;
542147SN/A
552147SN/Aclass SymbolTable;
562222SN/A
572147SN/Anamespace Trace {
582147SN/A    class InstRecord;
592147SN/A}
602222SN/A
612147SN/A/**
622147SN/A * Base, ISA-independent static instruction class.
632147SN/A *
642222SN/A * The main component of this class is the vector of flags and the
652147SN/A * associated methods for reading them.  Any object that can rely
662147SN/A * solely on these flags can process instructions without being
672147SN/A * recompiled for multiple ISAs.
682222SN/A */
692147SN/Aclass StaticInst : public RefCounted, public StaticInstFlags
702147SN/A{
712147SN/A  public:
722222SN/A    /// Binary extended machine instruction type.
732147SN/A    typedef TheISA::ExtMachInst ExtMachInst;
742147SN/A    /// Logical register index type.
752147SN/A    typedef TheISA::RegIndex RegIndex;
762222SN/A
772147SN/A    enum {
782147SN/A        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,        //< Max source regs
792147SN/A        MaxInstDestRegs = TheISA::MaxInstDestRegs       //< Max dest regs
802222SN/A    };
812147SN/A
822289SN/A  protected:
832289SN/A
842289SN/A    /// Flag values for this instruction.
852289SN/A    std::bitset<Num_Flags> flags;
862147SN/A
872147SN/A    /// See opClass().
882222SN/A    OpClass _opClass;
892147SN/A
902147SN/A    /// See numSrcRegs().
912147SN/A    int8_t _numSrcRegs;
922222SN/A
932147SN/A    /// See numDestRegs().
942147SN/A    int8_t _numDestRegs;
952147SN/A
962222SN/A    /// The following are used to track physical register usage
972147SN/A    /// for machines with separate int & FP reg files.
982147SN/A    //@{
992147SN/A    int8_t _numFPDestRegs;
1002222SN/A    int8_t _numIntDestRegs;
1012147SN/A    int8_t _numCCDestRegs;
1022147SN/A    //@}
1032147SN/A
1042222SN/A  public:
1052147SN/A
1062147SN/A    /// @name Register information.
1072147SN/A    /// The sum of numFPDestRegs() and numIntDestRegs() equals
1082222SN/A    /// numDestRegs().  The former two functions are used to track
1092147SN/A    /// physical register usage for machines with separate int & FP
1102174SN/A    /// reg files.
1112174SN/A    //@{
1125569Snate@binkert.org    /// Number of source registers.
1137678Sgblack@eecs.umich.edu    int8_t numSrcRegs()  const { return _numSrcRegs; }
1142174SN/A    /// Number of destination registers.
1152680Sktlim@umich.edu    int8_t numDestRegs() const { return _numDestRegs; }
1162222SN/A    /// Number of floating-point destination regs.
1172174SN/A    int8_t numFPDestRegs()  const { return _numFPDestRegs; }
1187720Sgblack@eecs.umich.edu    /// Number of integer destination regs.
1197720Sgblack@eecs.umich.edu    int8_t numIntDestRegs() const { return _numIntDestRegs; }
1202196SN/A    //@}
1217720Sgblack@eecs.umich.edu
1227720Sgblack@eecs.umich.edu    /// @name Flag accessors.
1232196SN/A    /// These functions are used to access the values of the various
1242201SN/A    /// instruction property flags.  See StaticInst::Flags for descriptions
1252196SN/A    /// of the individual flags.
1265568Snate@binkert.org    //@{
1275568Snate@binkert.org
1282196SN/A    bool isNop()          const { return flags[IsNop]; }
1292196SN/A
1307720Sgblack@eecs.umich.edu    bool isMemRef()       const { return flags[IsMemRef]; }
1317720Sgblack@eecs.umich.edu    bool isLoad()         const { return flags[IsLoad]; }
1322174SN/A    bool isStore()        const { return flags[IsStore]; }
1332174SN/A    bool isStoreConditional()     const { return flags[IsStoreConditional]; }
1345569Snate@binkert.org    bool isInstPrefetch() const { return flags[IsInstPrefetch]; }
1357678Sgblack@eecs.umich.edu    bool isDataPrefetch() const { return flags[IsDataPrefetch]; }
1362201SN/A    bool isPrefetch()     const { return isInstPrefetch() ||
1372680Sktlim@umich.edu                                         isDataPrefetch(); }
1382201SN/A
1392201SN/A    bool isInteger()      const { return flags[IsInteger]; }
1402201SN/A    bool isFloating()     const { return flags[IsFloating]; }
1415569Snate@binkert.org    bool isCC()           const { return flags[IsCC]; }
1427678Sgblack@eecs.umich.edu
1432289SN/A    bool isControl()      const { return flags[IsControl]; }
1442289SN/A    bool isCall()         const { return flags[IsCall]; }
1452289SN/A    bool isReturn()       const { return flags[IsReturn]; }
1462289SN/A    bool isDirectCtrl()   const { return flags[IsDirectControl]; }
1472289SN/A    bool isIndirectCtrl() const { return flags[IsIndirectControl]; }
1482289SN/A    bool isCondCtrl()     const { return flags[IsCondControl]; }
1495569Snate@binkert.org    bool isUncondCtrl()   const { return flags[IsUncondControl]; }
1506739Sgblack@eecs.umich.edu    bool isCondDelaySlot() const { return flags[IsCondDelaySlot]; }
1512289SN/A
1525568Snate@binkert.org    bool isThreadSync()   const { return flags[IsThreadSync]; }
1532289SN/A    bool isSerializing()  const { return flags[IsSerializing] ||
1542289SN/A                                      flags[IsSerializeBefore] ||
1557678Sgblack@eecs.umich.edu                                      flags[IsSerializeAfter]; }
1565568Snate@binkert.org    bool isSerializeBefore() const { return flags[IsSerializeBefore]; }
1577678Sgblack@eecs.umich.edu    bool isSerializeAfter() const { return flags[IsSerializeAfter]; }
1587678Sgblack@eecs.umich.edu    bool isSquashAfter() const { return flags[IsSquashAfter]; }
1595569Snate@binkert.org    bool isMemBarrier()   const { return flags[IsMemBarrier]; }
1602289SN/A    bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
1612289SN/A    bool isNonSpeculative() const { return flags[IsNonSpeculative]; }
1625568Snate@binkert.org    bool isQuiesce() const { return flags[IsQuiesce]; }
1635568Snate@binkert.org    bool isIprAccess() const { return flags[IsIprAccess]; }
1642289SN/A    bool isUnverifiable() const { return flags[IsUnverifiable]; }
1652289SN/A    bool isSyscall() const { return flags[IsSyscall]; }
1662680Sktlim@umich.edu    bool isMacroop() const { return flags[IsMacroop]; }
1672289SN/A    bool isMicroop() const { return flags[IsMicroop]; }
1682289SN/A    bool isDelayedCommit() const { return flags[IsDelayedCommit]; }
1695569Snate@binkert.org    bool isLastMicroop() const { return flags[IsLastMicroop]; }
1707678Sgblack@eecs.umich.edu    bool isFirstMicroop() const { return flags[IsFirstMicroop]; }
1712289SN/A    //This flag doesn't do anything yet
1722680Sktlim@umich.edu    bool isMicroBranch() const { return flags[IsMicroBranch]; }
1735568Snate@binkert.org    //@}
1745568Snate@binkert.org
1755569Snate@binkert.org    void setLastMicroop() { flags[IsLastMicroop] = true; }
1762289SN/A    void setDelayedCommit() { flags[IsDelayedCommit] = true; }
1772289SN/A    void setFlag(Flags f) { flags[f] = true; }
1782680Sktlim@umich.edu
1792289SN/A    /// Operation class.  Used to select appropriate function unit in issue.
1802289SN/A    OpClass opClass()     const { return _opClass; }
1814997Sgblack@eecs.umich.edu
1824997Sgblack@eecs.umich.edu
1835569Snate@binkert.org    /// Return logical index (architectural reg num) of i'th destination reg.
1847678Sgblack@eecs.umich.edu    /// Only the entries from 0 through numDestRegs()-1 are valid.
1854997Sgblack@eecs.umich.edu    RegIndex destRegIdx(int i) const { return _destRegIdx[i]; }
1864997Sgblack@eecs.umich.edu
1875184Sgblack@eecs.umich.edu    /// Return logical index (architectural reg num) of i'th source reg.
1885184Sgblack@eecs.umich.edu    /// Only the entries from 0 through numSrcRegs()-1 are valid.
1895569Snate@binkert.org    RegIndex srcRegIdx(int i)  const { return _srcRegIdx[i]; }
1904997Sgblack@eecs.umich.edu
1914997Sgblack@eecs.umich.edu    /// Pointer to a statically allocated "null" instruction object.
1924997Sgblack@eecs.umich.edu    /// Used to give eaCompInst() and memAccInst() something to return
1935004Sgblack@eecs.umich.edu    /// when called on non-memory instructions.
1944997Sgblack@eecs.umich.edu    static StaticInstPtr nullStaticInstPtr;
1954997Sgblack@eecs.umich.edu
1964997Sgblack@eecs.umich.edu    /**
1975569Snate@binkert.org     * Memory references only: returns "fake" instruction representing
1987678Sgblack@eecs.umich.edu     * the effective address part of the memory operation.  Used to
1994997Sgblack@eecs.umich.edu     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
2004997Sgblack@eecs.umich.edu     * just the EA computation.
2015184Sgblack@eecs.umich.edu     */
2025184Sgblack@eecs.umich.edu    virtual const
2035569Snate@binkert.org    StaticInstPtr &eaCompInst() const { return nullStaticInstPtr; }
2044997Sgblack@eecs.umich.edu
2055184Sgblack@eecs.umich.edu    /**
2064997Sgblack@eecs.umich.edu     * Memory references only: returns "fake" instruction representing
2075569Snate@binkert.org     * the memory access part of the memory operation.  Used to
2084997Sgblack@eecs.umich.edu     * obtain the dependence info (numSrcRegs and srcRegIdx[]) for
2094997Sgblack@eecs.umich.edu     * just the memory access (not the EA computation).
2105004Sgblack@eecs.umich.edu     */
2114997Sgblack@eecs.umich.edu    virtual const
2124997Sgblack@eecs.umich.edu    StaticInstPtr &memAccInst() const { return nullStaticInstPtr; }
2134997Sgblack@eecs.umich.edu
2142174SN/A    /// The binary machine instruction.
2152174SN/A    const ExtMachInst machInst;
2162167SN/A
2172167SN/A  protected:
218
219    /// See destRegIdx().
220    RegIndex _destRegIdx[MaxInstDestRegs];
221    /// See srcRegIdx().
222    RegIndex _srcRegIdx[MaxInstSrcRegs];
223
224    /**
225     * Base mnemonic (e.g., "add").  Used by generateDisassembly()
226     * methods.  Also useful to readily identify instructions from
227     * within the debugger when #cachedDisassembly has not been
228     * initialized.
229     */
230    const char *mnemonic;
231
232    /**
233     * String representation of disassembly (lazily evaluated via
234     * disassemble()).
235     */
236    mutable std::string *cachedDisassembly;
237
238    /**
239     * Internal function to generate disassembly string.
240     */
241    virtual std::string
242    generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
243
244    /// Constructor.
245    /// It's important to initialize everything here to a sane
246    /// default, since the decoder generally only overrides
247    /// the fields that are meaningful for the particular
248    /// instruction.
249    StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass)
250        : _opClass(__opClass), _numSrcRegs(0), _numDestRegs(0),
251          _numFPDestRegs(0), _numIntDestRegs(0),
252          machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0)
253    { }
254
255  public:
256    virtual ~StaticInst();
257
258    virtual Fault execute(ExecContext *xc,
259                          Trace::InstRecord *traceData) const = 0;
260    virtual Fault eaComp(ExecContext *xc,
261                         Trace::InstRecord *traceData) const
262    {
263        panic("eaComp not defined!");
264    }
265
266    virtual Fault initiateAcc(ExecContext *xc,
267                              Trace::InstRecord *traceData) const
268    {
269        panic("initiateAcc not defined!");
270    }
271
272    virtual Fault completeAcc(Packet *pkt, ExecContext *xc,
273                              Trace::InstRecord *traceData) const
274    {
275        panic("completeAcc not defined!");
276    }
277
278    virtual void advancePC(TheISA::PCState &pcState) const = 0;
279
280    /**
281     * Return the microop that goes with a particular micropc. This should
282     * only be defined/used in macroops which will contain microops
283     */
284    virtual StaticInstPtr fetchMicroop(MicroPC upc) const;
285
286    /**
287     * Return the target address for a PC-relative branch.
288     * Invalid if not a PC-relative branch (i.e. isDirectCtrl()
289     * should be true).
290     */
291    virtual TheISA::PCState branchTarget(const TheISA::PCState &pc) const;
292
293    /**
294     * Return the target address for an indirect branch (jump).  The
295     * register value is read from the supplied thread context, so
296     * the result is valid only if the thread context is about to
297     * execute the branch in question.  Invalid if not an indirect
298     * branch (i.e. isIndirectCtrl() should be true).
299     */
300    virtual TheISA::PCState branchTarget(ThreadContext *tc) const;
301
302    /**
303     * Return true if the instruction is a control transfer, and if so,
304     * return the target address as well.
305     */
306    bool hasBranchTarget(const TheISA::PCState &pc, ThreadContext *tc,
307                         TheISA::PCState &tgt) const;
308
309    /**
310     * Return string representation of disassembled instruction.
311     * The default version of this function will call the internal
312     * virtual generateDisassembly() function to get the string,
313     * then cache it in #cachedDisassembly.  If the disassembly
314     * should not be cached, this function should be overridden directly.
315     */
316    virtual const std::string &disassemble(Addr pc,
317        const SymbolTable *symtab = 0) const;
318
319    /**
320     * Print a separator separated list of this instruction's set flag
321     * names on the given stream.
322     */
323    void printFlags(std::ostream &outs, const std::string &separator) const;
324
325    /// Return name of machine instruction
326    std::string getName() { return mnemonic; }
327};
328
329#endif // __CPU_STATIC_INST_HH__
330