dyn_inst.hh revision 14105:969b4e972b07
12036SN/A/*
22036SN/A * Copyright (c) 2013-2014,2018 ARM Limited
32036SN/A * All rights reserved
42036SN/A *
52036SN/A * The license below extends only to copyright in the software and shall
62036SN/A * not be construed as granting a license to any other intellectual
72036SN/A * property including but not limited to intellectual property relating
82036SN/A * to a hardware implementation of the functionality of the software
92036SN/A * licensed hereunder.  You may use the software subject to the license
102036SN/A * terms below provided that you ensure that this notice is replicated
112036SN/A * unmodified and in its entirety in all distributions of the software,
122036SN/A * modified or unmodified, in source code or in binary form.
132036SN/A *
142036SN/A * Redistribution and use in source and binary forms, with or without
152036SN/A * modification, are permitted provided that the following conditions are
162036SN/A * met: redistributions of source code must retain the above copyright
172036SN/A * notice, this list of conditions and the following disclaimer;
182036SN/A * redistributions in binary form must reproduce the above copyright
192036SN/A * notice, this list of conditions and the following disclaimer in the
202036SN/A * documentation and/or other materials provided with the distribution;
212036SN/A * neither the name of the copyright holders nor the names of its
222036SN/A * contributors may be used to endorse or promote products derived from
232036SN/A * this software without specific prior written permission.
242036SN/A *
252036SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262036SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282772Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292772Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302036SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312036SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322036SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332036SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342036SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352036SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362036SN/A *
372036SN/A * Authors: Andrew Bardsley
382036SN/A */
392036SN/A
402036SN/A/**
412036SN/A * @file
422036SN/A *
432036SN/A *  The dynamic instruction and instruction/line id (sequence numbers)
442565SN/A *  definition for Minor.  A spirited attempt is made here to not carry too
452565SN/A *  much on this structure.
462565SN/A */
472565SN/A
482036SN/A#ifndef __CPU_MINOR_DYN_INST_HH__
492036SN/A#define __CPU_MINOR_DYN_INST_HH__
502036SN/A
512036SN/A#include <iostream>
522778Ssaidi@eecs.umich.edu
532778Ssaidi@eecs.umich.edu#include "base/refcnt.hh"
542778Ssaidi@eecs.umich.edu#include "cpu/minor/buffers.hh"
552778Ssaidi@eecs.umich.edu#include "cpu/inst_seq.hh"
562036SN/A#include "cpu/static_inst.hh"
572036SN/A#include "cpu/timing_expr.hh"
582036SN/A#include "sim/faults.hh"
592036SN/A
602036SN/Anamespace Minor
612565SN/A{
622565SN/A
632778Ssaidi@eecs.umich.educlass MinorDynInst;
642778Ssaidi@eecs.umich.edu
652565SN/A/** MinorDynInsts are currently reference counted. */
662036SN/Atypedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;
672036SN/A
682036SN/A/** Id for lines and instructions.  This includes all the relevant sequence
692036SN/A *  numbers and thread ids for all stages of execution. */
702036SN/Aclass InstId
712036SN/A{
722036SN/A  public:
732036SN/A    /** First sequence numbers to use in initialisation of the pipeline and
742565SN/A     *  to be expected on the first line/instruction issued */
752036SN/A    static const InstSeqNum firstStreamSeqNum = 1;
762036SN/A    static const InstSeqNum firstPredictionSeqNum = 1;
772036SN/A    static const InstSeqNum firstLineSeqNum = 1;
782036SN/A    static const InstSeqNum firstFetchSeqNum = 1;
792036SN/A    static const InstSeqNum firstExecSeqNum = 1;
802565SN/A
812565SN/A  public:
822778Ssaidi@eecs.umich.edu    /** The thread to which this line/instruction belongs */
832778Ssaidi@eecs.umich.edu    ThreadID threadId;
842565SN/A
852036SN/A    /** The 'stream' this instruction belongs to.  Streams are interrupted
862036SN/A     *  (and sequence numbers increased) when Execute finds it wants to
872036SN/A     *  change the stream of instructions due to a branch. */
882565SN/A    InstSeqNum streamSeqNum;
892036SN/A
902036SN/A    /** The predicted qualifier to stream, attached by Fetch2 as a
912036SN/A     *  consequence of branch prediction */
922036SN/A    InstSeqNum predictionSeqNum;
932036SN/A
942565SN/A    /** Line sequence number.  This is the sequence number of the fetched
952565SN/A     *  line from which this instruction was fetched */
962778Ssaidi@eecs.umich.edu    InstSeqNum lineSeqNum;
972778Ssaidi@eecs.umich.edu
982565SN/A    /** Fetch sequence number.  This is 0 for bubbles and an ascending
992036SN/A     *  sequence for the stream of all fetched instructions */
1002036SN/A    InstSeqNum fetchSeqNum;
1012565SN/A
1022036SN/A    /** 'Execute' sequence number.  These are assigned after micro-op
1032036SN/A     *  decomposition and form an ascending sequence (starting with 1) for
1042764Sstever@eecs.umich.edu     *  post-micro-op decomposed instructions. */
1052764Sstever@eecs.umich.edu    InstSeqNum execSeqNum;
1062764Sstever@eecs.umich.edu
1072764Sstever@eecs.umich.edu  public:
1082764Sstever@eecs.umich.edu    /** Very boring default constructor */
1092764Sstever@eecs.umich.edu    InstId(
1102764Sstever@eecs.umich.edu        ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0,
1112764Sstever@eecs.umich.edu        InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0,
1122764Sstever@eecs.umich.edu        InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) :
1132764Sstever@eecs.umich.edu        threadId(thread_id), streamSeqNum(stream_seq_num),
1142764Sstever@eecs.umich.edu        predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num),
1152764Sstever@eecs.umich.edu        fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num)
1162764Sstever@eecs.umich.edu    { }
1172764Sstever@eecs.umich.edu
1182764Sstever@eecs.umich.edu  public:
1192764Sstever@eecs.umich.edu    /* Equal if the thread and last set sequence number matches */
1202764Sstever@eecs.umich.edu    bool
1212036SN/A    operator== (const InstId &rhs)
1222036SN/A    {
1232036SN/A        /* If any of fetch and exec sequence number are not set
1242036SN/A         *  they need to be 0, so a straight comparison is still
1252036SN/A         *  fine */
1262036SN/A        bool ret = (threadId == rhs.threadId &&
1272036SN/A            lineSeqNum == rhs.lineSeqNum &&
1282036SN/A            fetchSeqNum == rhs.fetchSeqNum &&
1292036SN/A            execSeqNum == rhs.execSeqNum);
1302036SN/A
1312036SN/A        /* Stream and prediction *must* match if these are the same id */
1322036SN/A        if (ret) {
1332036SN/A            assert(streamSeqNum == rhs.streamSeqNum &&
1342036SN/A                predictionSeqNum == rhs.predictionSeqNum);
1352036SN/A        }
1362036SN/A
1372036SN/A        return ret;
1382036SN/A    }
1392036SN/A};
1402036SN/A
1412036SN/A/** Print this id in the usual slash-separated format expected by
1422036SN/A *  MinorTrace */
1432036SN/Astd::ostream &operator <<(std::ostream &os, const InstId &id);
1442036SN/A
1452036SN/Aclass MinorDynInst;
1462036SN/A
1472036SN/A/** Print a short reference to this instruction.  '-' for a bubble and a
1482036SN/A *  series of '/' separated sequence numbers for other instructions.  The
1492036SN/A *  sequence numbers will be in the order: stream, prediction, line, fetch,
1502036SN/A *  exec with exec absent if it is 0.  This is used by MinorTrace. */
1512036SN/Astd::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
1522036SN/A
1532036SN/A/** Dynamic instruction for Minor.
1542036SN/A *  MinorDynInst implements the BubbleIF interface
1552036SN/A *  Has two separate notions of sequence number for pre/post-micro-op
1562036SN/A *  decomposition: fetchSeqNum and execSeqNum */
1572036SN/Aclass MinorDynInst : public RefCounted
1582036SN/A{
1592036SN/A  private:
1602036SN/A    /** A prototypical bubble instruction.  You must call MinorDynInst::init
1612036SN/A     *  to initialise this */
1622036SN/A    static MinorDynInstPtr bubbleInst;
1632036SN/A
1642036SN/A  public:
1652036SN/A    StaticInstPtr staticInst;
1662036SN/A
1672036SN/A    InstId id;
1682036SN/A
1692036SN/A    /** Trace information for this instruction's execution */
1702036SN/A    Trace::InstRecord *traceData;
1712036SN/A
1722036SN/A    /** The fetch address of this instruction */
1732036SN/A    TheISA::PCState pc;
1742036SN/A
175    /** This is actually a fault masquerading as an instruction */
176    Fault fault;
177
178    /** Tried to predict the destination of this inst (if a control
179     *  instruction or a sys call) */
180    bool triedToPredict;
181
182    /** This instruction was predicted to change control flow and
183     *  the following instructions will have a newer predictionSeqNum */
184    bool predictedTaken;
185
186    /** Predicted branch target */
187    TheISA::PCState predictedTarget;
188
189    /** Fields only set during execution */
190
191    /** FU this instruction is issued to */
192    unsigned int fuIndex;
193
194    /** This instruction is in the LSQ, not a functional unit */
195    bool inLSQ;
196
197    /** Translation fault in case of a mem ref */
198    Fault translationFault;
199
200    /** The instruction has been sent to the store buffer */
201    bool inStoreBuffer;
202
203    /** Can this instruction be executed out of order.  In this model,
204     *  this only happens with mem refs that need to be issued early
205     *  to allow other instructions to fill the fetch delay */
206    bool canEarlyIssue;
207
208    /** Flag controlling conditional execution of the instruction */
209    bool predicate;
210
211    /** Flag controlling conditional execution of the memory access associated
212     *  with the instruction (only meaningful for loads/stores) */
213    bool memAccPredicate;
214
215    /** execSeqNum of the latest inst on which this inst depends.
216     *  This can be used as a sanity check for dependency ordering
217     *  where slightly out of order execution is required (notably
218     *  initiateAcc for memory ops) */
219    InstSeqNum instToWaitFor;
220
221    /** Extra delay at the end of the pipeline */
222    Cycles extraCommitDelay;
223    TimingExpr *extraCommitDelayExpr;
224
225    /** Once issued, extraCommitDelay becomes minimumCommitCycle
226     *  to account for delay in absolute time */
227    Cycles minimumCommitCycle;
228
229    /** Flat register indices so that, when clearing the scoreboard, we
230     *  have the same register indices as when the instruction was marked
231     *  up */
232    RegId flatDestRegIdx[TheISA::MaxInstDestRegs];
233
234  public:
235    MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) :
236        staticInst(NULL), id(id_), traceData(NULL),
237        pc(TheISA::PCState(0)), fault(fault_),
238        triedToPredict(false), predictedTaken(false),
239        fuIndex(0), inLSQ(false), translationFault(NoFault),
240        inStoreBuffer(false), canEarlyIssue(false), predicate(true),
241        memAccPredicate(true), instToWaitFor(0), extraCommitDelay(Cycles(0)),
242        extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0))
243    { }
244
245  public:
246    /** The BubbleIF interface. */
247    bool isBubble() const { return id.fetchSeqNum == 0; }
248
249    /** There is a single bubble inst */
250    static MinorDynInstPtr bubble() { return bubbleInst; }
251
252    /** Is this a fault rather than instruction */
253    bool isFault() const { return fault != NoFault; }
254
255    /** Is this a real instruction */
256    bool isInst() const { return !isBubble() && !isFault(); }
257
258    /** Is this a real mem ref instruction */
259    bool isMemRef() const { return isInst() && staticInst->isMemRef(); }
260
261    /** Is this an instruction that can be executed `for free' and
262     *  needn't spend time in an FU */
263    bool isNoCostInst() const;
264
265    /** Assuming this is not a fault, is this instruction either
266     *  a whole instruction or the last microop from a macroop */
267    bool isLastOpInInst() const;
268
269    /** Initialise the class */
270    static void init();
271
272    /** Print (possibly verbose) instruction information for
273     *  MinorTrace using the given Named object's name */
274    void minorTraceInst(const Named &named_object) const;
275
276    /** ReportIF interface */
277    void reportData(std::ostream &os) const;
278
279    bool readPredicate() const { return predicate; }
280
281    void setPredicate(bool val) { predicate = val; }
282
283    bool readMemAccPredicate() const { return memAccPredicate; }
284
285    void setMemAccPredicate(bool val) { memAccPredicate = val; }
286
287    ~MinorDynInst();
288};
289
290/** Print a summary of the instruction */
291std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
292
293}
294
295#endif /* __CPU_MINOR_DYN_INST_HH__ */
296