dyn_inst.hh revision 13954
17008SN/A/*
27008SN/A * Copyright (c) 2013-2014 ARM Limited
37008SN/A * All rights reserved
47008SN/A *
57008SN/A * The license below extends only to copyright in the software and shall
67008SN/A * not be construed as granting a license to any other intellectual
77008SN/A * property including but not limited to intellectual property relating
87008SN/A * to a hardware implementation of the functionality of the software
97008SN/A * licensed hereunder.  You may use the software subject to the license
107008SN/A * terms below provided that you ensure that this notice is replicated
117008SN/A * unmodified and in its entirety in all distributions of the software,
127008SN/A * modified or unmodified, in source code or in binary form.
137008SN/A *
147008SN/A * Redistribution and use in source and binary forms, with or without
157008SN/A * modification, are permitted provided that the following conditions are
167008SN/A * met: redistributions of source code must retain the above copyright
177008SN/A * notice, this list of conditions and the following disclaimer;
187008SN/A * redistributions in binary form must reproduce the above copyright
197008SN/A * notice, this list of conditions and the following disclaimer in the
207008SN/A * documentation and/or other materials provided with the distribution;
217008SN/A * neither the name of the copyright holders nor the names of its
227008SN/A * contributors may be used to endorse or promote products derived from
237008SN/A * this software without specific prior written permission.
247008SN/A *
257008SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
267008SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
277008SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
286145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
297039SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
307039SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
316145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210301Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
336145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
346145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
356145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
366145SN/A *
376145SN/A * Authors: Andrew Bardsley
386145SN/A */
396145SN/A
406145SN/A/**
416145SN/A * @file
426145SN/A *
436145SN/A *  The dynamic instruction and instruction/line id (sequence numbers)
446145SN/A *  definition for Minor.  A spirited attempt is made here to not carry too
456145SN/A *  much on this structure.
466145SN/A */
477039SN/A
487039SN/A#ifndef __CPU_MINOR_DYN_INST_HH__
497039SN/A#define __CPU_MINOR_DYN_INST_HH__
507039SN/A
517039SN/A#include <iostream>
526145SN/A
539505SN/A#include "base/refcnt.hh"
547039SN/A#include "cpu/minor/buffers.hh"
556145SN/A#include "cpu/inst_seq.hh"
567039SN/A#include "cpu/static_inst.hh"
577039SN/A#include "cpu/timing_expr.hh"
587039SN/A#include "sim/faults.hh"
597039SN/A
607039SN/Anamespace Minor
616145SN/A{
626145SN/A
636145SN/Aclass MinorDynInst;
646145SN/A
657039SN/A/** MinorDynInsts are currently reference counted. */
666145SN/Atypedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;
677039SN/A
687039SN/A/** Id for lines and instructions.  This includes all the relevant sequence
696145SN/A *  numbers and thread ids for all stages of execution. */
707039SN/Aclass InstId
717039SN/A{
726145SN/A  public:
737039SN/A    /** First sequence numbers to use in initialisation of the pipeline and
747039SN/A     *  to be expected on the first line/instruction issued */
757039SN/A    static const InstSeqNum firstStreamSeqNum = 1;
767039SN/A    static const InstSeqNum firstPredictionSeqNum = 1;
777039SN/A    static const InstSeqNum firstLineSeqNum = 1;
787039SN/A    static const InstSeqNum firstFetchSeqNum = 1;
797039SN/A    static const InstSeqNum firstExecSeqNum = 1;
807039SN/A
817039SN/A  public:
827039SN/A    /** The thread to which this line/instruction belongs */
837039SN/A    ThreadID threadId;
847039SN/A
857039SN/A    /** The 'stream' this instruction belongs to.  Streams are interrupted
867039SN/A     *  (and sequence numbers increased) when Execute finds it wants to
877039SN/A     *  change the stream of instructions due to a branch. */
887039SN/A    InstSeqNum streamSeqNum;
896145SN/A
906145SN/A    /** The predicted qualifier to stream, attached by Fetch2 as a
916145SN/A     *  consequence of branch prediction */
926145SN/A    InstSeqNum predictionSeqNum;
936145SN/A
947039SN/A    /** Line sequence number.  This is the sequence number of the fetched
957039SN/A     *  line from which this instruction was fetched */
966145SN/A    InstSeqNum lineSeqNum;
976145SN/A
987039SN/A    /** Fetch sequence number.  This is 0 for bubbles and an ascending
999505SN/A     *  sequence for the stream of all fetched instructions */
1007039SN/A    InstSeqNum fetchSeqNum;
1017039SN/A
1027039SN/A    /** 'Execute' sequence number.  These are assigned after micro-op
1036145SN/A     *  decomposition and form an ascending sequence (starting with 1) for
1047039SN/A     *  post-micro-op decomposed instructions. */
1057039SN/A    InstSeqNum execSeqNum;
1067039SN/A
1077039SN/A  public:
1087039SN/A    /** Very boring default constructor */
1097039SN/A    InstId(
1107039SN/A        ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0,
1117039SN/A        InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0,
1127039SN/A        InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) :
1137039SN/A        threadId(thread_id), streamSeqNum(stream_seq_num),
1147039SN/A        predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num),
1156145SN/A        fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num)
1166145SN/A    { }
1177039SN/A
1187039SN/A  public:
1197039SN/A    /* Equal if the thread and last set sequence number matches */
1207039SN/A    bool
1217039SN/A    operator== (const InstId &rhs)
1226145SN/A    {
1237039SN/A        /* If any of fetch and exec sequence number are not set
1247039SN/A         *  they need to be 0, so a straight comparison is still
1257039SN/A         *  fine */
1267039SN/A        bool ret = (threadId == rhs.threadId &&
1277039SN/A            lineSeqNum == rhs.lineSeqNum &&
1287039SN/A            fetchSeqNum == rhs.fetchSeqNum &&
1297039SN/A            execSeqNum == rhs.execSeqNum);
1307039SN/A
1316145SN/A        /* Stream and prediction *must* match if these are the same id */
1327039SN/A        if (ret) {
1337039SN/A            assert(streamSeqNum == rhs.streamSeqNum &&
1347039SN/A                predictionSeqNum == rhs.predictionSeqNum);
1356145SN/A        }
1366145SN/A
1377039SN/A        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    /** The instruction has been sent to the store buffer */
198    bool inStoreBuffer;
199
200    /** Can this instruction be executed out of order.  In this model,
201     *  this only happens with mem refs that need to be issued early
202     *  to allow other instructions to fill the fetch delay */
203    bool canEarlyIssue;
204
205    /** Flag controlling conditional execution of the instruction */
206    bool predicate;
207
208    /** Flag controlling conditional execution of the memory access associated
209     *  with the instruction (only meaningful for loads/stores) */
210    bool memAccPredicate;
211
212    /** execSeqNum of the latest inst on which this inst depends.
213     *  This can be used as a sanity check for dependency ordering
214     *  where slightly out of order execution is required (notably
215     *  initiateAcc for memory ops) */
216    InstSeqNum instToWaitFor;
217
218    /** Extra delay at the end of the pipeline */
219    Cycles extraCommitDelay;
220    TimingExpr *extraCommitDelayExpr;
221
222    /** Once issued, extraCommitDelay becomes minimumCommitCycle
223     *  to account for delay in absolute time */
224    Cycles minimumCommitCycle;
225
226    /** Flat register indices so that, when clearing the scoreboard, we
227     *  have the same register indices as when the instruction was marked
228     *  up */
229    RegId flatDestRegIdx[TheISA::MaxInstDestRegs];
230
231  public:
232    MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) :
233        staticInst(NULL), id(id_), traceData(NULL),
234        pc(TheISA::PCState(0)), fault(fault_),
235        triedToPredict(false), predictedTaken(false),
236        fuIndex(0), inLSQ(false), inStoreBuffer(false),
237        canEarlyIssue(false), predicate(true), memAccPredicate(true),
238        instToWaitFor(0), extraCommitDelay(Cycles(0)),
239        extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0))
240    { }
241
242  public:
243    /** The BubbleIF interface. */
244    bool isBubble() const { return id.fetchSeqNum == 0; }
245
246    /** There is a single bubble inst */
247    static MinorDynInstPtr bubble() { return bubbleInst; }
248
249    /** Is this a fault rather than instruction */
250    bool isFault() const { return fault != NoFault; }
251
252    /** Is this a real instruction */
253    bool isInst() const { return !isBubble() && !isFault(); }
254
255    /** Is this a real mem ref instruction */
256    bool isMemRef() const { return isInst() && staticInst->isMemRef(); }
257
258    /** Is this an instruction that can be executed `for free' and
259     *  needn't spend time in an FU */
260    bool isNoCostInst() const;
261
262    /** Assuming this is not a fault, is this instruction either
263     *  a whole instruction or the last microop from a macroop */
264    bool isLastOpInInst() const;
265
266    /** Initialise the class */
267    static void init();
268
269    /** Print (possibly verbose) instruction information for
270     *  MinorTrace using the given Named object's name */
271    void minorTraceInst(const Named &named_object) const;
272
273    /** ReportIF interface */
274    void reportData(std::ostream &os) const;
275
276    bool readPredicate() const { return predicate; }
277
278    void setPredicate(bool val) { predicate = val; }
279
280    bool readMemAccPredicate() const { return memAccPredicate; }
281
282    void setMemAccPredicate(bool val) { memAccPredicate = val; }
283
284    ~MinorDynInst();
285};
286
287/** Print a summary of the instruction */
288std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
289
290}
291
292#endif /* __CPU_MINOR_DYN_INST_HH__ */
293