dyn_inst.hh revision 13954
11689SN/A/*
27944SGiacomo.Gabrielli@arm.com * Copyright (c) 2013-2014 ARM Limited
37944SGiacomo.Gabrielli@arm.com * All rights reserved
47944SGiacomo.Gabrielli@arm.com *
57944SGiacomo.Gabrielli@arm.com * The license below extends only to copyright in the software and shall
67944SGiacomo.Gabrielli@arm.com * not be construed as granting a license to any other intellectual
77944SGiacomo.Gabrielli@arm.com * property including but not limited to intellectual property relating
87944SGiacomo.Gabrielli@arm.com * to a hardware implementation of the functionality of the software
97944SGiacomo.Gabrielli@arm.com * licensed hereunder.  You may use the software subject to the license
107944SGiacomo.Gabrielli@arm.com * terms below provided that you ensure that this notice is replicated
117944SGiacomo.Gabrielli@arm.com * unmodified and in its entirety in all distributions of the software,
127944SGiacomo.Gabrielli@arm.com * modified or unmodified, in source code or in binary form.
137944SGiacomo.Gabrielli@arm.com *
142326SN/A * Redistribution and use in source and binary forms, with or without
151689SN/A * modification, are permitted provided that the following conditions are
161689SN/A * met: redistributions of source code must retain the above copyright
171689SN/A * notice, this list of conditions and the following disclaimer;
181689SN/A * redistributions in binary form must reproduce the above copyright
191689SN/A * notice, this list of conditions and the following disclaimer in the
201689SN/A * documentation and/or other materials provided with the distribution;
211689SN/A * neither the name of the copyright holders nor the names of its
221689SN/A * contributors may be used to endorse or promote products derived from
231689SN/A * this software without specific prior written permission.
241689SN/A *
251689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
261689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
271689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
281689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
291689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
301689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
311689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
321689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
331689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
341689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
351689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
361689SN/A *
371689SN/A * Authors: Andrew Bardsley
381689SN/A */
392665Ssaidi@eecs.umich.edu
402665Ssaidi@eecs.umich.edu/**
411689SN/A * @file
421689SN/A *
432292SN/A *  The dynamic instruction and instruction/line id (sequence numbers)
442292SN/A *  definition for Minor.  A spirited attempt is made here to not carry too
451060SN/A *  much on this structure.
461060SN/A */
471061SN/A
481060SN/A#ifndef __CPU_MINOR_DYN_INST_HH__
491061SN/A#define __CPU_MINOR_DYN_INST_HH__
501060SN/A
511062SN/A#include <iostream>
527813Ssteve.reinhardt@amd.com
536216Snate@binkert.org#include "base/refcnt.hh"
541061SN/A#include "cpu/minor/buffers.hh"
552326SN/A#include "cpu/inst_seq.hh"
562669Sktlim@umich.edu#include "cpu/static_inst.hh"
575529Snate@binkert.org#include "cpu/timing_expr.hh"
581060SN/A#include "sim/faults.hh"
595529Snate@binkert.org
602292SN/Anamespace Minor
612292SN/A{
622292SN/A
631060SN/Aclass MinorDynInst;
641689SN/A
651689SN/A/** MinorDynInsts are currently reference counted. */
661689SN/Atypedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;
671689SN/A
681060SN/A/** Id for lines and instructions.  This includes all the relevant sequence
691060SN/A *  numbers and thread ids for all stages of execution. */
701060SN/Aclass InstId
712292SN/A{
722292SN/A  public:
732292SN/A    /** First sequence numbers to use in initialisation of the pipeline and
742292SN/A     *  to be expected on the first line/instruction issued */
752292SN/A    static const InstSeqNum firstStreamSeqNum = 1;
762292SN/A    static const InstSeqNum firstPredictionSeqNum = 1;
772292SN/A    static const InstSeqNum firstLineSeqNum = 1;
782292SN/A    static const InstSeqNum firstFetchSeqNum = 1;
791060SN/A    static const InstSeqNum firstExecSeqNum = 1;
801061SN/A
811060SN/A  public:
821060SN/A    /** The thread to which this line/instruction belongs */
831060SN/A    ThreadID threadId;
841060SN/A
852733Sktlim@umich.edu    /** The 'stream' this instruction belongs to.  Streams are interrupted
861061SN/A     *  (and sequence numbers increased) when Execute finds it wants to
871060SN/A     *  change the stream of instructions due to a branch. */
882292SN/A    InstSeqNum streamSeqNum;
891061SN/A
901061SN/A    /** The predicted qualifier to stream, attached by Fetch2 as a
911061SN/A     *  consequence of branch prediction */
921060SN/A    InstSeqNum predictionSeqNum;
932292SN/A
941061SN/A    /** Line sequence number.  This is the sequence number of the fetched
951060SN/A     *  line from which this instruction was fetched */
962733Sktlim@umich.edu    InstSeqNum lineSeqNum;
972292SN/A
982292SN/A    /** Fetch sequence number.  This is 0 for bubbles and an ascending
992292SN/A     *  sequence for the stream of all fetched instructions */
1002292SN/A    InstSeqNum fetchSeqNum;
1012292SN/A
1022292SN/A    /** 'Execute' sequence number.  These are assigned after micro-op
1032292SN/A     *  decomposition and form an ascending sequence (starting with 1) for
1042292SN/A     *  post-micro-op decomposed instructions. */
1052292SN/A    InstSeqNum execSeqNum;
1062292SN/A
1072292SN/A  public:
1082292SN/A    /** Very boring default constructor */
1092292SN/A    InstId(
1102348SN/A        ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0,
1112348SN/A        InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0,
1122348SN/A        InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) :
1132326SN/A        threadId(thread_id), streamSeqNum(stream_seq_num),
1142326SN/A        predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num),
1152292SN/A        fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num)
1162292SN/A    { }
1172292SN/A
1182292SN/A  public:
1192292SN/A    /* Equal if the thread and last set sequence number matches */
1202292SN/A    bool
1215336Shines@cs.fsu.edu    operator== (const InstId &rhs)
1222326SN/A    {
1231060SN/A        /* If any of fetch and exec sequence number are not set
1241060SN/A         *  they need to be 0, so a straight comparison is still
1252292SN/A         *  fine */
1265529Snate@binkert.org        bool ret = (threadId == rhs.threadId &&
1271061SN/A            lineSeqNum == rhs.lineSeqNum &&
1282292SN/A            fetchSeqNum == rhs.fetchSeqNum &&
1292292SN/A            execSeqNum == rhs.execSeqNum);
1301061SN/A
1312292SN/A        /* Stream and prediction *must* match if these are the same id */
1322292SN/A        if (ret) {
1331060SN/A            assert(streamSeqNum == rhs.streamSeqNum &&
1342292SN/A                predictionSeqNum == rhs.predictionSeqNum);
1351062SN/A        }
1361062SN/A
1372348SN/A        return ret;
1382307SN/A    }
1391060SN/A};
1402292SN/A
1416221Snate@binkert.org/** Print this id in the usual slash-separated format expected by
1422292SN/A *  MinorTrace */
1432292SN/Astd::ostream &operator <<(std::ostream &os, const InstId &id);
1441060SN/A
1451060SN/Aclass MinorDynInst;
1462292SN/A
1471060SN/A/** Print a short reference to this instruction.  '-' for a bubble and a
1481060SN/A *  series of '/' separated sequence numbers for other instructions.  The
1492348SN/A *  sequence numbers will be in the order: stream, prediction, line, fetch,
1502307SN/A *  exec with exec absent if it is 0.  This is used by MinorTrace. */
1512307SN/Astd::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
1522348SN/A
1532307SN/A/** Dynamic instruction for Minor.
1542307SN/A *  MinorDynInst implements the BubbleIF interface
1552348SN/A *  Has two separate notions of sequence number for pre/post-micro-op
1562307SN/A *  decomposition: fetchSeqNum and execSeqNum */
1572307SN/Aclass MinorDynInst : public RefCounted
1582292SN/A{
1596221Snate@binkert.org  private:
1602292SN/A    /** A prototypical bubble instruction.  You must call MinorDynInst::init
1612292SN/A     *  to initialise this */
1622292SN/A    static MinorDynInstPtr bubbleInst;
1632292SN/A
1642292SN/A  public:
1651060SN/A    StaticInstPtr staticInst;
1661060SN/A
1672292SN/A    InstId id;
1686221Snate@binkert.org
1692292SN/A    /** Trace information for this instruction's execution */
1702292SN/A    Trace::InstRecord *traceData;
1711060SN/A
1721060SN/A    /** The fetch address of this instruction */
1732292SN/A    TheISA::PCState pc;
1746221Snate@binkert.org
1752292SN/A    /** This is actually a fault masquerading as an instruction */
1762292SN/A    Fault fault;
1772292SN/A
1782292SN/A    /** Tried to predict the destination of this inst (if a control
1792292SN/A     *  instruction or a sys call) */
1801061SN/A    bool triedToPredict;
1811060SN/A
1822292SN/A    /** This instruction was predicted to change control flow and
1831061SN/A     *  the following instructions will have a newer predictionSeqNum */
1841061SN/A    bool predictedTaken;
1852292SN/A
1862292SN/A    /** Predicted branch target */
1872292SN/A    TheISA::PCState predictedTarget;
1882292SN/A
1891060SN/A    /** Fields only set during execution */
1902348SN/A
1912348SN/A    /** FU this instruction is issued to */
1922348SN/A    unsigned int fuIndex;
1932333SN/A
1942333SN/A    /** This instruction is in the LSQ, not a functional unit */
1957944SGiacomo.Gabrielli@arm.com    bool inLSQ;
1967944SGiacomo.Gabrielli@arm.com
1977944SGiacomo.Gabrielli@arm.com    /** The instruction has been sent to the store buffer */
1987944SGiacomo.Gabrielli@arm.com    bool inStoreBuffer;
1997944SGiacomo.Gabrielli@arm.com
2002292SN/A    /** Can this instruction be executed out of order.  In this model,
2012326SN/A     *  this only happens with mem refs that need to be issued early
2022326SN/A     *  to allow other instructions to fill the fetch delay */
2032292SN/A    bool canEarlyIssue;
2042326SN/A
2052326SN/A    /** Flag controlling conditional execution of the instruction */
2061755SN/A    bool predicate;
2072292SN/A
2082292SN/A    /** Flag controlling conditional execution of the memory access associated
2092292SN/A     *  with the instruction (only meaningful for loads/stores) */
2102292SN/A    bool memAccPredicate;
2112292SN/A
2122292SN/A    /** execSeqNum of the latest inst on which this inst depends.
2132292SN/A     *  This can be used as a sanity check for dependency ordering
2141060SN/A     *  where slightly out of order execution is required (notably
2151060SN/A     *  initiateAcc for memory ops) */
2162292SN/A    InstSeqNum instToWaitFor;
2171061SN/A
2181061SN/A    /** Extra delay at the end of the pipeline */
2192292SN/A    Cycles extraCommitDelay;
2202292SN/A    TimingExpr *extraCommitDelayExpr;
2212292SN/A
2222292SN/A    /** Once issued, extraCommitDelay becomes minimumCommitCycle
2236221Snate@binkert.org     *  to account for delay in absolute time */
2241061SN/A    Cycles minimumCommitCycle;
2252292SN/A
2262301SN/A    /** Flat register indices so that, when clearing the scoreboard, we
2271755SN/A     *  have the same register indices as when the instruction was marked
2282292SN/A     *  up */
2292292SN/A    RegId flatDestRegIdx[TheISA::MaxInstDestRegs];
2302292SN/A
2312292SN/A  public:
2322292SN/A    MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) :
2332292SN/A        staticInst(NULL), id(id_), traceData(NULL),
2342292SN/A        pc(TheISA::PCState(0)), fault(fault_),
2352292SN/A        triedToPredict(false), predictedTaken(false),
2362292SN/A        fuIndex(0), inLSQ(false), inStoreBuffer(false),
2372292SN/A        canEarlyIssue(false), predicate(true), memAccPredicate(true),
2382292SN/A        instToWaitFor(0), extraCommitDelay(Cycles(0)),
2392292SN/A        extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0))
2402292SN/A    { }
2412292SN/A
2422292SN/A  public:
2437944SGiacomo.Gabrielli@arm.com    /** The BubbleIF interface. */
2447944SGiacomo.Gabrielli@arm.com    bool isBubble() const { return id.fetchSeqNum == 0; }
2457944SGiacomo.Gabrielli@arm.com
2467944SGiacomo.Gabrielli@arm.com    /** There is a single bubble inst */
2477944SGiacomo.Gabrielli@arm.com    static MinorDynInstPtr bubble() { return bubbleInst; }
2487944SGiacomo.Gabrielli@arm.com
2492292SN/A    /** Is this a fault rather than instruction */
2501061SN/A    bool isFault() const { return fault != NoFault; }
2511061SN/A
2522292SN/A    /** Is this a real instruction */
2532292SN/A    bool isInst() const { return !isBubble() && !isFault(); }
2542292SN/A
2552292SN/A    /** Is this a real mem ref instruction */
2566221Snate@binkert.org    bool isMemRef() const { return isInst() && staticInst->isMemRef(); }
2571060SN/A
2582292SN/A    /** Is this an instruction that can be executed `for free' and
2596221Snate@binkert.org     *  needn't spend time in an FU */
2601060SN/A    bool isNoCostInst() const;
2612292SN/A
2622292SN/A    /** Assuming this is not a fault, is this instruction either
2631060SN/A     *  a whole instruction or the last microop from a macroop */
2641060SN/A    bool isLastOpInInst() const;
2652292SN/A
2666221Snate@binkert.org    /** Initialise the class */
2672292SN/A    static void init();
2682292SN/A
2692292SN/A    /** Print (possibly verbose) instruction information for
2702292SN/A     *  MinorTrace using the given Named object's name */
2712292SN/A    void minorTraceInst(const Named &named_object) const;
2721060SN/A
2732733Sktlim@umich.edu    /** ReportIF interface */
2741060SN/A    void reportData(std::ostream &os) const;
2752292SN/A
2762292SN/A    bool readPredicate() const { return predicate; }
2772292SN/A
2782292SN/A    void setPredicate(bool val) { predicate = val; }
2792292SN/A
2802292SN/A    bool readMemAccPredicate() const { return memAccPredicate; }
2811061SN/A
2821061SN/A    void setMemAccPredicate(bool val) { memAccPredicate = val; }
2831061SN/A
2842292SN/A    ~MinorDynInst();
2851061SN/A};
2861060SN/A
2871060SN/A/** Print a summary of the instruction */
2881060SN/Astd::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
2891060SN/A
2901060SN/A}
2911060SN/A
2921060SN/A#endif /* __CPU_MINOR_DYN_INST_HH__ */
2931060SN/A