110259SAndrew.Bardsley@arm.com/*
214105Sgabor.dozsa@arm.com * Copyright (c) 2013-2014,2018 ARM Limited
310259SAndrew.Bardsley@arm.com * All rights reserved
410259SAndrew.Bardsley@arm.com *
510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall
610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual
710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating
810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software
910259SAndrew.Bardsley@arm.com * licensed hereunder.  You may use the software subject to the license
1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated
1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software,
1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form.
1310259SAndrew.Bardsley@arm.com *
1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without
1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are
1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright
1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer;
1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright
1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the
2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution;
2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its
2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from
2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission.
2410259SAndrew.Bardsley@arm.com *
2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610259SAndrew.Bardsley@arm.com *
3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley
3810259SAndrew.Bardsley@arm.com */
3910259SAndrew.Bardsley@arm.com
4010259SAndrew.Bardsley@arm.com/**
4110259SAndrew.Bardsley@arm.com * @file
4210259SAndrew.Bardsley@arm.com *
4310259SAndrew.Bardsley@arm.com *  The dynamic instruction and instruction/line id (sequence numbers)
4410259SAndrew.Bardsley@arm.com *  definition for Minor.  A spirited attempt is made here to not carry too
4510259SAndrew.Bardsley@arm.com *  much on this structure.
4610259SAndrew.Bardsley@arm.com */
4710259SAndrew.Bardsley@arm.com
4810259SAndrew.Bardsley@arm.com#ifndef __CPU_MINOR_DYN_INST_HH__
4910259SAndrew.Bardsley@arm.com#define __CPU_MINOR_DYN_INST_HH__
5010259SAndrew.Bardsley@arm.com
5110259SAndrew.Bardsley@arm.com#include <iostream>
5210259SAndrew.Bardsley@arm.com
5310259SAndrew.Bardsley@arm.com#include "base/refcnt.hh"
5410259SAndrew.Bardsley@arm.com#include "cpu/minor/buffers.hh"
5510259SAndrew.Bardsley@arm.com#include "cpu/inst_seq.hh"
5610259SAndrew.Bardsley@arm.com#include "cpu/static_inst.hh"
5710259SAndrew.Bardsley@arm.com#include "cpu/timing_expr.hh"
5810259SAndrew.Bardsley@arm.com#include "sim/faults.hh"
5910259SAndrew.Bardsley@arm.com
6010259SAndrew.Bardsley@arm.comnamespace Minor
6110259SAndrew.Bardsley@arm.com{
6210259SAndrew.Bardsley@arm.com
6310259SAndrew.Bardsley@arm.comclass MinorDynInst;
6410259SAndrew.Bardsley@arm.com
6510259SAndrew.Bardsley@arm.com/** MinorDynInsts are currently reference counted. */
6610259SAndrew.Bardsley@arm.comtypedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;
6710259SAndrew.Bardsley@arm.com
6810259SAndrew.Bardsley@arm.com/** Id for lines and instructions.  This includes all the relevant sequence
6910259SAndrew.Bardsley@arm.com *  numbers and thread ids for all stages of execution. */
7010259SAndrew.Bardsley@arm.comclass InstId
7110259SAndrew.Bardsley@arm.com{
7210259SAndrew.Bardsley@arm.com  public:
7310259SAndrew.Bardsley@arm.com    /** First sequence numbers to use in initialisation of the pipeline and
7410259SAndrew.Bardsley@arm.com     *  to be expected on the first line/instruction issued */
7510259SAndrew.Bardsley@arm.com    static const InstSeqNum firstStreamSeqNum = 1;
7610259SAndrew.Bardsley@arm.com    static const InstSeqNum firstPredictionSeqNum = 1;
7710259SAndrew.Bardsley@arm.com    static const InstSeqNum firstLineSeqNum = 1;
7810259SAndrew.Bardsley@arm.com    static const InstSeqNum firstFetchSeqNum = 1;
7910259SAndrew.Bardsley@arm.com    static const InstSeqNum firstExecSeqNum = 1;
8010259SAndrew.Bardsley@arm.com
8110259SAndrew.Bardsley@arm.com  public:
8210259SAndrew.Bardsley@arm.com    /** The thread to which this line/instruction belongs */
8310259SAndrew.Bardsley@arm.com    ThreadID threadId;
8410259SAndrew.Bardsley@arm.com
8510259SAndrew.Bardsley@arm.com    /** The 'stream' this instruction belongs to.  Streams are interrupted
8610259SAndrew.Bardsley@arm.com     *  (and sequence numbers increased) when Execute finds it wants to
8710259SAndrew.Bardsley@arm.com     *  change the stream of instructions due to a branch. */
8810259SAndrew.Bardsley@arm.com    InstSeqNum streamSeqNum;
8910259SAndrew.Bardsley@arm.com
9010259SAndrew.Bardsley@arm.com    /** The predicted qualifier to stream, attached by Fetch2 as a
9110259SAndrew.Bardsley@arm.com     *  consequence of branch prediction */
9210259SAndrew.Bardsley@arm.com    InstSeqNum predictionSeqNum;
9310259SAndrew.Bardsley@arm.com
9410259SAndrew.Bardsley@arm.com    /** Line sequence number.  This is the sequence number of the fetched
9510259SAndrew.Bardsley@arm.com     *  line from which this instruction was fetched */
9610259SAndrew.Bardsley@arm.com    InstSeqNum lineSeqNum;
9710259SAndrew.Bardsley@arm.com
9810259SAndrew.Bardsley@arm.com    /** Fetch sequence number.  This is 0 for bubbles and an ascending
9910259SAndrew.Bardsley@arm.com     *  sequence for the stream of all fetched instructions */
10010259SAndrew.Bardsley@arm.com    InstSeqNum fetchSeqNum;
10110259SAndrew.Bardsley@arm.com
10210259SAndrew.Bardsley@arm.com    /** 'Execute' sequence number.  These are assigned after micro-op
10310259SAndrew.Bardsley@arm.com     *  decomposition and form an ascending sequence (starting with 1) for
10410259SAndrew.Bardsley@arm.com     *  post-micro-op decomposed instructions. */
10510259SAndrew.Bardsley@arm.com    InstSeqNum execSeqNum;
10610259SAndrew.Bardsley@arm.com
10710259SAndrew.Bardsley@arm.com  public:
10810259SAndrew.Bardsley@arm.com    /** Very boring default constructor */
10910259SAndrew.Bardsley@arm.com    InstId(
11010259SAndrew.Bardsley@arm.com        ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0,
11110259SAndrew.Bardsley@arm.com        InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0,
11210259SAndrew.Bardsley@arm.com        InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) :
11310259SAndrew.Bardsley@arm.com        threadId(thread_id), streamSeqNum(stream_seq_num),
11410259SAndrew.Bardsley@arm.com        predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num),
11510259SAndrew.Bardsley@arm.com        fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num)
11610259SAndrew.Bardsley@arm.com    { }
11710259SAndrew.Bardsley@arm.com
11810259SAndrew.Bardsley@arm.com  public:
11910259SAndrew.Bardsley@arm.com    /* Equal if the thread and last set sequence number matches */
12010259SAndrew.Bardsley@arm.com    bool
12110259SAndrew.Bardsley@arm.com    operator== (const InstId &rhs)
12210259SAndrew.Bardsley@arm.com    {
12310259SAndrew.Bardsley@arm.com        /* If any of fetch and exec sequence number are not set
12410259SAndrew.Bardsley@arm.com         *  they need to be 0, so a straight comparison is still
12510259SAndrew.Bardsley@arm.com         *  fine */
12610259SAndrew.Bardsley@arm.com        bool ret = (threadId == rhs.threadId &&
12710259SAndrew.Bardsley@arm.com            lineSeqNum == rhs.lineSeqNum &&
12810259SAndrew.Bardsley@arm.com            fetchSeqNum == rhs.fetchSeqNum &&
12910259SAndrew.Bardsley@arm.com            execSeqNum == rhs.execSeqNum);
13010259SAndrew.Bardsley@arm.com
13110259SAndrew.Bardsley@arm.com        /* Stream and prediction *must* match if these are the same id */
13210259SAndrew.Bardsley@arm.com        if (ret) {
13310259SAndrew.Bardsley@arm.com            assert(streamSeqNum == rhs.streamSeqNum &&
13410259SAndrew.Bardsley@arm.com                predictionSeqNum == rhs.predictionSeqNum);
13510259SAndrew.Bardsley@arm.com        }
13610259SAndrew.Bardsley@arm.com
13710259SAndrew.Bardsley@arm.com        return ret;
13810259SAndrew.Bardsley@arm.com    }
13910259SAndrew.Bardsley@arm.com};
14010259SAndrew.Bardsley@arm.com
14110259SAndrew.Bardsley@arm.com/** Print this id in the usual slash-separated format expected by
14210259SAndrew.Bardsley@arm.com *  MinorTrace */
14310259SAndrew.Bardsley@arm.comstd::ostream &operator <<(std::ostream &os, const InstId &id);
14410259SAndrew.Bardsley@arm.com
14510259SAndrew.Bardsley@arm.comclass MinorDynInst;
14610259SAndrew.Bardsley@arm.com
14710259SAndrew.Bardsley@arm.com/** Print a short reference to this instruction.  '-' for a bubble and a
14810259SAndrew.Bardsley@arm.com *  series of '/' separated sequence numbers for other instructions.  The
14910259SAndrew.Bardsley@arm.com *  sequence numbers will be in the order: stream, prediction, line, fetch,
15010259SAndrew.Bardsley@arm.com *  exec with exec absent if it is 0.  This is used by MinorTrace. */
15110259SAndrew.Bardsley@arm.comstd::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
15210259SAndrew.Bardsley@arm.com
15310259SAndrew.Bardsley@arm.com/** Dynamic instruction for Minor.
15410259SAndrew.Bardsley@arm.com *  MinorDynInst implements the BubbleIF interface
15510259SAndrew.Bardsley@arm.com *  Has two separate notions of sequence number for pre/post-micro-op
15610259SAndrew.Bardsley@arm.com *  decomposition: fetchSeqNum and execSeqNum */
15710259SAndrew.Bardsley@arm.comclass MinorDynInst : public RefCounted
15810259SAndrew.Bardsley@arm.com{
15910259SAndrew.Bardsley@arm.com  private:
16010259SAndrew.Bardsley@arm.com    /** A prototypical bubble instruction.  You must call MinorDynInst::init
16110259SAndrew.Bardsley@arm.com     *  to initialise this */
16210259SAndrew.Bardsley@arm.com    static MinorDynInstPtr bubbleInst;
16310259SAndrew.Bardsley@arm.com
16410259SAndrew.Bardsley@arm.com  public:
16510259SAndrew.Bardsley@arm.com    StaticInstPtr staticInst;
16610259SAndrew.Bardsley@arm.com
16710259SAndrew.Bardsley@arm.com    InstId id;
16810259SAndrew.Bardsley@arm.com
16910259SAndrew.Bardsley@arm.com    /** Trace information for this instruction's execution */
17010259SAndrew.Bardsley@arm.com    Trace::InstRecord *traceData;
17110259SAndrew.Bardsley@arm.com
17210259SAndrew.Bardsley@arm.com    /** The fetch address of this instruction */
17310259SAndrew.Bardsley@arm.com    TheISA::PCState pc;
17410259SAndrew.Bardsley@arm.com
17510259SAndrew.Bardsley@arm.com    /** This is actually a fault masquerading as an instruction */
17610259SAndrew.Bardsley@arm.com    Fault fault;
17710259SAndrew.Bardsley@arm.com
17810259SAndrew.Bardsley@arm.com    /** Tried to predict the destination of this inst (if a control
17910259SAndrew.Bardsley@arm.com     *  instruction or a sys call) */
18010259SAndrew.Bardsley@arm.com    bool triedToPredict;
18110259SAndrew.Bardsley@arm.com
18210259SAndrew.Bardsley@arm.com    /** This instruction was predicted to change control flow and
18310259SAndrew.Bardsley@arm.com     *  the following instructions will have a newer predictionSeqNum */
18410259SAndrew.Bardsley@arm.com    bool predictedTaken;
18510259SAndrew.Bardsley@arm.com
18610259SAndrew.Bardsley@arm.com    /** Predicted branch target */
18710259SAndrew.Bardsley@arm.com    TheISA::PCState predictedTarget;
18810259SAndrew.Bardsley@arm.com
18910259SAndrew.Bardsley@arm.com    /** Fields only set during execution */
19010259SAndrew.Bardsley@arm.com
19110259SAndrew.Bardsley@arm.com    /** FU this instruction is issued to */
19210259SAndrew.Bardsley@arm.com    unsigned int fuIndex;
19310259SAndrew.Bardsley@arm.com
19410259SAndrew.Bardsley@arm.com    /** This instruction is in the LSQ, not a functional unit */
19510259SAndrew.Bardsley@arm.com    bool inLSQ;
19610259SAndrew.Bardsley@arm.com
19714105Sgabor.dozsa@arm.com    /** Translation fault in case of a mem ref */
19814105Sgabor.dozsa@arm.com    Fault translationFault;
19914105Sgabor.dozsa@arm.com
20010259SAndrew.Bardsley@arm.com    /** The instruction has been sent to the store buffer */
20110259SAndrew.Bardsley@arm.com    bool inStoreBuffer;
20210259SAndrew.Bardsley@arm.com
20310259SAndrew.Bardsley@arm.com    /** Can this instruction be executed out of order.  In this model,
20410259SAndrew.Bardsley@arm.com     *  this only happens with mem refs that need to be issued early
20510259SAndrew.Bardsley@arm.com     *  to allow other instructions to fill the fetch delay */
20610259SAndrew.Bardsley@arm.com    bool canEarlyIssue;
20710259SAndrew.Bardsley@arm.com
20813954Sgiacomo.gabrielli@arm.com    /** Flag controlling conditional execution of the instruction */
20913954Sgiacomo.gabrielli@arm.com    bool predicate;
21013954Sgiacomo.gabrielli@arm.com
21113954Sgiacomo.gabrielli@arm.com    /** Flag controlling conditional execution of the memory access associated
21213954Sgiacomo.gabrielli@arm.com     *  with the instruction (only meaningful for loads/stores) */
21313954Sgiacomo.gabrielli@arm.com    bool memAccPredicate;
21413954Sgiacomo.gabrielli@arm.com
21510259SAndrew.Bardsley@arm.com    /** execSeqNum of the latest inst on which this inst depends.
21610259SAndrew.Bardsley@arm.com     *  This can be used as a sanity check for dependency ordering
21710259SAndrew.Bardsley@arm.com     *  where slightly out of order execution is required (notably
21810259SAndrew.Bardsley@arm.com     *  initiateAcc for memory ops) */
21910259SAndrew.Bardsley@arm.com    InstSeqNum instToWaitFor;
22010259SAndrew.Bardsley@arm.com
22110259SAndrew.Bardsley@arm.com    /** Extra delay at the end of the pipeline */
22210259SAndrew.Bardsley@arm.com    Cycles extraCommitDelay;
22310259SAndrew.Bardsley@arm.com    TimingExpr *extraCommitDelayExpr;
22410259SAndrew.Bardsley@arm.com
22510259SAndrew.Bardsley@arm.com    /** Once issued, extraCommitDelay becomes minimumCommitCycle
22610259SAndrew.Bardsley@arm.com     *  to account for delay in absolute time */
22710259SAndrew.Bardsley@arm.com    Cycles minimumCommitCycle;
22810259SAndrew.Bardsley@arm.com
22910259SAndrew.Bardsley@arm.com    /** Flat register indices so that, when clearing the scoreboard, we
23010259SAndrew.Bardsley@arm.com     *  have the same register indices as when the instruction was marked
23110259SAndrew.Bardsley@arm.com     *  up */
23212104Snathanael.premillieu@arm.com    RegId flatDestRegIdx[TheISA::MaxInstDestRegs];
23310259SAndrew.Bardsley@arm.com
23410259SAndrew.Bardsley@arm.com  public:
23510259SAndrew.Bardsley@arm.com    MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) :
23610259SAndrew.Bardsley@arm.com        staticInst(NULL), id(id_), traceData(NULL),
23710259SAndrew.Bardsley@arm.com        pc(TheISA::PCState(0)), fault(fault_),
23810259SAndrew.Bardsley@arm.com        triedToPredict(false), predictedTaken(false),
23914105Sgabor.dozsa@arm.com        fuIndex(0), inLSQ(false), translationFault(NoFault),
24014105Sgabor.dozsa@arm.com        inStoreBuffer(false), canEarlyIssue(false), predicate(true),
24114105Sgabor.dozsa@arm.com        memAccPredicate(true), instToWaitFor(0), extraCommitDelay(Cycles(0)),
24212420Sgabeblack@google.com        extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0))
24310259SAndrew.Bardsley@arm.com    { }
24410259SAndrew.Bardsley@arm.com
24510259SAndrew.Bardsley@arm.com  public:
24610259SAndrew.Bardsley@arm.com    /** The BubbleIF interface. */
24710259SAndrew.Bardsley@arm.com    bool isBubble() const { return id.fetchSeqNum == 0; }
24810259SAndrew.Bardsley@arm.com
24910259SAndrew.Bardsley@arm.com    /** There is a single bubble inst */
25010259SAndrew.Bardsley@arm.com    static MinorDynInstPtr bubble() { return bubbleInst; }
25110259SAndrew.Bardsley@arm.com
25210259SAndrew.Bardsley@arm.com    /** Is this a fault rather than instruction */
25310259SAndrew.Bardsley@arm.com    bool isFault() const { return fault != NoFault; }
25410259SAndrew.Bardsley@arm.com
25510259SAndrew.Bardsley@arm.com    /** Is this a real instruction */
25610259SAndrew.Bardsley@arm.com    bool isInst() const { return !isBubble() && !isFault(); }
25710259SAndrew.Bardsley@arm.com
25810259SAndrew.Bardsley@arm.com    /** Is this a real mem ref instruction */
25910259SAndrew.Bardsley@arm.com    bool isMemRef() const { return isInst() && staticInst->isMemRef(); }
26010259SAndrew.Bardsley@arm.com
26110259SAndrew.Bardsley@arm.com    /** Is this an instruction that can be executed `for free' and
26210259SAndrew.Bardsley@arm.com     *  needn't spend time in an FU */
26310259SAndrew.Bardsley@arm.com    bool isNoCostInst() const;
26410259SAndrew.Bardsley@arm.com
26510259SAndrew.Bardsley@arm.com    /** Assuming this is not a fault, is this instruction either
26610259SAndrew.Bardsley@arm.com     *  a whole instruction or the last microop from a macroop */
26710259SAndrew.Bardsley@arm.com    bool isLastOpInInst() const;
26810259SAndrew.Bardsley@arm.com
26910259SAndrew.Bardsley@arm.com    /** Initialise the class */
27010259SAndrew.Bardsley@arm.com    static void init();
27110259SAndrew.Bardsley@arm.com
27210259SAndrew.Bardsley@arm.com    /** Print (possibly verbose) instruction information for
27310259SAndrew.Bardsley@arm.com     *  MinorTrace using the given Named object's name */
27410259SAndrew.Bardsley@arm.com    void minorTraceInst(const Named &named_object) const;
27510259SAndrew.Bardsley@arm.com
27610259SAndrew.Bardsley@arm.com    /** ReportIF interface */
27710259SAndrew.Bardsley@arm.com    void reportData(std::ostream &os) const;
27810259SAndrew.Bardsley@arm.com
27913954Sgiacomo.gabrielli@arm.com    bool readPredicate() const { return predicate; }
28013954Sgiacomo.gabrielli@arm.com
28113954Sgiacomo.gabrielli@arm.com    void setPredicate(bool val) { predicate = val; }
28213954Sgiacomo.gabrielli@arm.com
28313954Sgiacomo.gabrielli@arm.com    bool readMemAccPredicate() const { return memAccPredicate; }
28413954Sgiacomo.gabrielli@arm.com
28513954Sgiacomo.gabrielli@arm.com    void setMemAccPredicate(bool val) { memAccPredicate = val; }
28613954Sgiacomo.gabrielli@arm.com
28710259SAndrew.Bardsley@arm.com    ~MinorDynInst();
28810259SAndrew.Bardsley@arm.com};
28910259SAndrew.Bardsley@arm.com
29010259SAndrew.Bardsley@arm.com/** Print a summary of the instruction */
29110259SAndrew.Bardsley@arm.comstd::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
29210259SAndrew.Bardsley@arm.com
29310259SAndrew.Bardsley@arm.com}
29410259SAndrew.Bardsley@arm.com
29510259SAndrew.Bardsley@arm.com#endif /* __CPU_MINOR_DYN_INST_HH__ */
296