cpu: `Minor' in-order CPU model
[gem5.git] / src / cpu / minor / dyn_inst.hh
1 /*
2 * Copyright (c) 2013-2014 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 * Authors: Andrew Bardsley
38 */
39
40 /**
41 * @file
42 *
43 * The dynamic instruction and instruction/line id (sequence numbers)
44 * definition for Minor. A spirited attempt is made here to not carry too
45 * much on this structure.
46 */
47
48 #ifndef __CPU_MINOR_DYN_INST_HH__
49 #define __CPU_MINOR_DYN_INST_HH__
50
51 #include <iostream>
52
53 #include "base/refcnt.hh"
54 #include "cpu/minor/buffers.hh"
55 #include "cpu/inst_seq.hh"
56 #include "cpu/static_inst.hh"
57 #include "cpu/timing_expr.hh"
58 #include "sim/faults.hh"
59
60 namespace Minor
61 {
62
63 class MinorDynInst;
64
65 /** MinorDynInsts are currently reference counted. */
66 typedef RefCountingPtr<MinorDynInst> MinorDynInstPtr;
67
68 /** Id for lines and instructions. This includes all the relevant sequence
69 * numbers and thread ids for all stages of execution. */
70 class InstId
71 {
72 public:
73 /** First sequence numbers to use in initialisation of the pipeline and
74 * to be expected on the first line/instruction issued */
75 static const InstSeqNum firstStreamSeqNum = 1;
76 static const InstSeqNum firstPredictionSeqNum = 1;
77 static const InstSeqNum firstLineSeqNum = 1;
78 static const InstSeqNum firstFetchSeqNum = 1;
79 static const InstSeqNum firstExecSeqNum = 1;
80
81 public:
82 /** The thread to which this line/instruction belongs */
83 ThreadID threadId;
84
85 /** The 'stream' this instruction belongs to. Streams are interrupted
86 * (and sequence numbers increased) when Execute finds it wants to
87 * change the stream of instructions due to a branch. */
88 InstSeqNum streamSeqNum;
89
90 /** The predicted qualifier to stream, attached by Fetch2 as a
91 * consequence of branch prediction */
92 InstSeqNum predictionSeqNum;
93
94 /** Line sequence number. This is the sequence number of the fetched
95 * line from which this instruction was fetched */
96 InstSeqNum lineSeqNum;
97
98 /** Fetch sequence number. This is 0 for bubbles and an ascending
99 * sequence for the stream of all fetched instructions */
100 InstSeqNum fetchSeqNum;
101
102 /** 'Execute' sequence number. These are assigned after micro-op
103 * decomposition and form an ascending sequence (starting with 1) for
104 * post-micro-op decomposed instructions. */
105 InstSeqNum execSeqNum;
106
107 public:
108 /** Very boring default constructor */
109 InstId(
110 ThreadID thread_id = 0, InstSeqNum stream_seq_num = 0,
111 InstSeqNum prediction_seq_num = 0, InstSeqNum line_seq_num = 0,
112 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 */
143 std::ostream &operator <<(std::ostream &os, const InstId &id);
144
145 class 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. */
151 std::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 */
157 class 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 */
277 std::ostream &operator <<(std::ostream &os, const MinorDynInst &inst);
278
279 }
280
281 #endif /* __CPU_MINOR_DYN_INST_HH__ */