dyn_inst.hh revision 10259
16157Snate@binkert.org/*
26157Snate@binkert.org * Copyright (c) 2013-2014 ARM Limited
36157Snate@binkert.org * All rights reserved
46157Snate@binkert.org *
56157Snate@binkert.org * The license below extends only to copyright in the software and shall
66157Snate@binkert.org * not be construed as granting a license to any other intellectual
76157Snate@binkert.org * property including but not limited to intellectual property relating
86157Snate@binkert.org * to a hardware implementation of the functionality of the software
96157Snate@binkert.org * licensed hereunder.  You may use the software subject to the license
106157Snate@binkert.org * terms below provided that you ensure that this notice is replicated
116157Snate@binkert.org * unmodified and in its entirety in all distributions of the software,
126157Snate@binkert.org * modified or unmodified, in source code or in binary form.
136157Snate@binkert.org *
146157Snate@binkert.org * Redistribution and use in source and binary forms, with or without
156157Snate@binkert.org * modification, are permitted provided that the following conditions are
166157Snate@binkert.org * met: redistributions of source code must retain the above copyright
176157Snate@binkert.org * notice, this list of conditions and the following disclaimer;
186157Snate@binkert.org * redistributions in binary form must reproduce the above copyright
196157Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
206157Snate@binkert.org * documentation and/or other materials provided with the distribution;
216157Snate@binkert.org * neither the name of the copyright holders nor the names of its
226157Snate@binkert.org * contributors may be used to endorse or promote products derived from
236157Snate@binkert.org * this software without specific prior written permission.
246157Snate@binkert.org *
256157Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
266157Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
276157Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
286157Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
296157Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
306157Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
316157Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
326157Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
336157Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
346157Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
356157Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
366157Snate@binkert.org *
376157Snate@binkert.org * Authors: Andrew Bardsley
386157Snate@binkert.org */
396157Snate@binkert.org
409850Sandreas.hansson@arm.com/**
417768SAli.Saidi@ARM.com * @file
427768SAli.Saidi@ARM.com *
438492Snilay@cs.wisc.edu *  The dynamic instruction and instruction/line id (sequence numbers)
446168Snate@binkert.org *  definition for Minor.  A spirited attempt is made here to not carry too
456168Snate@binkert.org *  much on this structure.
466157Snate@binkert.org */
476157Snate@binkert.org
486157Snate@binkert.org#ifndef __CPU_MINOR_DYN_INST_HH__
496157Snate@binkert.org#define __CPU_MINOR_DYN_INST_HH__
506157Snate@binkert.org
516157Snate@binkert.org#include <iostream>
526157Snate@binkert.org
536157Snate@binkert.org#include "base/refcnt.hh"
546157Snate@binkert.org#include "cpu/minor/buffers.hh"
556157Snate@binkert.org#include "cpu/inst_seq.hh"
566157Snate@binkert.org#include "cpu/static_inst.hh"
576157Snate@binkert.org#include "cpu/timing_expr.hh"
586157Snate@binkert.org#include "sim/faults.hh"
596157Snate@binkert.org
606157Snate@binkert.orgnamespace Minor
616157Snate@binkert.org{
626157Snate@binkert.org
636157Snate@binkert.orgclass MinorDynInst;
646157Snate@binkert.org
656157Snate@binkert.org/** MinorDynInsts are currently reference counted. */
666157Snate@binkert.orgtypedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;
676157Snate@binkert.org
686157Snate@binkert.org/** Id for lines and instructions.  This includes all the relevant sequence
696157Snate@binkert.org *  numbers and thread ids for all stages of execution. */
706157Snate@binkert.orgclass InstId
716157Snate@binkert.org{
726157Snate@binkert.org  public:
736157Snate@binkert.org    /** First sequence numbers to use in initialisation of the pipeline and
746157Snate@binkert.org     *  to be expected on the first line/instruction issued */
756157Snate@binkert.org    static const InstSeqNum firstStreamSeqNum = 1;
766157Snate@binkert.org    static const InstSeqNum firstPredictionSeqNum = 1;
776157Snate@binkert.org    static const InstSeqNum firstLineSeqNum = 1;
786157Snate@binkert.org    static const InstSeqNum firstFetchSeqNum = 1;
796157Snate@binkert.org    static const InstSeqNum firstExecSeqNum = 1;
806157Snate@binkert.org
816157Snate@binkert.org  public:
826157Snate@binkert.org    /** The thread to which this line/instruction belongs */
836157Snate@binkert.org    ThreadID threadId;
846157Snate@binkert.org
856157Snate@binkert.org    /** The 'stream' this instruction belongs to.  Streams are interrupted
866157Snate@binkert.org     *  (and sequence numbers increased) when Execute finds it wants to
876157Snate@binkert.org     *  change the stream of instructions due to a branch. */
886157Snate@binkert.org    InstSeqNum streamSeqNum;
898483Sgblack@eecs.umich.edu
908483Sgblack@eecs.umich.edu    /** The predicted qualifier to stream, attached by Fetch2 as a
916157Snate@binkert.org     *  consequence of branch prediction */
926882SBrad.Beckmann@amd.com    InstSeqNum predictionSeqNum;
936286Snate@binkert.org
946286Snate@binkert.org    /** Line sequence number.  This is the sequence number of the fetched
956286Snate@binkert.org     *  line from which this instruction was fetched */
966286Snate@binkert.org    InstSeqNum lineSeqNum;
978092Snilay@cs.wisc.edu
986286Snate@binkert.org    /** Fetch sequence number.  This is 0 for bubbles and an ascending
996286Snate@binkert.org     *  sequence for the stream of all fetched instructions */
1006157Snate@binkert.org    InstSeqNum fetchSeqNum;
1016157Snate@binkert.org
1026157Snate@binkert.org    /** 'Execute' sequence number.  These are assigned after micro-op
1036157Snate@binkert.org     *  decomposition and form an ascending sequence (starting with 1) for
1046157Snate@binkert.org     *  post-micro-op decomposed instructions. */
1056286Snate@binkert.org    InstSeqNum execSeqNum;
1069363Snilay@cs.wisc.edu
1076157Snate@binkert.org  public:
1086286Snate@binkert.org    /** Very boring default constructor */
1096157Snate@binkert.org    InstId(
1106157Snate@binkert.org        ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0,
1116157Snate@binkert.org        InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0,
1128191SLisa.Hsu@amd.com        InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) :
1136157Snate@binkert.org        threadId(thread_id), streamSeqNum(stream_seq_num),
1146797SBrad.Beckmann@amd.com        predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num),
1156157Snate@binkert.org        fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num)
1166157Snate@binkert.org    { }
1176157Snate@binkert.org
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    /** 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    /** execSeqNum of the latest inst on which this inst depends.
206     *  This can be used as a sanity check for dependency ordering
207     *  where slightly out of order execution is required (notably
208     *  initiateAcc for memory ops) */
209    InstSeqNum instToWaitFor;
210
211    /** Extra delay at the end of the pipeline */
212    Cycles extraCommitDelay;
213    TimingExpr *extraCommitDelayExpr;
214
215    /** Once issued, extraCommitDelay becomes minimumCommitCycle
216     *  to account for delay in absolute time */
217    Cycles minimumCommitCycle;
218
219    /** Flat register indices so that, when clearing the scoreboard, we
220     *  have the same register indices as when the instruction was marked
221     *  up */
222    TheISA::RegIndex flatDestRegIdx[TheISA::MaxInstDestRegs];
223
224    /** Effective address as set by ExecContext::setEA */
225    Addr ea;
226
227  public:
228    MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) :
229        staticInst(NULL), id(id_), traceData(NULL),
230        pc(TheISA::PCState(0)), fault(fault_),
231        triedToPredict(false), predictedTaken(false),
232        fuIndex(0), inLSQ(false), inStoreBuffer(false),
233        canEarlyIssue(false),
234        instToWaitFor(0), extraCommitDelay(Cycles(0)),
235        extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0)),
236        ea(0)
237    { }
238
239  public:
240    /** The BubbleIF interface. */
241    bool isBubble() const { return id.fetchSeqNum == 0; }
242
243    /** There is a single bubble inst */
244    static MinorDynInstPtr bubble() { return bubbleInst; }
245
246    /** Is this a fault rather than instruction */
247    bool isFault() const { return fault != NoFault; }
248
249    /** Is this a real instruction */
250    bool isInst() const { return !isBubble() && !isFault(); }
251
252    /** Is this a real mem ref instruction */
253    bool isMemRef() const { return isInst() && staticInst->isMemRef(); }
254
255    /** Is this an instruction that can be executed `for free' and
256     *  needn't spend time in an FU */
257    bool isNoCostInst() const;
258
259    /** Assuming this is not a fault, is this instruction either
260     *  a whole instruction or the last microop from a macroop */
261    bool isLastOpInInst() const;
262
263    /** Initialise the class */
264    static void init();
265
266    /** Print (possibly verbose) instruction information for
267     *  MinorTrace using the given Named object's name */
268    void minorTraceInst(const Named &named_object) const;
269
270    /** ReportIF interface */
271    void reportData(std::ostream &os) const;
272
273    ~MinorDynInst();
274};
275
276/** Print a summary of the instruction */
277std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
278
279}
280
281#endif /* __CPU_MINOR_DYN_INST_HH__ */
282