base_dyn_inst.hh revision 8850
12686Sksewell@umich.edu/*
22100SN/A * Copyright (c) 2011 ARM Limited
35254Sksewell@umich.edu * All rights reserved.
45254Sksewell@umich.edu *
55254Sksewell@umich.edu * The license below extends only to copyright in the software and shall
65254Sksewell@umich.edu * not be construed as granting a license to any other intellectual
75254Sksewell@umich.edu * property including but not limited to intellectual property relating
85254Sksewell@umich.edu * to a hardware implementation of the functionality of the software
95254Sksewell@umich.edu * licensed hereunder.  You may use the software subject to the license
105254Sksewell@umich.edu * terms below provided that you ensure that this notice is replicated
115254Sksewell@umich.edu * unmodified and in its entirety in all distributions of the software,
125254Sksewell@umich.edu * modified or unmodified, in source code or in binary form.
135254Sksewell@umich.edu *
145254Sksewell@umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan
155254Sksewell@umich.edu * Copyright (c) 2009 The University of Edinburgh
165254Sksewell@umich.edu * All rights reserved.
175254Sksewell@umich.edu *
185254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
195254Sksewell@umich.edu * modification, are permitted provided that the following conditions are
205254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
215254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
225254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
235254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
245254Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
255254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
265254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
275254Sksewell@umich.edu * this software without specific prior written permission.
285254Sksewell@umich.edu *
295254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
305254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
315254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322706Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332022SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342022SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352043SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362024SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372024SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382043SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392686Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
404661Sksewell@umich.edu *
412022SN/A * Authors: Kevin Lim
422083SN/A *          Timothy M. Jones
432686Sksewell@umich.edu */
442101SN/A
452043SN/A#ifndef __CPU_BASE_DYN_INST_HH__
462043SN/A#define __CPU_BASE_DYN_INST_HH__
472101SN/A
482101SN/A#include <bitset>
496384Sgblack@eecs.umich.edu#include <list>
506384Sgblack@eecs.umich.edu#include <string>
516384Sgblack@eecs.umich.edu#include <queue>
526384Sgblack@eecs.umich.edu
536384Sgblack@eecs.umich.edu#include "arch/utility.hh"
546384Sgblack@eecs.umich.edu#include "base/fast_alloc.hh"
552101SN/A#include "base/trace.hh"
562101SN/A#include "config/the_isa.hh"
572101SN/A#include "config/use_checker.hh"
582046SN/A#include "cpu/o3/comm.hh"
592686Sksewell@umich.edu#include "cpu/exetrace.hh"
602686Sksewell@umich.edu#include "cpu/inst_seq.hh"
612686Sksewell@umich.edu#include "cpu/op_class.hh"
622470SN/A#include "cpu/static_inst.hh"
632686Sksewell@umich.edu#include "cpu/translation.hh"
644661Sksewell@umich.edu#include "mem/packet.hh"
655222Sksewell@umich.edu#include "sim/byteswap.hh"
665222Sksewell@umich.edu#include "sim/fault_fwd.hh"
672686Sksewell@umich.edu#include "sim/system.hh"
688588Sgblack@eecs.umich.edu#include "sim/tlb.hh"
692470SN/A
702241SN/A/**
712101SN/A * @file
722495SN/A * Defines a dynamic instruction context.
732495SN/A */
748588Sgblack@eecs.umich.edu
752101SN/Atemplate <class Impl>
766384Sgblack@eecs.umich.educlass BaseDynInst : public FastAlloc, public RefCounted
776384Sgblack@eecs.umich.edu{
786384Sgblack@eecs.umich.edu  public:
798588Sgblack@eecs.umich.edu    // Typedef for the CPU.
806384Sgblack@eecs.umich.edu    typedef typename Impl::CPUType ImplCPU;
812495SN/A    typedef typename ImplCPU::ImplState ImplState;
822101SN/A
832101SN/A    // Logical register index type.
842495SN/A    typedef TheISA::RegIndex RegIndex;
852495SN/A    // Integer register type.
862495SN/A    typedef TheISA::IntReg IntReg;
872495SN/A    // Floating point register type.
882495SN/A    typedef TheISA::FloatReg FloatReg;
892495SN/A
902495SN/A    // The DynInstPtr type.
912495SN/A    typedef typename Impl::DynInstPtr DynInstPtr;
922495SN/A    typedef RefCountingPtr<BaseDynInst<Impl> > BaseDynInstPtr;
932495SN/A
942495SN/A    // The list of instructions iterator type.
952495SN/A    typedef typename std::list<DynInstPtr>::iterator ListIt;
962495SN/A
972101SN/A    enum {
988588Sgblack@eecs.umich.edu        MaxInstSrcRegs = TheISA::MaxInstSrcRegs,        /// Max source regs
992101SN/A        MaxInstDestRegs = TheISA::MaxInstDestRegs,      /// Max dest regs
1002101SN/A    };
1018588Sgblack@eecs.umich.edu
1022101SN/A    /** The StaticInst used by this BaseDynInst. */
1036384Sgblack@eecs.umich.edu    StaticInstPtr staticInst;
1046384Sgblack@eecs.umich.edu    StaticInstPtr macroop;
1056384Sgblack@eecs.umich.edu
1068588Sgblack@eecs.umich.edu    ////////////////////////////////////////////
1078588Sgblack@eecs.umich.edu    //
1086384Sgblack@eecs.umich.edu    // INSTRUCTION EXECUTION
1092101SN/A    //
1102101SN/A    ////////////////////////////////////////////
1112495SN/A    /** InstRecord that tracks this instructions. */
1122495SN/A    Trace::InstRecord *traceData;
1132495SN/A
1142495SN/A    void demapPage(Addr vaddr, uint64_t asn)
1152495SN/A    {
1166384Sgblack@eecs.umich.edu        cpu->demapPage(vaddr, asn);
1176384Sgblack@eecs.umich.edu    }
1186384Sgblack@eecs.umich.edu    void demapInstPage(Addr vaddr, uint64_t asn)
1196384Sgblack@eecs.umich.edu    {
1206384Sgblack@eecs.umich.edu        cpu->demapPage(vaddr, asn);
1212495SN/A    }
1226384Sgblack@eecs.umich.edu    void demapDataPage(Addr vaddr, uint64_t asn)
1232495SN/A    {
1242495SN/A        cpu->demapPage(vaddr, asn);
1252043SN/A    }
1262043SN/A
1272025SN/A    Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
1282043SN/A
1292686Sksewell@umich.edu    Fault writeMem(uint8_t *data, unsigned size,
1302686Sksewell@umich.edu                   Addr addr, unsigned flags, uint64_t *res);
1312123SN/A
1322101SN/A    /** Splits a request in two if it crosses a dcache block. */
1336376Sgblack@eecs.umich.edu    void splitRequest(RequestPtr req, RequestPtr &sreqLow,
1346376Sgblack@eecs.umich.edu                      RequestPtr &sreqHigh);
1356376Sgblack@eecs.umich.edu
1367792Sgblack@eecs.umich.edu    /** Initiate a DTB address translation. */
1376376Sgblack@eecs.umich.edu    void initiateTranslation(RequestPtr req, RequestPtr sreqLow,
1386376Sgblack@eecs.umich.edu                             RequestPtr sreqHigh, uint64_t *res,
1396376Sgblack@eecs.umich.edu                             BaseTLB::Mode mode);
1406376Sgblack@eecs.umich.edu
1416376Sgblack@eecs.umich.edu    /** Finish a DTB address translation. */
1426376Sgblack@eecs.umich.edu    void finishTranslation(WholeTranslationState *state);
1436376Sgblack@eecs.umich.edu
1447792Sgblack@eecs.umich.edu    /** True if the DTB address translation has started. */
1456376Sgblack@eecs.umich.edu    bool translationStarted;
1466376Sgblack@eecs.umich.edu
1476376Sgblack@eecs.umich.edu    /** True if the DTB address translation has completed. */
1486376Sgblack@eecs.umich.edu    bool translationCompleted;
1492101SN/A
1502042SN/A    /** True if this address was found to match a previous load and they issued
1512101SN/A     * out of order. If that happend, then it's only a problem if an incoming
1527720Sgblack@eecs.umich.edu     * snoop invalidate modifies the line, in which case we need to squash.
1537792Sgblack@eecs.umich.edu     * If nothing modified the line the order doesn't matter.
1547792Sgblack@eecs.umich.edu     */
1557720Sgblack@eecs.umich.edu    bool possibleLoadViolation;
1567720Sgblack@eecs.umich.edu
1577792Sgblack@eecs.umich.edu    /** True if the address hit a external snoop while sitting in the LSQ.
1587792Sgblack@eecs.umich.edu     * If this is true and a older instruction sees it, this instruction must
1597720Sgblack@eecs.umich.edu     * reexecute
1602101SN/A     */
1612101SN/A    bool hitExternalSnoop;
1622042SN/A
1632101SN/A    /**
1642686Sksewell@umich.edu     * Returns true if the DTB address translation is being delayed due to a hw
1652686Sksewell@umich.edu     * page table walk.
1668901Sandreas.hansson@arm.com     */
1678564Sgblack@eecs.umich.edu    bool isTranslationDelayed() const
1688564Sgblack@eecs.umich.edu    {
16910474Sandreas.hansson@arm.com        return (translationStarted && !translationCompleted);
1708564Sgblack@eecs.umich.edu    }
1712686Sksewell@umich.edu
17210474Sandreas.hansson@arm.com    /**
1732101SN/A     * Saved memory requests (needed when the DTB address translation is
1742083SN/A     * delayed due to a hw page table walk).
1752043SN/A     */
1762025SN/A    RequestPtr savedReq;
1772043SN/A    RequestPtr savedSreqLow;
1786384Sgblack@eecs.umich.edu    RequestPtr savedSreqHigh;
1796384Sgblack@eecs.umich.edu
1804661Sksewell@umich.edu#if USE_CHECKER
1816384Sgblack@eecs.umich.edu    // Need a copy of main request pointer to verify on writes.
1826384Sgblack@eecs.umich.edu    RequestPtr reqToVerify;
1834661Sksewell@umich.edu#endif //USE_CHECKER
1842083SN/A
1852025SN/A    /** @todo: Consider making this private. */
1862043SN/A  public:
1874661Sksewell@umich.edu    /** The sequence number of the instruction. */
1888588Sgblack@eecs.umich.edu    InstSeqNum seqNum;
1898588Sgblack@eecs.umich.edu
1904661Sksewell@umich.edu    enum Status {
1914661Sksewell@umich.edu        IqEntry,                 /// Instruction is in the IQ
1922686Sksewell@umich.edu        RobEntry,                /// Instruction is in the ROB
1936384Sgblack@eecs.umich.edu        LsqEntry,                /// Instruction is in the LSQ
1948588Sgblack@eecs.umich.edu        Completed,               /// Instruction has completed
1958588Sgblack@eecs.umich.edu        ResultReady,             /// Instruction has its result
1968588Sgblack@eecs.umich.edu        CanIssue,                /// Instruction can issue and execute
1976384Sgblack@eecs.umich.edu        Issued,                  /// Instruction has issued
1985222Sksewell@umich.edu        Executed,                /// Instruction has executed
1995222Sksewell@umich.edu        CanCommit,               /// Instruction can commit
2006384Sgblack@eecs.umich.edu        AtCommit,                /// Instruction has reached commit
2018588Sgblack@eecs.umich.edu        Committed,               /// Instruction has committed
2028588Sgblack@eecs.umich.edu        Squashed,                /// Instruction is squashed
2038588Sgblack@eecs.umich.edu        SquashedInIQ,            /// Instruction is squashed in the IQ
2046384Sgblack@eecs.umich.edu        SquashedInLSQ,           /// Instruction is squashed in the LSQ
2055222Sksewell@umich.edu        SquashedInROB,           /// Instruction is squashed in the ROB
2062101SN/A        RecoverInst,             /// Is a recover instruction
2072084SN/A        BlockingInst,            /// Is a blocking instruction
2082025SN/A        ThreadsyncWait,          /// Is a thread synchronization instruction
2092495SN/A        SerializeBefore,         /// Needs to serialize on
2102495SN/A                                 /// instructions ahead of it
2112495SN/A        SerializeAfter,          /// Needs to serialize instructions behind it
2126384Sgblack@eecs.umich.edu        SerializeHandled,        /// Serialization has been handled
2138564Sgblack@eecs.umich.edu        NumStatus
2148564Sgblack@eecs.umich.edu    };
2158738Sgblack@eecs.umich.edu
2168564Sgblack@eecs.umich.edu    /** The status of this BaseDynInst.  Several bits can be set. */
21710474Sandreas.hansson@arm.com    std::bitset<NumStatus> status;
2186384Sgblack@eecs.umich.edu
2196384Sgblack@eecs.umich.edu    /** The thread this instruction is from. */
2208588Sgblack@eecs.umich.edu    ThreadID threadNumber;
2215222Sksewell@umich.edu
2228564Sgblack@eecs.umich.edu    /** data address space ID, for loads & stores. */
2238564Sgblack@eecs.umich.edu    short asid;
2248738Sgblack@eecs.umich.edu
2258564Sgblack@eecs.umich.edu    /** How many source registers are ready. */
22610474Sandreas.hansson@arm.com    unsigned readyRegs;
2276384Sgblack@eecs.umich.edu
2286384Sgblack@eecs.umich.edu    /** Pointer to the Impl's CPU object. */
2298588Sgblack@eecs.umich.edu    ImplCPU *cpu;
2306384Sgblack@eecs.umich.edu
2316384Sgblack@eecs.umich.edu    /** Pointer to the thread state. */
2326384Sgblack@eecs.umich.edu    ImplState *thread;
2336384Sgblack@eecs.umich.edu
2342495SN/A    /** The kind of fault this instruction has generated. */
2352101SN/A    Fault fault;
2362043SN/A
2372025SN/A    /** Pointer to the data for the memory access. */
2382495SN/A    uint8_t *memData;
2392495SN/A
2402495SN/A    /** The effective virtual address (lds & stores only). */
2418588Sgblack@eecs.umich.edu    Addr effAddr;
2428588Sgblack@eecs.umich.edu
2432495SN/A    /** The size of the request */
2442101SN/A    Addr effSize;
2452084SN/A
2462024SN/A    /** Is the effective virtual address valid. */
2472043SN/A    bool effAddrValid;
2482239SN/A
2498588Sgblack@eecs.umich.edu    /** The effective physical address. */
2508588Sgblack@eecs.umich.edu    Addr physEffAddr;
2518588Sgblack@eecs.umich.edu
2528588Sgblack@eecs.umich.edu    /** The memory request flags (from translation). */
2538588Sgblack@eecs.umich.edu    unsigned memReqFlags;
2548588Sgblack@eecs.umich.edu
2552101SN/A    union Result {
2562043SN/A        uint64_t integer;
2572043SN/A        double dbl;
2582025SN/A        void set(uint64_t i) { integer = i; }
2592043SN/A        void set(double d) { dbl = d; }
2602043SN/A        void get(uint64_t& i) { i = integer; }
2612101SN/A        void get(double& d) { d = dbl; }
2628588Sgblack@eecs.umich.edu    };
2638588Sgblack@eecs.umich.edu
2648588Sgblack@eecs.umich.edu    /** The result of the instruction; assumes an instruction can have many
2658588Sgblack@eecs.umich.edu     *  destination registers.
2662101SN/A     */
2672043SN/A    std::queue<Result> instResult;
2682025SN/A
2692043SN/A    /** Records changes to result? */
2705222Sksewell@umich.edu    bool recordResult;
2718588Sgblack@eecs.umich.edu
2726384Sgblack@eecs.umich.edu    /** Did this instruction execute, or is it predicated false */
2738588Sgblack@eecs.umich.edu    bool predicate;
2746384Sgblack@eecs.umich.edu
2758588Sgblack@eecs.umich.edu  protected:
2766384Sgblack@eecs.umich.edu    /** PC state for this instruction. */
2778588Sgblack@eecs.umich.edu    TheISA::PCState pc;
2786384Sgblack@eecs.umich.edu
2798588Sgblack@eecs.umich.edu    /** Predicted PC state after this instruction. */
2808588Sgblack@eecs.umich.edu    TheISA::PCState predPC;
2812101SN/A
2822043SN/A    /** If this is a branch that was predicted taken */
2832043SN/A    bool predTaken;
2842043SN/A
2852101SN/A  public:
2868588Sgblack@eecs.umich.edu
2872686Sksewell@umich.edu#ifdef DEBUG
2882686Sksewell@umich.edu    void dumpSNList();
2898588Sgblack@eecs.umich.edu#endif
2902686Sksewell@umich.edu
2918588Sgblack@eecs.umich.edu    /** Whether or not the source register is ready.
2928588Sgblack@eecs.umich.edu     *  @todo: Not sure this should be here vs the derived class.
2932101SN/A     */
2942043SN/A    bool _readySrcRegIdx[MaxInstSrcRegs];
2952043SN/A
2962043SN/A  protected:
2976384Sgblack@eecs.umich.edu    /** Flattened register index of the destination registers of this
2986384Sgblack@eecs.umich.edu     *  instruction.
2994661Sksewell@umich.edu     */
3002101SN/A    TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs];
3012101SN/A
3022101SN/A    /** Flattened register index of the source registers of this
3032043SN/A     *  instruction.
3042043SN/A     */
3052043SN/A    TheISA::RegIndex _flatSrcRegIdx[TheISA::MaxInstSrcRegs];
3062123SN/A
3077792Sgblack@eecs.umich.edu    /** Physical register index of the destination registers of this
3087792Sgblack@eecs.umich.edu     *  instruction.
3097792Sgblack@eecs.umich.edu     */
3102043SN/A    PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs];
3112043SN/A
3122100SN/A    /** Physical register index of the source registers of this
3132686Sksewell@umich.edu     *  instruction.
3142686Sksewell@umich.edu     */
3158588Sgblack@eecs.umich.edu    PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs];
3162686Sksewell@umich.edu
3178588Sgblack@eecs.umich.edu    /** Physical register index of the previous producers of the
3188588Sgblack@eecs.umich.edu     *  architected destinations.
3198588Sgblack@eecs.umich.edu     */
3202043SN/A    PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs];
3212084SN/A
3222024SN/A  public:
3232101SN/A
3242686Sksewell@umich.edu    /** Returns the physical register index of the i'th destination
3255222Sksewell@umich.edu     *  register.
3268564Sgblack@eecs.umich.edu     */
3278564Sgblack@eecs.umich.edu    PhysRegIndex renamedDestRegIdx(int idx) const
3288738Sgblack@eecs.umich.edu    {
3298564Sgblack@eecs.umich.edu        return _destRegIdx[idx];
33010474Sandreas.hansson@arm.com    }
3316384Sgblack@eecs.umich.edu
3326384Sgblack@eecs.umich.edu    /** Returns the physical register index of the i'th source register. */
3338588Sgblack@eecs.umich.edu    PhysRegIndex renamedSrcRegIdx(int idx) const
3348588Sgblack@eecs.umich.edu    {
3358588Sgblack@eecs.umich.edu        return _srcRegIdx[idx];
3368588Sgblack@eecs.umich.edu    }
3378588Sgblack@eecs.umich.edu
3388588Sgblack@eecs.umich.edu    /** Returns the flattened register index of the i'th destination
3392495SN/A     *  register.
3402495SN/A     */
3416384Sgblack@eecs.umich.edu    TheISA::RegIndex flattenedDestRegIdx(int idx) const
3422495SN/A    {
3432084SN/A        return _flatDestRegIdx[idx];
3442084SN/A    }
3452024SN/A
3462101SN/A    /** Returns the flattened register index of the i'th source register */
3472101SN/A    TheISA::RegIndex flattenedSrcRegIdx(int idx) const
3482101SN/A    {
3492101SN/A        return _flatSrcRegIdx[idx];
3506384Sgblack@eecs.umich.edu    }
3516384Sgblack@eecs.umich.edu
3526384Sgblack@eecs.umich.edu    /** Returns the physical register index of the previous physical register
3536384Sgblack@eecs.umich.edu     *  that remapped to the same logical register index.
3546384Sgblack@eecs.umich.edu     */
3556384Sgblack@eecs.umich.edu    PhysRegIndex prevDestRegIdx(int idx) const
3566384Sgblack@eecs.umich.edu    {
3576384Sgblack@eecs.umich.edu        return _prevDestRegIdx[idx];
3586384Sgblack@eecs.umich.edu    }
3596384Sgblack@eecs.umich.edu
3606384Sgblack@eecs.umich.edu    /** Renames a destination register to a physical register.  Also records
3616384Sgblack@eecs.umich.edu     *  the previous physical register that the logical register mapped to.
3626384Sgblack@eecs.umich.edu     */
3636384Sgblack@eecs.umich.edu    void renameDestReg(int idx,
3646384Sgblack@eecs.umich.edu                       PhysRegIndex renamed_dest,
3656384Sgblack@eecs.umich.edu                       PhysRegIndex previous_rename)
3666384Sgblack@eecs.umich.edu    {
3676384Sgblack@eecs.umich.edu        _destRegIdx[idx] = renamed_dest;
3686384Sgblack@eecs.umich.edu        _prevDestRegIdx[idx] = previous_rename;
3696384Sgblack@eecs.umich.edu    }
3706384Sgblack@eecs.umich.edu
3716384Sgblack@eecs.umich.edu    /** Renames a source logical register to the physical register which
3726384Sgblack@eecs.umich.edu     *  has/will produce that logical register's result.
3736384Sgblack@eecs.umich.edu     *  @todo: add in whether or not the source register is ready.
3746384Sgblack@eecs.umich.edu     */
3756384Sgblack@eecs.umich.edu    void renameSrcReg(int idx, PhysRegIndex renamed_src)
3766384Sgblack@eecs.umich.edu    {
3776384Sgblack@eecs.umich.edu        _srcRegIdx[idx] = renamed_src;
3786384Sgblack@eecs.umich.edu    }
3796384Sgblack@eecs.umich.edu
3806384Sgblack@eecs.umich.edu    /** Flattens a source architectural register index into a logical index.
3816384Sgblack@eecs.umich.edu     */
3826384Sgblack@eecs.umich.edu    void flattenSrcReg(int idx, TheISA::RegIndex flattened_src)
3836384Sgblack@eecs.umich.edu    {
3846384Sgblack@eecs.umich.edu        _flatSrcRegIdx[idx] = flattened_src;
3854661Sksewell@umich.edu    }
3866376Sgblack@eecs.umich.edu
3876376Sgblack@eecs.umich.edu    /** Flattens a destination architectural register index into a logical
3889918Ssteve.reinhardt@amd.com     * index.
3896376Sgblack@eecs.umich.edu     */
3904661Sksewell@umich.edu    void flattenDestReg(int idx, TheISA::RegIndex flattened_dest)
3916384Sgblack@eecs.umich.edu    {
3926384Sgblack@eecs.umich.edu        _flatDestRegIdx[idx] = flattened_dest;
3936384Sgblack@eecs.umich.edu    }
3944661Sksewell@umich.edu    /** BaseDynInst constructor given a binary instruction.
3956383Sgblack@eecs.umich.edu     *  @param staticInst A StaticInstPtr to the underlying instruction.
3966383Sgblack@eecs.umich.edu     *  @param pc The PC state for the instruction.
3976383Sgblack@eecs.umich.edu     *  @param predPC The predicted next PC state for the instruction.
3986383Sgblack@eecs.umich.edu     *  @param seq_num The sequence number of the instruction.
3996383Sgblack@eecs.umich.edu     *  @param cpu Pointer to the instruction's CPU.
4006383Sgblack@eecs.umich.edu     */
4016383Sgblack@eecs.umich.edu    BaseDynInst(StaticInstPtr staticInst, StaticInstPtr macroop,
4026383Sgblack@eecs.umich.edu                TheISA::PCState pc, TheISA::PCState predPC,
4036383Sgblack@eecs.umich.edu                InstSeqNum seq_num, ImplCPU *cpu);
4046383Sgblack@eecs.umich.edu
4056383Sgblack@eecs.umich.edu    /** BaseDynInst constructor given a StaticInst pointer.
4066383Sgblack@eecs.umich.edu     *  @param _staticInst The StaticInst for this BaseDynInst.
4076383Sgblack@eecs.umich.edu     */
4086384Sgblack@eecs.umich.edu    BaseDynInst(StaticInstPtr staticInst, StaticInstPtr macroop);
4092686Sksewell@umich.edu
4104661Sksewell@umich.edu    /** BaseDynInst destructor. */
4114661Sksewell@umich.edu    ~BaseDynInst();
4129918Ssteve.reinhardt@amd.com
4136384Sgblack@eecs.umich.edu  private:
4144661Sksewell@umich.edu    /** Function to initialize variables in the constructors. */
4159918Ssteve.reinhardt@amd.com    void initVars();
4166384Sgblack@eecs.umich.edu
4176384Sgblack@eecs.umich.edu  public:
4186384Sgblack@eecs.umich.edu    /** Dumps out contents of this BaseDynInst. */
4196384Sgblack@eecs.umich.edu    void dump();
4209918Ssteve.reinhardt@amd.com
4216384Sgblack@eecs.umich.edu    /** Dumps out contents of this BaseDynInst into given string. */
4226384Sgblack@eecs.umich.edu    void dump(std::string &outstring);
4236384Sgblack@eecs.umich.edu
4249918Ssteve.reinhardt@amd.com    /** Read this CPU's ID. */
4256384Sgblack@eecs.umich.edu    int cpuId() { return cpu->cpuId(); }
4266384Sgblack@eecs.umich.edu
4276384Sgblack@eecs.umich.edu    /** Read this CPU's data requestor ID */
4286384Sgblack@eecs.umich.edu    MasterID masterId() { return cpu->dataMasterId(); }
4296384Sgblack@eecs.umich.edu
4306384Sgblack@eecs.umich.edu    /** Read this context's system-wide ID **/
4316384Sgblack@eecs.umich.edu    int contextId() { return thread->contextId(); }
4326384Sgblack@eecs.umich.edu
4336384Sgblack@eecs.umich.edu    /** Returns the fault type. */
4346384Sgblack@eecs.umich.edu    Fault getFault() { return fault; }
4356384Sgblack@eecs.umich.edu
4366384Sgblack@eecs.umich.edu    /** Checks whether or not this instruction has had its branch target
4376384Sgblack@eecs.umich.edu     *  calculated yet.  For now it is not utilized and is hacked to be
4386384Sgblack@eecs.umich.edu     *  always false.
4396384Sgblack@eecs.umich.edu     *  @todo: Actually use this instruction.
4406384Sgblack@eecs.umich.edu     */
4416384Sgblack@eecs.umich.edu    bool doneTargCalc() { return false; }
4426384Sgblack@eecs.umich.edu
4436384Sgblack@eecs.umich.edu    /** Set the predicted target of this current instruction. */
4446384Sgblack@eecs.umich.edu    void setPredTarg(const TheISA::PCState &_predPC)
4456384Sgblack@eecs.umich.edu    {
4462101SN/A        predPC = _predPC;
4476384Sgblack@eecs.umich.edu    }
4482686Sksewell@umich.edu
4492027SN/A    const TheISA::PCState &readPredTarg() { return predPC; }
4506384Sgblack@eecs.umich.edu
4516384Sgblack@eecs.umich.edu    /** Returns the predicted PC immediately after the branch. */
4524661Sksewell@umich.edu    Addr predInstAddr() { return predPC.instAddr(); }
4539918Ssteve.reinhardt@amd.com
4544661Sksewell@umich.edu    /** Returns the predicted PC two instructions after the branch */
4554661Sksewell@umich.edu    Addr predNextInstAddr() { return predPC.nextInstAddr(); }
4564661Sksewell@umich.edu
4574661Sksewell@umich.edu    /** Returns the predicted micro PC after the branch */
4584661Sksewell@umich.edu    Addr predMicroPC() { return predPC.microPC(); }
4596383Sgblack@eecs.umich.edu
4604661Sksewell@umich.edu    /** Returns whether the instruction was predicted taken or not. */
4616383Sgblack@eecs.umich.edu    bool readPredTaken()
4624661Sksewell@umich.edu    {
4634661Sksewell@umich.edu        return predTaken;
4646383Sgblack@eecs.umich.edu    }
4654661Sksewell@umich.edu
4664661Sksewell@umich.edu    void setPredTaken(bool predicted_taken)
4676383Sgblack@eecs.umich.edu    {
4684661Sksewell@umich.edu        predTaken = predicted_taken;
4694661Sksewell@umich.edu    }
4706383Sgblack@eecs.umich.edu
4714661Sksewell@umich.edu    /** Returns whether the instruction mispredicted. */
4724661Sksewell@umich.edu    bool mispredicted()
4736383Sgblack@eecs.umich.edu    {
4744661Sksewell@umich.edu        TheISA::PCState tempPC = pc;
4754661Sksewell@umich.edu        TheISA::advancePC(tempPC, staticInst);
4766383Sgblack@eecs.umich.edu        return !(tempPC == predPC);
4774661Sksewell@umich.edu    }
4784661Sksewell@umich.edu
4796383Sgblack@eecs.umich.edu    //
4804661Sksewell@umich.edu    //  Instruction types.  Forward checks to StaticInst object.
4814661Sksewell@umich.edu    //
4826383Sgblack@eecs.umich.edu    bool isNop()          const { return staticInst->isNop(); }
4834661Sksewell@umich.edu    bool isMemRef()       const { return staticInst->isMemRef(); }
4844661Sksewell@umich.edu    bool isLoad()         const { return staticInst->isLoad(); }
4856383Sgblack@eecs.umich.edu    bool isStore()        const { return staticInst->isStore(); }
4864661Sksewell@umich.edu    bool isStoreConditional() const
4874661Sksewell@umich.edu    { return staticInst->isStoreConditional(); }
4886383Sgblack@eecs.umich.edu    bool isInstPrefetch() const { return staticInst->isInstPrefetch(); }
4894661Sksewell@umich.edu    bool isDataPrefetch() const { return staticInst->isDataPrefetch(); }
4904661Sksewell@umich.edu    bool isInteger()      const { return staticInst->isInteger(); }
4916383Sgblack@eecs.umich.edu    bool isFloating()     const { return staticInst->isFloating(); }
4924661Sksewell@umich.edu    bool isControl()      const { return staticInst->isControl(); }
4936383Sgblack@eecs.umich.edu    bool isCall()         const { return staticInst->isCall(); }
4946384Sgblack@eecs.umich.edu    bool isReturn()       const { return staticInst->isReturn(); }
4955222Sksewell@umich.edu    bool isDirectCtrl()   const { return staticInst->isDirectCtrl(); }
4964661Sksewell@umich.edu    bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); }
4976384Sgblack@eecs.umich.edu    bool isCondCtrl()     const { return staticInst->isCondCtrl(); }
4986384Sgblack@eecs.umich.edu    bool isUncondCtrl()   const { return staticInst->isUncondCtrl(); }
4999918Ssteve.reinhardt@amd.com    bool isCondDelaySlot() const { return staticInst->isCondDelaySlot(); }
5008607Sgblack@eecs.umich.edu    bool isThreadSync()   const { return staticInst->isThreadSync(); }
5018607Sgblack@eecs.umich.edu    bool isSerializing()  const { return staticInst->isSerializing(); }
5029918Ssteve.reinhardt@amd.com    bool isSerializeBefore() const
5036384Sgblack@eecs.umich.edu    { return staticInst->isSerializeBefore() || status[SerializeBefore]; }
5046384Sgblack@eecs.umich.edu    bool isSerializeAfter() const
5056384Sgblack@eecs.umich.edu    { return staticInst->isSerializeAfter() || status[SerializeAfter]; }
5066384Sgblack@eecs.umich.edu    bool isSquashAfter() const { return staticInst->isSquashAfter(); }
5076384Sgblack@eecs.umich.edu    bool isMemBarrier()   const { return staticInst->isMemBarrier(); }
5086384Sgblack@eecs.umich.edu    bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
5098588Sgblack@eecs.umich.edu    bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
5106384Sgblack@eecs.umich.edu    bool isQuiesce() const { return staticInst->isQuiesce(); }
5116384Sgblack@eecs.umich.edu    bool isIprAccess() const { return staticInst->isIprAccess(); }
5126384Sgblack@eecs.umich.edu    bool isUnverifiable() const { return staticInst->isUnverifiable(); }
5136384Sgblack@eecs.umich.edu    bool isSyscall() const { return staticInst->isSyscall(); }
5146384Sgblack@eecs.umich.edu    bool isMacroop() const { return staticInst->isMacroop(); }
5158588Sgblack@eecs.umich.edu    bool isMicroop() const { return staticInst->isMicroop(); }
5166384Sgblack@eecs.umich.edu    bool isDelayedCommit() const { return staticInst->isDelayedCommit(); }
5178588Sgblack@eecs.umich.edu    bool isLastMicroop() const { return staticInst->isLastMicroop(); }
5186384Sgblack@eecs.umich.edu    bool isFirstMicroop() const { return staticInst->isFirstMicroop(); }
5196384Sgblack@eecs.umich.edu    bool isMicroBranch() const { return staticInst->isMicroBranch(); }
5206384Sgblack@eecs.umich.edu
5216384Sgblack@eecs.umich.edu    /** Temporarily sets this instruction as a serialize before instruction. */
5228588Sgblack@eecs.umich.edu    void setSerializeBefore() { status.set(SerializeBefore); }
5236384Sgblack@eecs.umich.edu
5248588Sgblack@eecs.umich.edu    /** Clears the serializeBefore part of this instruction. */
5256384Sgblack@eecs.umich.edu    void clearSerializeBefore() { status.reset(SerializeBefore); }
5268588Sgblack@eecs.umich.edu
5276384Sgblack@eecs.umich.edu    /** Checks if this serializeBefore is only temporarily set. */
5286384Sgblack@eecs.umich.edu    bool isTempSerializeBefore() { return status[SerializeBefore]; }
5298588Sgblack@eecs.umich.edu
5306384Sgblack@eecs.umich.edu    /** Temporarily sets this instruction as a serialize after instruction. */
5316384Sgblack@eecs.umich.edu    void setSerializeAfter() { status.set(SerializeAfter); }
5326384Sgblack@eecs.umich.edu
5336384Sgblack@eecs.umich.edu    /** Clears the serializeAfter part of this instruction.*/
5346384Sgblack@eecs.umich.edu    void clearSerializeAfter() { status.reset(SerializeAfter); }
5358607Sgblack@eecs.umich.edu
5366384Sgblack@eecs.umich.edu    /** Checks if this serializeAfter is only temporarily set. */
5379918Ssteve.reinhardt@amd.com    bool isTempSerializeAfter() { return status[SerializeAfter]; }
5386384Sgblack@eecs.umich.edu
5396384Sgblack@eecs.umich.edu    /** Sets the serialization part of this instruction as handled. */
5404661Sksewell@umich.edu    void setSerializeHandled() { status.set(SerializeHandled); }
5414661Sksewell@umich.edu
5422101SN/A    /** Checks if the serialization part of this instruction has been
5434661Sksewell@umich.edu     *  handled.  This does not apply to the temporary serializing
5444661Sksewell@umich.edu     *  state; it only applies to this instruction's own permanent
5454661Sksewell@umich.edu     *  serializing state.
5464661Sksewell@umich.edu     */
5474661Sksewell@umich.edu    bool isSerializeHandled() { return status[SerializeHandled]; }
5486376Sgblack@eecs.umich.edu
5496376Sgblack@eecs.umich.edu    /** Returns the opclass of this instruction. */
5506376Sgblack@eecs.umich.edu    OpClass opClass() const { return staticInst->opClass(); }
5516376Sgblack@eecs.umich.edu
5526376Sgblack@eecs.umich.edu    /** Returns the branch target address. */
5536376Sgblack@eecs.umich.edu    TheISA::PCState branchTarget() const
5546376Sgblack@eecs.umich.edu    { return staticInst->branchTarget(pc); }
5556376Sgblack@eecs.umich.edu
5566376Sgblack@eecs.umich.edu    /** Returns the number of source registers. */
5576376Sgblack@eecs.umich.edu    int8_t numSrcRegs() const { return staticInst->numSrcRegs(); }
5586376Sgblack@eecs.umich.edu
5596376Sgblack@eecs.umich.edu    /** Returns the number of destination registers. */
5606376Sgblack@eecs.umich.edu    int8_t numDestRegs() const { return staticInst->numDestRegs(); }
5616376Sgblack@eecs.umich.edu
5626376Sgblack@eecs.umich.edu    // the following are used to track physical register usage
5636376Sgblack@eecs.umich.edu    // for machines with separate int & FP reg files
5645222Sksewell@umich.edu    int8_t numFPDestRegs()  const { return staticInst->numFPDestRegs(); }
5654661Sksewell@umich.edu    int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); }
5666384Sgblack@eecs.umich.edu
5674661Sksewell@umich.edu    /** Returns the logical register index of the i'th destination register. */
5686384Sgblack@eecs.umich.edu    RegIndex destRegIdx(int i) const { return staticInst->destRegIdx(i); }
5696384Sgblack@eecs.umich.edu
5704661Sksewell@umich.edu    /** Returns the logical register index of the i'th source register. */
5714661Sksewell@umich.edu    RegIndex srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
5724661Sksewell@umich.edu
5736376Sgblack@eecs.umich.edu    /** Pops a result off the instResult queue */
5746376Sgblack@eecs.umich.edu    template <class T>
5756376Sgblack@eecs.umich.edu    void popResult(T& t)
5766376Sgblack@eecs.umich.edu    {
5776376Sgblack@eecs.umich.edu        if (!instResult.empty()) {
5786376Sgblack@eecs.umich.edu            instResult.front().get(t);
5796376Sgblack@eecs.umich.edu            instResult.pop();
5806376Sgblack@eecs.umich.edu        }
5816376Sgblack@eecs.umich.edu    }
5826376Sgblack@eecs.umich.edu
5836376Sgblack@eecs.umich.edu    /** Read the most recent result stored by this instruction */
5846376Sgblack@eecs.umich.edu    template <class T>
5855222Sksewell@umich.edu    void readResult(T& t)
5864661Sksewell@umich.edu    {
5876384Sgblack@eecs.umich.edu        instResult.back().get(t);
5884661Sksewell@umich.edu    }
5895222Sksewell@umich.edu
5904661Sksewell@umich.edu    /** Pushes a result onto the instResult queue */
5914661Sksewell@umich.edu    template <class T>
5924661Sksewell@umich.edu    void setResult(T t)
5936384Sgblack@eecs.umich.edu    {
5946384Sgblack@eecs.umich.edu        if (recordResult) {
5956384Sgblack@eecs.umich.edu            Result instRes;
5966384Sgblack@eecs.umich.edu            instRes.set(t);
5976384Sgblack@eecs.umich.edu            instResult.push(instRes);
5986384Sgblack@eecs.umich.edu        }
5996384Sgblack@eecs.umich.edu    }
6006384Sgblack@eecs.umich.edu
6016384Sgblack@eecs.umich.edu    /** Records an integer register being set to a value. */
6026384Sgblack@eecs.umich.edu    void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
6036384Sgblack@eecs.umich.edu    {
60410474Sandreas.hansson@arm.com        setResult<uint64_t>(val);
6056384Sgblack@eecs.umich.edu    }
6066384Sgblack@eecs.umich.edu
6076384Sgblack@eecs.umich.edu    /** Records an fp register being set to a value. */
6086384Sgblack@eecs.umich.edu    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
6096384Sgblack@eecs.umich.edu                            int width)
6106384Sgblack@eecs.umich.edu    {
6116384Sgblack@eecs.umich.edu        if (width == 32 || width == 64) {
6126384Sgblack@eecs.umich.edu            setResult<double>(val);
6136384Sgblack@eecs.umich.edu        } else {
6146384Sgblack@eecs.umich.edu            panic("Unsupported width!");
61510474Sandreas.hansson@arm.com        }
6166384Sgblack@eecs.umich.edu    }
6176384Sgblack@eecs.umich.edu
6186384Sgblack@eecs.umich.edu    /** Records an fp register being set to a value. */
6196384Sgblack@eecs.umich.edu    void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
6204661Sksewell@umich.edu    {
6216384Sgblack@eecs.umich.edu        setResult<double>(val);
6224661Sksewell@umich.edu    }
6234661Sksewell@umich.edu
6244661Sksewell@umich.edu    /** Records an fp register being set to an integer value. */
6256376Sgblack@eecs.umich.edu    void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val,
6266376Sgblack@eecs.umich.edu                                int width)
6276376Sgblack@eecs.umich.edu    {
6286376Sgblack@eecs.umich.edu        setResult<uint64_t>(val);
6296376Sgblack@eecs.umich.edu    }
63010474Sandreas.hansson@arm.com
6314661Sksewell@umich.edu    /** Records an fp register being set to an integer value. */
6326376Sgblack@eecs.umich.edu    void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val)
6334661Sksewell@umich.edu    {
6346376Sgblack@eecs.umich.edu        setResult<uint64_t>(val);
6356376Sgblack@eecs.umich.edu    }
6366376Sgblack@eecs.umich.edu
6376376Sgblack@eecs.umich.edu    /** Records that one of the source registers is ready. */
6386376Sgblack@eecs.umich.edu    void markSrcRegReady();
63910474Sandreas.hansson@arm.com
6404661Sksewell@umich.edu    /** Marks a specific register as ready. */
6416376Sgblack@eecs.umich.edu    void markSrcRegReady(RegIndex src_idx);
6424661Sksewell@umich.edu
6436384Sgblack@eecs.umich.edu    /** Returns if a source register is ready. */
6442101SN/A    bool isReadySrcRegIdx(int idx) const
6452101SN/A    {
6462101SN/A        return this->_readySrcRegIdx[idx];
6476384Sgblack@eecs.umich.edu    }
6486384Sgblack@eecs.umich.edu
6496384Sgblack@eecs.umich.edu    /** Sets this instruction as completed. */
6506384Sgblack@eecs.umich.edu    void setCompleted() { status.set(Completed); }
6516384Sgblack@eecs.umich.edu
6526384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is completed. */
6536384Sgblack@eecs.umich.edu    bool isCompleted() const { return status[Completed]; }
6546384Sgblack@eecs.umich.edu
6557792Sgblack@eecs.umich.edu    /** Marks the result as ready. */
6566384Sgblack@eecs.umich.edu    void setResultReady() { status.set(ResultReady); }
6577792Sgblack@eecs.umich.edu
6586384Sgblack@eecs.umich.edu    /** Returns whether or not the result is ready. */
6597792Sgblack@eecs.umich.edu    bool isResultReady() const { return status[ResultReady]; }
6606384Sgblack@eecs.umich.edu
6617792Sgblack@eecs.umich.edu    /** Sets this instruction as ready to issue. */
6626384Sgblack@eecs.umich.edu    void setCanIssue() { status.set(CanIssue); }
6636384Sgblack@eecs.umich.edu
6646384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is ready to issue. */
6656384Sgblack@eecs.umich.edu    bool readyToIssue() const { return status[CanIssue]; }
6666384Sgblack@eecs.umich.edu
6676384Sgblack@eecs.umich.edu    /** Clears this instruction being able to issue. */
6686384Sgblack@eecs.umich.edu    void clearCanIssue() { status.reset(CanIssue); }
6696376Sgblack@eecs.umich.edu
6706384Sgblack@eecs.umich.edu    /** Sets this instruction as issued from the IQ. */
6716384Sgblack@eecs.umich.edu    void setIssued() { status.set(Issued); }
6726384Sgblack@eecs.umich.edu
6736384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction has issued. */
6745222Sksewell@umich.edu    bool isIssued() const { return status[Issued]; }
6756384Sgblack@eecs.umich.edu
6766384Sgblack@eecs.umich.edu    /** Clears this instruction as being issued. */
6776384Sgblack@eecs.umich.edu    void clearIssued() { status.reset(Issued); }
6786384Sgblack@eecs.umich.edu
6796384Sgblack@eecs.umich.edu    /** Sets this instruction as executed. */
6807792Sgblack@eecs.umich.edu    void setExecuted() { status.set(Executed); }
6816384Sgblack@eecs.umich.edu
6827792Sgblack@eecs.umich.edu    /** Returns whether or not this instruction has executed. */
6836384Sgblack@eecs.umich.edu    bool isExecuted() const { return status[Executed]; }
6846384Sgblack@eecs.umich.edu
6856384Sgblack@eecs.umich.edu    /** Sets this instruction as ready to commit. */
6866384Sgblack@eecs.umich.edu    void setCanCommit() { status.set(CanCommit); }
6876384Sgblack@eecs.umich.edu
6886384Sgblack@eecs.umich.edu    /** Clears this instruction as being ready to commit. */
6896384Sgblack@eecs.umich.edu    void clearCanCommit() { status.reset(CanCommit); }
6906384Sgblack@eecs.umich.edu
6916384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is ready to commit. */
6926384Sgblack@eecs.umich.edu    bool readyToCommit() const { return status[CanCommit]; }
6936384Sgblack@eecs.umich.edu
6946384Sgblack@eecs.umich.edu    void setAtCommit() { status.set(AtCommit); }
6956384Sgblack@eecs.umich.edu
6966384Sgblack@eecs.umich.edu    bool isAtCommit() { return status[AtCommit]; }
6976384Sgblack@eecs.umich.edu
6986384Sgblack@eecs.umich.edu    /** Sets this instruction as committed. */
6996384Sgblack@eecs.umich.edu    void setCommitted() { status.set(Committed); }
7006384Sgblack@eecs.umich.edu
7016384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is committed. */
7026384Sgblack@eecs.umich.edu    bool isCommitted() const { return status[Committed]; }
7036384Sgblack@eecs.umich.edu
7046384Sgblack@eecs.umich.edu    /** Sets this instruction as squashed. */
7056384Sgblack@eecs.umich.edu    void setSquashed() { status.set(Squashed); }
7066384Sgblack@eecs.umich.edu
7076384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is squashed. */
7086384Sgblack@eecs.umich.edu    bool isSquashed() const { return status[Squashed]; }
7096384Sgblack@eecs.umich.edu
7106384Sgblack@eecs.umich.edu    //Instruction Queue Entry
7116384Sgblack@eecs.umich.edu    //-----------------------
7126384Sgblack@eecs.umich.edu    /** Sets this instruction as a entry the IQ. */
7136384Sgblack@eecs.umich.edu    void setInIQ() { status.set(IqEntry); }
7146384Sgblack@eecs.umich.edu
7156384Sgblack@eecs.umich.edu    /** Sets this instruction as a entry the IQ. */
7165222Sksewell@umich.edu    void clearInIQ() { status.reset(IqEntry); }
7176384Sgblack@eecs.umich.edu
7186384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction has issued. */
7196384Sgblack@eecs.umich.edu    bool isInIQ() const { return status[IqEntry]; }
7206384Sgblack@eecs.umich.edu
7216384Sgblack@eecs.umich.edu    /** Sets this instruction as squashed in the IQ. */
7226384Sgblack@eecs.umich.edu    void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);}
7236384Sgblack@eecs.umich.edu
7246384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is squashed in the IQ. */
7256384Sgblack@eecs.umich.edu    bool isSquashedInIQ() const { return status[SquashedInIQ]; }
7266384Sgblack@eecs.umich.edu
7276384Sgblack@eecs.umich.edu
7286384Sgblack@eecs.umich.edu    //Load / Store Queue Functions
7296384Sgblack@eecs.umich.edu    //-----------------------
7306384Sgblack@eecs.umich.edu    /** Sets this instruction as a entry the LSQ. */
7316384Sgblack@eecs.umich.edu    void setInLSQ() { status.set(LsqEntry); }
7325222Sksewell@umich.edu
7336384Sgblack@eecs.umich.edu    /** Sets this instruction as a entry the LSQ. */
7346384Sgblack@eecs.umich.edu    void removeInLSQ() { status.reset(LsqEntry); }
7356384Sgblack@eecs.umich.edu
7366384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is in the LSQ. */
7376384Sgblack@eecs.umich.edu    bool isInLSQ() const { return status[LsqEntry]; }
7386384Sgblack@eecs.umich.edu
7396384Sgblack@eecs.umich.edu    /** Sets this instruction as squashed in the LSQ. */
7406384Sgblack@eecs.umich.edu    void setSquashedInLSQ() { status.set(SquashedInLSQ);}
7416384Sgblack@eecs.umich.edu
7426384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is squashed in the LSQ. */
7436384Sgblack@eecs.umich.edu    bool isSquashedInLSQ() const { return status[SquashedInLSQ]; }
7446384Sgblack@eecs.umich.edu
7456384Sgblack@eecs.umich.edu
7466384Sgblack@eecs.umich.edu    //Reorder Buffer Functions
7476384Sgblack@eecs.umich.edu    //-----------------------
7486384Sgblack@eecs.umich.edu    /** Sets this instruction as a entry the ROB. */
7496384Sgblack@eecs.umich.edu    void setInROB() { status.set(RobEntry); }
7506384Sgblack@eecs.umich.edu
7516384Sgblack@eecs.umich.edu    /** Sets this instruction as a entry the ROB. */
7526384Sgblack@eecs.umich.edu    void clearInROB() { status.reset(RobEntry); }
7536384Sgblack@eecs.umich.edu
7546384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is in the ROB. */
7556384Sgblack@eecs.umich.edu    bool isInROB() const { return status[RobEntry]; }
7566384Sgblack@eecs.umich.edu
7576384Sgblack@eecs.umich.edu    /** Sets this instruction as squashed in the ROB. */
7586384Sgblack@eecs.umich.edu    void setSquashedInROB() { status.set(SquashedInROB); }
7596384Sgblack@eecs.umich.edu
7606384Sgblack@eecs.umich.edu    /** Returns whether or not this instruction is squashed in the ROB. */
7616384Sgblack@eecs.umich.edu    bool isSquashedInROB() const { return status[SquashedInROB]; }
7626384Sgblack@eecs.umich.edu
7636384Sgblack@eecs.umich.edu    /** Read the PC state of this instruction. */
7646384Sgblack@eecs.umich.edu    const TheISA::PCState pcState() const { return pc; }
7656384Sgblack@eecs.umich.edu
7666384Sgblack@eecs.umich.edu    /** Set the PC state of this instruction. */
7676384Sgblack@eecs.umich.edu    const void pcState(const TheISA::PCState &val) { pc = val; }
7686384Sgblack@eecs.umich.edu
7696384Sgblack@eecs.umich.edu    /** Read the PC of this instruction. */
7705222Sksewell@umich.edu    const Addr instAddr() const { return pc.instAddr(); }
7716384Sgblack@eecs.umich.edu
7726384Sgblack@eecs.umich.edu    /** Read the PC of the next instruction. */
7736384Sgblack@eecs.umich.edu    const Addr nextInstAddr() const { return pc.nextInstAddr(); }
7746384Sgblack@eecs.umich.edu
7756384Sgblack@eecs.umich.edu    /**Read the micro PC of this instruction. */
7766384Sgblack@eecs.umich.edu    const Addr microPC() const { return pc.microPC(); }
7776384Sgblack@eecs.umich.edu
7786384Sgblack@eecs.umich.edu    bool readPredicate()
7796384Sgblack@eecs.umich.edu    {
7806384Sgblack@eecs.umich.edu        return predicate;
7816384Sgblack@eecs.umich.edu    }
7826384Sgblack@eecs.umich.edu
7836384Sgblack@eecs.umich.edu    void setPredicate(bool val)
7846384Sgblack@eecs.umich.edu    {
7856384Sgblack@eecs.umich.edu        predicate = val;
7866384Sgblack@eecs.umich.edu
7876384Sgblack@eecs.umich.edu        if (traceData) {
7886384Sgblack@eecs.umich.edu            traceData->setPredicate(val);
7896384Sgblack@eecs.umich.edu        }
7906384Sgblack@eecs.umich.edu    }
7916384Sgblack@eecs.umich.edu
7926384Sgblack@eecs.umich.edu    /** Sets the ASID. */
7936384Sgblack@eecs.umich.edu    void setASID(short addr_space_id) { asid = addr_space_id; }
7946384Sgblack@eecs.umich.edu
7956384Sgblack@eecs.umich.edu    /** Sets the thread id. */
7966384Sgblack@eecs.umich.edu    void setTid(ThreadID tid) { threadNumber = tid; }
7975222Sksewell@umich.edu
7986384Sgblack@eecs.umich.edu    /** Sets the pointer to the thread state. */
7996384Sgblack@eecs.umich.edu    void setThreadState(ImplState *state) { thread = state; }
8006384Sgblack@eecs.umich.edu
8016384Sgblack@eecs.umich.edu    /** Returns the thread context. */
8026384Sgblack@eecs.umich.edu    ThreadContext *tcBase() { return thread->getTC(); }
8036384Sgblack@eecs.umich.edu
8046384Sgblack@eecs.umich.edu  private:
8056384Sgblack@eecs.umich.edu    /** Instruction effective address.
8066384Sgblack@eecs.umich.edu     *  @todo: Consider if this is necessary or not.
8076384Sgblack@eecs.umich.edu     */
8086384Sgblack@eecs.umich.edu    Addr instEffAddr;
8096384Sgblack@eecs.umich.edu
8106384Sgblack@eecs.umich.edu    /** Whether or not the effective address calculation is completed.
8116384Sgblack@eecs.umich.edu     *  @todo: Consider if this is necessary or not.
8126384Sgblack@eecs.umich.edu     */
8136384Sgblack@eecs.umich.edu    bool eaCalcDone;
8146384Sgblack@eecs.umich.edu
8156384Sgblack@eecs.umich.edu    /** Is this instruction's memory access uncacheable. */
8166384Sgblack@eecs.umich.edu    bool isUncacheable;
8176384Sgblack@eecs.umich.edu
8186384Sgblack@eecs.umich.edu    /** Has this instruction generated a memory request. */
8196384Sgblack@eecs.umich.edu    bool reqMade;
8206384Sgblack@eecs.umich.edu
8216384Sgblack@eecs.umich.edu  public:
8226384Sgblack@eecs.umich.edu    /** Sets the effective address. */
8236384Sgblack@eecs.umich.edu    void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; }
8246384Sgblack@eecs.umich.edu
8256384Sgblack@eecs.umich.edu    /** Returns the effective address. */
8266384Sgblack@eecs.umich.edu    const Addr &getEA() const { return instEffAddr; }
8276384Sgblack@eecs.umich.edu
8286384Sgblack@eecs.umich.edu    /** Returns whether or not the eff. addr. calculation has been completed. */
8296384Sgblack@eecs.umich.edu    bool doneEACalc() { return eaCalcDone; }
8306384Sgblack@eecs.umich.edu
8316384Sgblack@eecs.umich.edu    /** Returns whether or not the eff. addr. source registers are ready. */
8326384Sgblack@eecs.umich.edu    bool eaSrcsReady();
8336384Sgblack@eecs.umich.edu
8346384Sgblack@eecs.umich.edu    /** Whether or not the memory operation is done. */
8355222Sksewell@umich.edu    bool memOpDone;
8366384Sgblack@eecs.umich.edu
8376384Sgblack@eecs.umich.edu    /** Is this instruction's memory access uncacheable. */
8386384Sgblack@eecs.umich.edu    bool uncacheable() { return isUncacheable; }
8396384Sgblack@eecs.umich.edu
8406384Sgblack@eecs.umich.edu    /** Has this instruction generated a memory request. */
8416384Sgblack@eecs.umich.edu    bool hasRequest() { return reqMade; }
8426384Sgblack@eecs.umich.edu
8436384Sgblack@eecs.umich.edu  public:
8446384Sgblack@eecs.umich.edu    /** Load queue index. */
8456384Sgblack@eecs.umich.edu    int16_t lqIdx;
8462101SN/A
8476384Sgblack@eecs.umich.edu    /** Store queue index. */
8486384Sgblack@eecs.umich.edu    int16_t sqIdx;
8496384Sgblack@eecs.umich.edu
8506384Sgblack@eecs.umich.edu    /** Iterator pointing to this BaseDynInst in the list of all insts. */
8516384Sgblack@eecs.umich.edu    ListIt instListIt;
8526384Sgblack@eecs.umich.edu
8536384Sgblack@eecs.umich.edu    /** Returns iterator to this instruction in the list of all insts. */
8546384Sgblack@eecs.umich.edu    ListIt &getInstListIt() { return instListIt; }
8556384Sgblack@eecs.umich.edu
8566384Sgblack@eecs.umich.edu    /** Sets iterator for this instruction in the list of all insts. */
8576384Sgblack@eecs.umich.edu    void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; }
8586384Sgblack@eecs.umich.edu
8596384Sgblack@eecs.umich.edu  public:
8606385Sgblack@eecs.umich.edu    /** Returns the number of consecutive store conditional failures. */
8616384Sgblack@eecs.umich.edu    unsigned readStCondFailures()
8626384Sgblack@eecs.umich.edu    { return thread->storeCondFailures; }
8636384Sgblack@eecs.umich.edu
8646384Sgblack@eecs.umich.edu    /** Sets the number of consecutive store conditional failures. */
8656384Sgblack@eecs.umich.edu    void setStCondFailures(unsigned sc_failures)
8666384Sgblack@eecs.umich.edu    { thread->storeCondFailures = sc_failures; }
8676384Sgblack@eecs.umich.edu};
8686384Sgblack@eecs.umich.edu
8696384Sgblack@eecs.umich.edutemplate<class Impl>
8706384Sgblack@eecs.umich.eduFault
8716384Sgblack@eecs.umich.eduBaseDynInst<Impl>::readMem(Addr addr, uint8_t *data,
8726384Sgblack@eecs.umich.edu                           unsigned size, unsigned flags)
8736384Sgblack@eecs.umich.edu{
8742101SN/A    reqMade = true;
8752043SN/A    Request *req = NULL;
8762027SN/A    Request *sreqLow = NULL;
8772101SN/A    Request *sreqHigh = NULL;
8782101SN/A
8792101SN/A    if (reqMade && translationStarted) {
8802101SN/A        req = savedReq;
8812686Sksewell@umich.edu        sreqLow = savedSreqLow;
8828588Sgblack@eecs.umich.edu        sreqHigh = savedSreqHigh;
8832495SN/A    } else {
8842495SN/A        req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(),
8856384Sgblack@eecs.umich.edu                          thread->contextId(), threadNumber);
8862573SN/A
8872616SN/A        // Only split the request if the ISA supports unaligned accesses.
8882573SN/A        if (TheISA::HasUnalignedMemAcc) {
8892573SN/A            splitRequest(req, sreqLow, sreqHigh);
8906384Sgblack@eecs.umich.edu        }
8916384Sgblack@eecs.umich.edu        initiateTranslation(req, sreqLow, sreqHigh, NULL, BaseTLB::Read);
8922573SN/A    }
8932573SN/A
8946384Sgblack@eecs.umich.edu    if (translationCompleted) {
8952573SN/A        if (fault == NoFault) {
8962573SN/A            effAddr = req->getVaddr();
8976384Sgblack@eecs.umich.edu            effSize = size;
8986384Sgblack@eecs.umich.edu            effAddrValid = true;
8996384Sgblack@eecs.umich.edu#if USE_CHECKER
9002573SN/A            if (reqToVerify != NULL) {
9012573SN/A                delete reqToVerify;
9022616SN/A            }
9032573SN/A            reqToVerify = new Request(*req);
9042573SN/A#endif //USE_CHECKER
9055222Sksewell@umich.edu            fault = cpu->read(req, sreqLow, sreqHigh, data, lqIdx);
9062573SN/A        } else {
9072573SN/A            // Commit will have to clean up whatever happened.  Set this
9082573SN/A            // instruction as executed.
9098588Sgblack@eecs.umich.edu            this->setExecuted();
9102686Sksewell@umich.edu        }
9118588Sgblack@eecs.umich.edu
9122686Sksewell@umich.edu        if (fault != NoFault) {
9132573SN/A            // Return a fixed value to keep simulation deterministic even
9146384Sgblack@eecs.umich.edu            // along misspeculated paths.
9152573SN/A            if (data)
9168588Sgblack@eecs.umich.edu                bzero(data, size);
9176384Sgblack@eecs.umich.edu        }
9186384Sgblack@eecs.umich.edu    }
9192573SN/A
9202573SN/A    if (traceData) {
9216384Sgblack@eecs.umich.edu        traceData->setAddr(addr);
9228588Sgblack@eecs.umich.edu    }
9236384Sgblack@eecs.umich.edu
9248588Sgblack@eecs.umich.edu    return fault;
9256384Sgblack@eecs.umich.edu}
9262573SN/A
9272573SN/Atemplate<class Impl>
9286384Sgblack@eecs.umich.eduFault
9298588Sgblack@eecs.umich.eduBaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size,
9306384Sgblack@eecs.umich.edu                            Addr addr, unsigned flags, uint64_t *res)
9318588Sgblack@eecs.umich.edu{
9326384Sgblack@eecs.umich.edu    if (traceData) {
9338588Sgblack@eecs.umich.edu        traceData->setAddr(addr);
9342573SN/A    }
9352573SN/A
9368588Sgblack@eecs.umich.edu    reqMade = true;
9372573SN/A    Request *req = NULL;
9382573SN/A    Request *sreqLow = NULL;
9392573SN/A    Request *sreqHigh = NULL;
9406384Sgblack@eecs.umich.edu
9416384Sgblack@eecs.umich.edu    if (reqMade && translationStarted) {
9426384Sgblack@eecs.umich.edu        req = savedReq;
9436384Sgblack@eecs.umich.edu        sreqLow = savedSreqLow;
9442495SN/A        sreqHigh = savedSreqHigh;
9452495SN/A    } else {
9462686Sksewell@umich.edu        req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(),
9472686Sksewell@umich.edu                          thread->contextId(), threadNumber);
9488588Sgblack@eecs.umich.edu
9498588Sgblack@eecs.umich.edu        // Only split the request if the ISA supports unaligned accesses.
9508588Sgblack@eecs.umich.edu        if (TheISA::HasUnalignedMemAcc) {
9512686Sksewell@umich.edu            splitRequest(req, sreqLow, sreqHigh);
9522686Sksewell@umich.edu        }
9532101SN/A        initiateTranslation(req, sreqLow, sreqHigh, res, BaseTLB::Write);
9545222Sksewell@umich.edu    }
9555222Sksewell@umich.edu
9565222Sksewell@umich.edu    if (fault == NoFault && translationCompleted) {
9575222Sksewell@umich.edu        effAddr = req->getVaddr();
9586384Sgblack@eecs.umich.edu        effSize = size;
9592025SN/A        effAddrValid = true;
9606384Sgblack@eecs.umich.edu#if USE_CHECKER
9616384Sgblack@eecs.umich.edu        if (reqToVerify != NULL) {
9626384Sgblack@eecs.umich.edu            delete reqToVerify;
9636384Sgblack@eecs.umich.edu        }
9646384Sgblack@eecs.umich.edu        reqToVerify = new Request(*req);
9656384Sgblack@eecs.umich.edu#endif // USE_CHECKER
9666384Sgblack@eecs.umich.edu        fault = cpu->write(req, sreqLow, sreqHigh, data, sqIdx);
9676384Sgblack@eecs.umich.edu    }
9686384Sgblack@eecs.umich.edu
9696384Sgblack@eecs.umich.edu    return fault;
9706384Sgblack@eecs.umich.edu}
9716384Sgblack@eecs.umich.edu
9726384Sgblack@eecs.umich.edutemplate<class Impl>
9736384Sgblack@eecs.umich.eduinline void
9746384Sgblack@eecs.umich.eduBaseDynInst<Impl>::splitRequest(RequestPtr req, RequestPtr &sreqLow,
9756384Sgblack@eecs.umich.edu                                RequestPtr &sreqHigh)
9766384Sgblack@eecs.umich.edu{
9776384Sgblack@eecs.umich.edu    // Check to see if the request crosses the next level block boundary.
9786384Sgblack@eecs.umich.edu    unsigned block_size = cpu->getDataPort().peerBlockSize();
9796384Sgblack@eecs.umich.edu    Addr addr = req->getVaddr();
9806384Sgblack@eecs.umich.edu    Addr split_addr = roundDown(addr + req->getSize() - 1, block_size);
9816384Sgblack@eecs.umich.edu    assert(split_addr <= addr || split_addr - addr < block_size);
9826384Sgblack@eecs.umich.edu
9836384Sgblack@eecs.umich.edu    // Spans two blocks.
9846384Sgblack@eecs.umich.edu    if (split_addr > addr) {
9856384Sgblack@eecs.umich.edu        req->splitOnVaddr(split_addr, sreqLow, sreqHigh);
9866384Sgblack@eecs.umich.edu    }
9872043SN/A}
9882027SN/A
9892101SN/Atemplate<class Impl>
9902101SN/Ainline void
9916384Sgblack@eecs.umich.eduBaseDynInst<Impl>::initiateTranslation(RequestPtr req, RequestPtr sreqLow,
9926384Sgblack@eecs.umich.edu                                       RequestPtr sreqHigh, uint64_t *res,
9932572SN/A                                       BaseTLB::Mode mode)
9942572SN/A{
9952101SN/A    translationStarted = true;
9968588Sgblack@eecs.umich.edu
9978588Sgblack@eecs.umich.edu    if (!TheISA::HasUnalignedMemAcc || sreqLow == NULL) {
9988588Sgblack@eecs.umich.edu        WholeTranslationState *state =
9998588Sgblack@eecs.umich.edu            new WholeTranslationState(req, NULL, res, mode);
10008588Sgblack@eecs.umich.edu
10018588Sgblack@eecs.umich.edu        // One translation if the request isn't split.
10028588Sgblack@eecs.umich.edu        DataTranslation<BaseDynInstPtr> *trans =
10032101SN/A            new DataTranslation<BaseDynInstPtr>(this, state);
10048588Sgblack@eecs.umich.edu        cpu->dtb->translateTiming(req, thread->getTC(), trans, mode);
10052101SN/A        if (!translationCompleted) {
10062572SN/A            // Save memory requests.
10072686Sksewell@umich.edu            savedReq = state->mainReq;
10088588Sgblack@eecs.umich.edu            savedSreqLow = state->sreqLow;
10096384Sgblack@eecs.umich.edu            savedSreqHigh = state->sreqHigh;
10108588Sgblack@eecs.umich.edu        }
10116384Sgblack@eecs.umich.edu    } else {
10128588Sgblack@eecs.umich.edu        WholeTranslationState *state =
10136384Sgblack@eecs.umich.edu            new WholeTranslationState(req, sreqLow, sreqHigh, NULL, res, mode);
10148588Sgblack@eecs.umich.edu
10156384Sgblack@eecs.umich.edu        // Two translations when the request is split.
10168588Sgblack@eecs.umich.edu        DataTranslation<BaseDynInstPtr> *stransLow =
10176384Sgblack@eecs.umich.edu            new DataTranslation<BaseDynInstPtr>(this, state, 0);
10188588Sgblack@eecs.umich.edu        DataTranslation<BaseDynInstPtr> *stransHigh =
10196384Sgblack@eecs.umich.edu            new DataTranslation<BaseDynInstPtr>(this, state, 1);
10208588Sgblack@eecs.umich.edu
10216384Sgblack@eecs.umich.edu        cpu->dtb->translateTiming(sreqLow, thread->getTC(), stransLow, mode);
10228588Sgblack@eecs.umich.edu        cpu->dtb->translateTiming(sreqHigh, thread->getTC(), stransHigh, mode);
10236384Sgblack@eecs.umich.edu        if (!translationCompleted) {
10242101SN/A            // Save memory requests.
10252101SN/A            savedReq = state->mainReq;
10262027SN/A            savedSreqLow = state->sreqLow;
10272572SN/A            savedSreqHigh = state->sreqHigh;
10282101SN/A        }
10292686Sksewell@umich.edu    }
10306384Sgblack@eecs.umich.edu}
10316384Sgblack@eecs.umich.edu
10326384Sgblack@eecs.umich.edutemplate<class Impl>
10336384Sgblack@eecs.umich.eduinline void
10346384Sgblack@eecs.umich.eduBaseDynInst<Impl>::finishTranslation(WholeTranslationState *state)
10356384Sgblack@eecs.umich.edu{
10366384Sgblack@eecs.umich.edu    fault = state->getFault();
10376384Sgblack@eecs.umich.edu
10382101SN/A    if (state->isUncacheable())
10392101SN/A        isUncacheable = true;
10402027SN/A
10412686Sksewell@umich.edu    if (fault == NoFault) {
10422686Sksewell@umich.edu        physEffAddr = state->getPaddr();
10432686Sksewell@umich.edu        memReqFlags = state->getFlags();
10442686Sksewell@umich.edu
10452686Sksewell@umich.edu        if (state->mainReq->isCondSwap()) {
10462602SN/A            assert(state->res);
10472602SN/A            state->mainReq->setExtraData(*state->res);
10486384Sgblack@eecs.umich.edu        }
10492101SN/A
10505222Sksewell@umich.edu    } else {
10516384Sgblack@eecs.umich.edu        state->deleteReqs();
10525222Sksewell@umich.edu    }
10532101SN/A    delete state;
10545222Sksewell@umich.edu
10552027SN/A    translationCompleted = true;
10562572SN/A}
10572603SN/A
10588588Sgblack@eecs.umich.edu#endif // __CPU_BASE_DYN_INST_HH__
10598588Sgblack@eecs.umich.edu