2 * Copyright (c) 2013-2014,2018 ARM Limited
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 * The dynamic instruction and instruction/line id (sequence numbers)
42 * definition for Minor. A spirited attempt is made here to not carry too
43 * much on this structure.
46 #ifndef __CPU_MINOR_DYN_INST_HH__
47 #define __CPU_MINOR_DYN_INST_HH__
51 #include "base/refcnt.hh"
52 #include "cpu/minor/buffers.hh"
53 #include "cpu/inst_seq.hh"
54 #include "cpu/static_inst.hh"
55 #include "cpu/timing_expr.hh"
56 #include "sim/faults.hh"
63 /** MinorDynInsts are currently reference counted. */
64 typedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;
66 /** Id for lines and instructions. This includes all the relevant sequence
67 * numbers and thread ids for all stages of execution. */
71 /** First sequence numbers to use in initialisation of the pipeline and
72 * to be expected on the first line/instruction issued */
73 static const InstSeqNum firstStreamSeqNum = 1;
74 static const InstSeqNum firstPredictionSeqNum = 1;
75 static const InstSeqNum firstLineSeqNum = 1;
76 static const InstSeqNum firstFetchSeqNum = 1;
77 static const InstSeqNum firstExecSeqNum = 1;
80 /** The thread to which this line/instruction belongs */
83 /** The 'stream' this instruction belongs to. Streams are interrupted
84 * (and sequence numbers increased) when Execute finds it wants to
85 * change the stream of instructions due to a branch. */
86 InstSeqNum streamSeqNum;
88 /** The predicted qualifier to stream, attached by Fetch2 as a
89 * consequence of branch prediction */
90 InstSeqNum predictionSeqNum;
92 /** Line sequence number. This is the sequence number of the fetched
93 * line from which this instruction was fetched */
94 InstSeqNum lineSeqNum;
96 /** Fetch sequence number. This is 0 for bubbles and an ascending
97 * sequence for the stream of all fetched instructions */
98 InstSeqNum fetchSeqNum;
100 /** 'Execute' sequence number. These are assigned after micro-op
101 * decomposition and form an ascending sequence (starting with 1) for
102 * post-micro-op decomposed instructions. */
103 InstSeqNum execSeqNum;
106 /** Very boring default constructor */
108 ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0,
109 InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0,
110 InstSeqNum fetch_seq_num = 0, InstSeqNum exec_seq_num = 0) :
111 threadId(thread_id), streamSeqNum(stream_seq_num),
112 predictionSeqNum(prediction_seq_num), lineSeqNum(line_seq_num),
113 fetchSeqNum(fetch_seq_num), execSeqNum(exec_seq_num)
117 /* Equal if the thread and last set sequence number matches */
119 operator== (const InstId &rhs)
121 /* If any of fetch and exec sequence number are not set
122 * they need to be 0, so a straight comparison is still
124 bool ret = (threadId == rhs.threadId &&
125 lineSeqNum == rhs.lineSeqNum &&
126 fetchSeqNum == rhs.fetchSeqNum &&
127 execSeqNum == rhs.execSeqNum);
129 /* Stream and prediction *must* match if these are the same id */
131 assert(streamSeqNum == rhs.streamSeqNum &&
132 predictionSeqNum == rhs.predictionSeqNum);
139 /** Print this id in the usual slash-separated format expected by
141 std::ostream &operator <<(std::ostream &os, const InstId &id);
145 /** Print a short reference to this instruction. '-' for a bubble and a
146 * series of '/' separated sequence numbers for other instructions. The
147 * sequence numbers will be in the order: stream, prediction, line, fetch,
148 * exec with exec absent if it is 0. This is used by MinorTrace. */
149 std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
151 /** Dynamic instruction for Minor.
152 * MinorDynInst implements the BubbleIF interface
153 * Has two separate notions of sequence number for pre/post-micro-op
154 * decomposition: fetchSeqNum and execSeqNum */
155 class MinorDynInst : public RefCounted
158 /** A prototypical bubble instruction. You must call MinorDynInst::init
159 * to initialise this */
160 static MinorDynInstPtr bubbleInst;
163 StaticInstPtr staticInst;
167 /** Trace information for this instruction's execution */
168 Trace::InstRecord *traceData;
170 /** The fetch address of this instruction */
173 /** This is actually a fault masquerading as an instruction */
176 /** Tried to predict the destination of this inst (if a control
177 * instruction or a sys call) */
180 /** This instruction was predicted to change control flow and
181 * the following instructions will have a newer predictionSeqNum */
184 /** Predicted branch target */
185 TheISA::PCState predictedTarget;
187 /** Fields only set during execution */
189 /** FU this instruction is issued to */
190 unsigned int fuIndex;
192 /** This instruction is in the LSQ, not a functional unit */
195 /** Translation fault in case of a mem ref */
196 Fault translationFault;
198 /** The instruction has been sent to the store buffer */
201 /** Can this instruction be executed out of order. In this model,
202 * this only happens with mem refs that need to be issued early
203 * to allow other instructions to fill the fetch delay */
206 /** Flag controlling conditional execution of the instruction */
209 /** Flag controlling conditional execution of the memory access associated
210 * with the instruction (only meaningful for loads/stores) */
211 bool memAccPredicate;
213 /** execSeqNum of the latest inst on which this inst depends.
214 * This can be used as a sanity check for dependency ordering
215 * where slightly out of order execution is required (notably
216 * initiateAcc for memory ops) */
217 InstSeqNum instToWaitFor;
219 /** Extra delay at the end of the pipeline */
220 Cycles extraCommitDelay;
221 TimingExpr *extraCommitDelayExpr;
223 /** Once issued, extraCommitDelay becomes minimumCommitCycle
224 * to account for delay in absolute time */
225 Cycles minimumCommitCycle;
227 /** Flat register indices so that, when clearing the scoreboard, we
228 * have the same register indices as when the instruction was marked
230 RegId flatDestRegIdx[TheISA::MaxInstDestRegs];
233 MinorDynInst(InstId id_ = InstId(), Fault fault_ = NoFault) :
234 staticInst(NULL), id(id_), traceData(NULL),
235 pc(TheISA::PCState(0)), fault(fault_),
236 triedToPredict(false), predictedTaken(false),
237 fuIndex(0), inLSQ(false), translationFault(NoFault),
238 inStoreBuffer(false), canEarlyIssue(false), predicate(true),
239 memAccPredicate(true), instToWaitFor(0), extraCommitDelay(Cycles(0)),
240 extraCommitDelayExpr(NULL), minimumCommitCycle(Cycles(0))
244 /** The BubbleIF interface. */
245 bool isBubble() const { return id.fetchSeqNum == 0; }
247 /** There is a single bubble inst */
248 static MinorDynInstPtr bubble() { return bubbleInst; }
250 /** Is this a fault rather than instruction */
251 bool isFault() const { return fault != NoFault; }
253 /** Is this a real instruction */
254 bool isInst() const { return !isBubble() && !isFault(); }
256 /** Is this a real mem ref instruction */
257 bool isMemRef() const { return isInst() && staticInst->isMemRef(); }
259 /** Is this an instruction that can be executed `for free' and
260 * needn't spend time in an FU */
261 bool isNoCostInst() const;
263 /** Assuming this is not a fault, is this instruction either
264 * a whole instruction or the last microop from a macroop */
265 bool isLastOpInInst() const;
267 /** Initialise the class */
270 /** Print (possibly verbose) instruction information for
271 * MinorTrace using the given Named object's name */
272 void minorTraceInst(const Named &named_object) const;
274 /** ReportIF interface */
275 void reportData(std::ostream &os) const;
277 bool readPredicate() const { return predicate; }
279 void setPredicate(bool val) { predicate = val; }
281 bool readMemAccPredicate() const { return memAccPredicate; }
283 void setMemAccPredicate(bool val) { memAccPredicate = val; }
288 /** Print a summary of the instruction */
289 std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
293 #endif /* __CPU_MINOR_DYN_INST_HH__ */