misc: Merged m5ops_base hotfix into develop
[gem5.git] / src / cpu / minor / dyn_inst.hh
1 /*
2 * Copyright (c) 2013-2014,2018 ARM Limited
3 * All rights reserved
4 *
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.
13 *
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.
24 *
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.
36 */
37
38 /**
39 * @file
40 *
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.
44 */
45
46 #ifndef __CPU_MINOR_DYN_INST_HH__
47 #define __CPU_MINOR_DYN_INST_HH__
48
49 #include <iostream>
50
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"
57
58 namespace Minor
59 {
60
61 class MinorDynInst;
62
63 /** MinorDynInsts are currently reference counted. */
64 typedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;
65
66 /** Id for lines and instructions. This includes all the relevant sequence
67 * numbers and thread ids for all stages of execution. */
68 class InstId
69 {
70 public:
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;
78
79 public:
80 /** The thread to which this line/instruction belongs */
81 ThreadID threadId;
82
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;
87
88 /** The predicted qualifier to stream, attached by Fetch2 as a
89 * consequence of branch prediction */
90 InstSeqNum predictionSeqNum;
91
92 /** Line sequence number. This is the sequence number of the fetched
93 * line from which this instruction was fetched */
94 InstSeqNum lineSeqNum;
95
96 /** Fetch sequence number. This is 0 for bubbles and an ascending
97 * sequence for the stream of all fetched instructions */
98 InstSeqNum fetchSeqNum;
99
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;
104
105 public:
106 /** Very boring default constructor */
107 InstId(
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)
114 { }
115
116 public:
117 /* Equal if the thread and last set sequence number matches */
118 bool
119 operator== (const InstId &rhs)
120 {
121 /* If any of fetch and exec sequence number are not set
122 * they need to be 0, so a straight comparison is still
123 * fine */
124 bool ret = (threadId == rhs.threadId &&
125 lineSeqNum == rhs.lineSeqNum &&
126 fetchSeqNum == rhs.fetchSeqNum &&
127 execSeqNum == rhs.execSeqNum);
128
129 /* Stream and prediction *must* match if these are the same id */
130 if (ret) {
131 assert(streamSeqNum == rhs.streamSeqNum &&
132 predictionSeqNum == rhs.predictionSeqNum);
133 }
134
135 return ret;
136 }
137 };
138
139 /** Print this id in the usual slash-separated format expected by
140 * MinorTrace */
141 std::ostream &operator <<(std::ostream &os, const InstId &id);
142
143 class MinorDynInst;
144
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);
150
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
156 {
157 private:
158 /** A prototypical bubble instruction. You must call MinorDynInst::init
159 * to initialise this */
160 static MinorDynInstPtr bubbleInst;
161
162 public:
163 StaticInstPtr staticInst;
164
165 InstId id;
166
167 /** Trace information for this instruction's execution */
168 Trace::InstRecord *traceData;
169
170 /** The fetch address of this instruction */
171 TheISA::PCState pc;
172
173 /** This is actually a fault masquerading as an instruction */
174 Fault fault;
175
176 /** Tried to predict the destination of this inst (if a control
177 * instruction or a sys call) */
178 bool triedToPredict;
179
180 /** This instruction was predicted to change control flow and
181 * the following instructions will have a newer predictionSeqNum */
182 bool predictedTaken;
183
184 /** Predicted branch target */
185 TheISA::PCState predictedTarget;
186
187 /** Fields only set during execution */
188
189 /** FU this instruction is issued to */
190 unsigned int fuIndex;
191
192 /** This instruction is in the LSQ, not a functional unit */
193 bool inLSQ;
194
195 /** Translation fault in case of a mem ref */
196 Fault translationFault;
197
198 /** The instruction has been sent to the store buffer */
199 bool inStoreBuffer;
200
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 */
204 bool canEarlyIssue;
205
206 /** Flag controlling conditional execution of the instruction */
207 bool predicate;
208
209 /** Flag controlling conditional execution of the memory access associated
210 * with the instruction (only meaningful for loads/stores) */
211 bool memAccPredicate;
212
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;
218
219 /** Extra delay at the end of the pipeline */
220 Cycles extraCommitDelay;
221 TimingExpr *extraCommitDelayExpr;
222
223 /** Once issued, extraCommitDelay becomes minimumCommitCycle
224 * to account for delay in absolute time */
225 Cycles minimumCommitCycle;
226
227 /** Flat register indices so that, when clearing the scoreboard, we
228 * have the same register indices as when the instruction was marked
229 * up */
230 RegId flatDestRegIdx[TheISA::MaxInstDestRegs];
231
232 public:
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))
241 { }
242
243 public:
244 /** The BubbleIF interface. */
245 bool isBubble() const { return id.fetchSeqNum == 0; }
246
247 /** There is a single bubble inst */
248 static MinorDynInstPtr bubble() { return bubbleInst; }
249
250 /** Is this a fault rather than instruction */
251 bool isFault() const { return fault != NoFault; }
252
253 /** Is this a real instruction */
254 bool isInst() const { return !isBubble() && !isFault(); }
255
256 /** Is this a real mem ref instruction */
257 bool isMemRef() const { return isInst() && staticInst->isMemRef(); }
258
259 /** Is this an instruction that can be executed `for free' and
260 * needn't spend time in an FU */
261 bool isNoCostInst() const;
262
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;
266
267 /** Initialise the class */
268 static void init();
269
270 /** Print (possibly verbose) instruction information for
271 * MinorTrace using the given Named object's name */
272 void minorTraceInst(const Named &named_object) const;
273
274 /** ReportIF interface */
275 void reportData(std::ostream &os) const;
276
277 bool readPredicate() const { return predicate; }
278
279 void setPredicate(bool val) { predicate = val; }
280
281 bool readMemAccPredicate() const { return memAccPredicate; }
282
283 void setMemAccPredicate(bool val) { memAccPredicate = val; }
284
285 ~MinorDynInst();
286 };
287
288 /** Print a summary of the instruction */
289 std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
290
291 }
292
293 #endif /* __CPU_MINOR_DYN_INST_HH__ */