dyn_inst.hh revision 14105:969b4e972b07
16657Snate@binkert.org/*
26657Snate@binkert.org * Copyright (c) 2013-2014,2018 ARM Limited
36657Snate@binkert.org * All rights reserved
46657Snate@binkert.org *
56657Snate@binkert.org * The license below extends only to copyright in the software and shall
66657Snate@binkert.org * not be construed as granting a license to any other intellectual
76657Snate@binkert.org * property including but not limited to intellectual property relating
86657Snate@binkert.org * to a hardware implementation of the functionality of the software
96657Snate@binkert.org * licensed hereunder.  You may use the software subject to the license
106657Snate@binkert.org * terms below provided that you ensure that this notice is replicated
116657Snate@binkert.org * unmodified and in its entirety in all distributions of the software,
126657Snate@binkert.org * modified or unmodified, in source code or in binary form.
136657Snate@binkert.org *
146657Snate@binkert.org * Redistribution and use in source and binary forms, with or without
156657Snate@binkert.org * modification, are permitted provided that the following conditions are
166657Snate@binkert.org * met: redistributions of source code must retain the above copyright
176657Snate@binkert.org * notice, this list of conditions and the following disclaimer;
186657Snate@binkert.org * redistributions in binary form must reproduce the above copyright
196657Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
206657Snate@binkert.org * documentation and/or other materials provided with the distribution;
216657Snate@binkert.org * neither the name of the copyright holders nor the names of its
226657Snate@binkert.org * contributors may be used to endorse or promote products derived from
236657Snate@binkert.org * this software without specific prior written permission.
246657Snate@binkert.org *
256657Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
266657Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
276657Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
286657Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
296657Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
306657Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
316657Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210984SBrad.Beckmann@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3311049Snilay@cs.wisc.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
346657Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
356657Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
366657Snate@binkert.org *
3711049Snilay@cs.wisc.edu * Authors: Andrew Bardsley
386657Snate@binkert.org */
396657Snate@binkert.org
408337Snilay@cs.wisc.edu/**
4110984SBrad.Beckmann@amd.com * @file
429298Snilay@cs.wisc.edu *
436657Snate@binkert.org *  The dynamic instruction and instruction/line id (sequence numbers)
446657Snate@binkert.org *  definition for Minor.  A spirited attempt is made here to not carry too
456657Snate@binkert.org *  much on this structure.
466657Snate@binkert.org */
476657Snate@binkert.org
486657Snate@binkert.org#ifndef __CPU_MINOR_DYN_INST_HH__
496657Snate@binkert.org#define __CPU_MINOR_DYN_INST_HH__
506657Snate@binkert.org
516657Snate@binkert.org#include <iostream>
526657Snate@binkert.org
536657Snate@binkert.org#include "base/refcnt.hh"
546657Snate@binkert.org#include "cpu/minor/buffers.hh"
556657Snate@binkert.org#include "cpu/inst_seq.hh"
567839Snilay@cs.wisc.edu#include "cpu/static_inst.hh"
577839Snilay@cs.wisc.edu#include "cpu/timing_expr.hh"
586657Snate@binkert.org#include "sim/faults.hh"
5910984SBrad.Beckmann@amd.com
6011049Snilay@cs.wisc.edunamespace Minor
616657Snate@binkert.org{
629219Spower.jg@gmail.com
638478Snilay@cs.wisc.educlass MinorDynInst;
648478Snilay@cs.wisc.edu
6511062Snilay@cs.wisc.edu/** MinorDynInsts are currently reference counted. */
6611062Snilay@cs.wisc.edutypedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;
6711062Snilay@cs.wisc.edu
6811062Snilay@cs.wisc.edu/** Id for lines and instructions.  This includes all the relevant sequence
6911062Snilay@cs.wisc.edu *  numbers and thread ids for all stages of execution. */
7011062Snilay@cs.wisc.educlass InstId
7111062Snilay@cs.wisc.edu{
7211062Snilay@cs.wisc.edu  public:
7311062Snilay@cs.wisc.edu    /** First sequence numbers to use in initialisation of the pipeline and
7411062Snilay@cs.wisc.edu     *  to be expected on the first line/instruction issued */
7511062Snilay@cs.wisc.edu    static const InstSeqNum firstStreamSeqNum = 1;
7611062Snilay@cs.wisc.edu    static const InstSeqNum firstPredictionSeqNum = 1;
7711062Snilay@cs.wisc.edu    static const InstSeqNum firstLineSeqNum = 1;
7811062Snilay@cs.wisc.edu    static const InstSeqNum firstFetchSeqNum = 1;
7911062Snilay@cs.wisc.edu    static const InstSeqNum firstExecSeqNum = 1;
8011062Snilay@cs.wisc.edu
8111062Snilay@cs.wisc.edu  public:
8211062Snilay@cs.wisc.edu    /** The thread to which this line/instruction belongs */
8311062Snilay@cs.wisc.edu    ThreadID threadId;
8411062Snilay@cs.wisc.edu
8511062Snilay@cs.wisc.edu    /** The 'stream' this instruction belongs to.  Streams are interrupted
868478Snilay@cs.wisc.edu     *  (and sequence numbers increased) when Execute finds it wants to
876657Snate@binkert.org     *  change the stream of instructions due to a branch. */
886657Snate@binkert.org    InstSeqNum streamSeqNum;
898478Snilay@cs.wisc.edu
906657Snate@binkert.org    /** The predicted qualifier to stream, attached by Fetch2 as a
916999Snate@binkert.org     *  consequence of branch prediction */
926657Snate@binkert.org    InstSeqNum predictionSeqNum;
936657Snate@binkert.org
9411049Snilay@cs.wisc.edu    /** Line sequence number.  This is the sequence number of the fetched
9511030Snilay@cs.wisc.edu     *  line from which this instruction was fetched */
966657Snate@binkert.org    InstSeqNum lineSeqNum;
976657Snate@binkert.org
987839Snilay@cs.wisc.edu    /** Fetch sequence number.  This is 0 for bubbles and an ascending
997839Snilay@cs.wisc.edu     *  sequence for the stream of all fetched instructions */
1006657Snate@binkert.org    InstSeqNum fetchSeqNum;
10111049Snilay@cs.wisc.edu
1026657Snate@binkert.org    /** 'Execute' sequence number.  These are assigned after micro-op
1036657Snate@binkert.org     *  decomposition and form an ascending sequence (starting with 1) for
1047007Snate@binkert.org     *  post-micro-op decomposed instructions. */
10510984SBrad.Beckmann@amd.com    InstSeqNum execSeqNum;
1066657Snate@binkert.org
1076657Snate@binkert.org  public:
1086657Snate@binkert.org    /** Very boring default constructor */
1096657Snate@binkert.org    InstId(
1108478Snilay@cs.wisc.edu        ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0,
1116657Snate@binkert.org        InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0,
1126657Snate@binkert.org        InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) :
113        threadId(thread_id), streamSeqNum(stream_seq_num),
114        predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num),
115        fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num)
116    { }
117
118  public:
119    /* Equal if the thread and last set sequence number matches */
120    bool
121    operator== (const InstId &rhs)
122    {
123        /* If any of fetch and exec sequence number are not set
124         *  they need to be 0, so a straight comparison is still
125         *  fine */
126        bool ret = (threadId == rhs.threadId &&
127            lineSeqNum == rhs.lineSeqNum &&
128            fetchSeqNum == rhs.fetchSeqNum &&
129            execSeqNum == rhs.execSeqNum);
130
131        /* Stream and prediction *must* match if these are the same id */
132        if (ret) {
133            assert(streamSeqNum == rhs.streamSeqNum &&
134                predictionSeqNum == rhs.predictionSeqNum);
135        }
136
137        return ret;
138    }
139};
140
141/** Print this id in the usual slash-separated format expected by
142 *  MinorTrace */
143std::ostream &operator <<(std::ostream &os, const InstId &id);
144
145class MinorDynInst;
146
147/** Print a short reference to this instruction.  '-' for a bubble and a
148 *  series of '/' separated sequence numbers for other instructions.  The
149 *  sequence numbers will be in the order: stream, prediction, line, fetch,
150 *  exec with exec absent if it is 0.  This is used by MinorTrace. */
151std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
152
153/** Dynamic instruction for Minor.
154 *  MinorDynInst implements the BubbleIF interface
155 *  Has two separate notions of sequence number for pre/post-micro-op
156 *  decomposition: fetchSeqNum and execSeqNum */
157class MinorDynInst : public RefCounted
158{
159  private:
160    /** A prototypical bubble instruction.  You must call MinorDynInst::init
161     *  to initialise this */
162    static MinorDynInstPtr bubbleInst;
163
164  public:
165    StaticInstPtr staticInst;
166
167    InstId id;
168
169    /** Trace information for this instruction's execution */
170    Trace::InstRecord *traceData;
171
172    /** The fetch address of this instruction */
173    TheISA::PCState pc;
174
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