gem5 v24.0.0.0
Loading...
Searching...
No Matches
dyn_inst.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2011, 2021 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 * Copyright (c) 2004-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#include "cpu/o3/dyn_inst.hh"
42
43#include <algorithm>
44
45#include "base/intmath.hh"
46#include "debug/DynInst.hh"
47#include "debug/IQ.hh"
48#include "debug/O3PipeView.hh"
49
50namespace gem5
51{
52
53namespace o3
54{
55
56DynInst::DynInst(const Arrays &arrays, const StaticInstPtr &static_inst,
57 const StaticInstPtr &_macroop, InstSeqNum seq_num, CPU *_cpu)
58 : seqNum(seq_num), staticInst(static_inst), cpu(_cpu),
59 _numSrcs(arrays.numSrcs), _numDests(arrays.numDests),
60 _flatDestIdx(arrays.flatDestIdx), _destIdx(arrays.destIdx),
61 _prevDestIdx(arrays.prevDestIdx), _srcIdx(arrays.srcIdx),
62 _readySrcIdx(arrays.readySrcIdx), macroop(_macroop)
63{
64 std::fill(_readySrcIdx, _readySrcIdx + (numSrcs() + 7) / 8, 0);
65
66 status.reset();
67
68 instFlags.reset();
69 instFlags[RecordResult] = true;
70 instFlags[Predicate] = true;
72
73#ifndef NDEBUG
74 ++cpu->instcount;
75
76 if (cpu->instcount > 1500) {
77#ifdef GEM5_DEBUG
78 cpu->dumpInsts();
79 dumpSNList();
80#endif
81 assert(cpu->instcount <= 1500);
82 }
83
85 "DynInst: [sn:%lli] Instruction created. Instcount for %s = %i\n",
87#endif
88
89#ifdef GEM5_DEBUG
90 cpu->snList.insert(seqNum);
91#endif
92
93}
94
95DynInst::DynInst(const Arrays &arrays, const StaticInstPtr &static_inst,
96 const StaticInstPtr &_macroop, const PCStateBase &_pc,
97 const PCStateBase &pred_pc, InstSeqNum seq_num, CPU *_cpu)
98 : DynInst(arrays, static_inst, _macroop, seq_num, _cpu)
99{
100 set(pc, _pc);
101 set(predPC, pred_pc);
102}
103
104DynInst::DynInst(const Arrays &arrays, const StaticInstPtr &_staticInst,
105 const StaticInstPtr &_macroop)
106 : DynInst(arrays, _staticInst, _macroop, 0, nullptr)
107{}
108
109/*
110 * This custom "new" operator uses the default "new" operator to allocate space
111 * for a DynInst, but also pads out the number of bytes to make room for some
112 * extra structures the DynInst needs. We save time and improve performance by
113 * only going to the heap once to get space for all these structures.
114 *
115 * When a DynInst is allocated with new, the compiler will call this "new"
116 * operator with "count" set to the number of bytes it needs to store the
117 * DynInst. We ultimately call into the default new operator to get those
118 * bytes, but before we do, we pad out "count" so that there will be extra
119 * space for some structures the DynInst needs. We take into account both the
120 * absolute size of these structures, and also what alignment they need.
121 *
122 * Once we've gotten a buffer large enough to hold the DynInst itself and these
123 * extra structures, we construct the extra bits using placement new. This
124 * constructs the structures in place in the space we created for them.
125 *
126 * Next, we return the buffer as the result of our operator. The compiler takes
127 * that buffer and constructs the DynInst in the beginning of it using the
128 * DynInst constructor.
129 *
130 * To avoid having to calculate where these extra structures are twice, once
131 * when making room for them and initializing them, and then once again in the
132 * DynInst constructor, we also pass in a structure called "arrays" which holds
133 * pointers to them. The fields of "arrays" are initialized in this operator,
134 * and are then consumed in the DynInst constructor.
135 */
136void *
137DynInst::operator new(size_t count, Arrays &arrays)
138{
139 // Convenience variables for brevity.
140 const auto num_dests = arrays.numDests;
141 const auto num_srcs = arrays.numSrcs;
142
143 // Figure out where everything will go.
144 uintptr_t inst = 0;
145 size_t inst_size = count;
146
147 uintptr_t flat_dest_idx = roundUp(inst + inst_size, alignof(RegId));
148 size_t flat_dest_idx_size = sizeof(*arrays.flatDestIdx) * num_dests;
149
150 uintptr_t dest_idx =
151 roundUp(flat_dest_idx + flat_dest_idx_size, alignof(PhysRegIdPtr));
152 size_t dest_idx_size = sizeof(*arrays.destIdx) * num_dests;
153
154 uintptr_t prev_dest_idx =
155 roundUp(dest_idx + dest_idx_size, alignof(PhysRegIdPtr));
156 size_t prev_dest_idx_size = sizeof(*arrays.prevDestIdx) * num_dests;
157
158 uintptr_t src_idx =
159 roundUp(prev_dest_idx + prev_dest_idx_size, alignof(PhysRegIdPtr));
160 size_t src_idx_size = sizeof(*arrays.srcIdx) * num_srcs;
161
162 uintptr_t ready_src_idx =
163 roundUp(src_idx + src_idx_size, alignof(uint8_t));
164 size_t ready_src_idx_size =
165 sizeof(*arrays.readySrcIdx) * ((num_srcs + 7) / 8);
166
167 // Figure out how much space we need in total.
168 size_t total_size = ready_src_idx + ready_src_idx_size;
169
170 // Actually allocate it.
171 uint8_t *buf = (uint8_t *)::operator new(total_size);
172
173 // Fill in "arrays" with pointers to all the arrays.
174 arrays.flatDestIdx = (RegId *)(buf + flat_dest_idx);
175 arrays.destIdx = (PhysRegIdPtr *)(buf + dest_idx);
176 arrays.prevDestIdx = (PhysRegIdPtr *)(buf + prev_dest_idx);
177 arrays.srcIdx = (PhysRegIdPtr *)(buf + src_idx);
178 arrays.readySrcIdx = (uint8_t *)(buf + ready_src_idx);
179
180 // Initialize all the extra components.
181 new (arrays.flatDestIdx) RegId[num_dests];
182 new (arrays.destIdx) PhysRegIdPtr[num_dests];
183 new (arrays.prevDestIdx) PhysRegIdPtr[num_dests];
184 new (arrays.srcIdx) PhysRegIdPtr[num_srcs];
185 new (arrays.readySrcIdx) uint8_t[num_srcs];
186
187 return buf;
188}
189
190// Because of the custom "new" operator that allocates more bytes than the
191// size of the DynInst object, AddressSanitizer throw new-delete-type-mismatch.
192// Adding a custom delete function is enough to shut down this false positive
193void
194DynInst::operator delete(void *ptr)
195{
196 ::operator delete(ptr);
197}
198
200{
201 /*
202 * The buffer this DynInst occupies also holds some of the structures it
203 * points to. We need to call their destructors manually to make sure that
204 * they're cleaned up appropriately, but we don't need to free their memory
205 * explicitly since that's part of the DynInst's buffer and is already
206 * going to be freed as part of deleting the DynInst.
207 */
208 for (int i = 0; i < _numDests; i++) {
209 _flatDestIdx[i].~RegId();
210 _destIdx[i].~PhysRegIdPtr();
211 _prevDestIdx[i].~PhysRegIdPtr();
212 }
213
214 for (int i = 0; i < _numSrcs; i++)
216
217 for (int i = 0; i < ((_numSrcs + 7) / 8); i++)
218 _readySrcIdx[i].~uint8_t();
219
220#if TRACING_ON
221 if (debug::O3PipeView) {
222 Tick fetch = fetchTick;
223 // fetchTick can be -1 if the instruction fetched outside the trace
224 // window.
225 if (fetch != -1) {
226 Tick val;
227 // Print info needed by the pipeline activity viewer.
228 DPRINTFR(O3PipeView, "O3PipeView:fetch:%llu:0x%08llx:%d:%llu:%s\n",
229 fetch,
230 pcState().instAddr(),
231 pcState().microPC(),
232 seqNum,
233 staticInst->disassemble(pcState().instAddr()));
234
235 val = (decodeTick == -1) ? 0 : fetch + decodeTick;
236 DPRINTFR(O3PipeView, "O3PipeView:decode:%llu\n", val);
237 val = (renameTick == -1) ? 0 : fetch + renameTick;
238 DPRINTFR(O3PipeView, "O3PipeView:rename:%llu\n", val);
239 val = (dispatchTick == -1) ? 0 : fetch + dispatchTick;
240 DPRINTFR(O3PipeView, "O3PipeView:dispatch:%llu\n", val);
241 val = (issueTick == -1) ? 0 : fetch + issueTick;
242 DPRINTFR(O3PipeView, "O3PipeView:issue:%llu\n", val);
243 val = (completeTick == -1) ? 0 : fetch + completeTick;
244 DPRINTFR(O3PipeView, "O3PipeView:complete:%llu\n", val);
245 val = (commitTick == -1) ? 0 : fetch + commitTick;
246
247 Tick valS = (storeTick == -1) ? 0 : fetch + storeTick;
248 DPRINTFR(O3PipeView, "O3PipeView:retire:%llu:store:%llu\n",
249 val, valS);
250 }
251 }
252#endif
253
254 delete [] memData;
255 delete traceData;
256 fault = NoFault;
257
258#ifndef NDEBUG
259 --cpu->instcount;
260
262 "DynInst: [sn:%lli] Instruction destroyed. Instcount for %s = %i\n",
263 seqNum, cpu->name(), cpu->instcount);
264#endif
265#ifdef GEM5_DEBUG
266 cpu->snList.erase(seqNum);
267#endif
268};
269
270
271#ifdef GEM5_DEBUG
272void
273DynInst::dumpSNList()
274{
275 std::set<InstSeqNum>::iterator sn_it = cpu->snList.begin();
276
277 int count = 0;
278 while (sn_it != cpu->snList.end()) {
279 cprintf("%i: [sn:%lli] not destroyed\n", count, (*sn_it));
280 count++;
281 sn_it++;
282 }
283}
284#endif
285
286void
288{
289 cprintf("T%d : %#08d `", threadNumber, pc->instAddr());
290 std::cout << staticInst->disassemble(pc->instAddr());
291 cprintf("'\n");
292}
293
294void
295DynInst::dump(std::string &outstring)
296{
297 std::ostringstream s;
298 s << "T" << threadNumber << " : 0x" << pc->instAddr() << " "
299 << staticInst->disassemble(pc->instAddr());
300
301 outstring = s.str();
302}
303
304void
306{
307 DPRINTF(IQ, "[sn:%lli] has %d ready out of %d sources. RTI %d)\n",
309 if (++readyRegs == numSrcRegs()) {
310 setCanIssue();
311 }
312}
313
314void
316{
317 readySrcIdx(src_idx, true);
319}
320
321
322void
324{
325 status.set(Squashed);
326
328 return;
329
330 // This inst has been renamed already so it may go through rename
331 // again (e.g. if the squash is due to memory access order violation).
332 // Reset the write counters for all pinned destination register to ensure
333 // that they are in a consistent state for a possible re-rename. This also
334 // ensures that dest regs will be pinned to the same phys register if
335 // re-rename happens.
336 for (int idx = 0; idx < numDestRegs(); idx++) {
337 PhysRegIdPtr phys_dest_reg = renamedDestIdx(idx);
338 if (phys_dest_reg->isPinned()) {
339 phys_dest_reg->incrNumPinnedWrites();
341 phys_dest_reg->incrNumPinnedWritesToComplete();
342 }
343 }
345}
346
347Fault
349{
350 // @todo: Pretty convoluted way to avoid squashing from happening
351 // when using the TC during an instruction's execution
352 // (specifically for instructions that have side-effects that use
353 // the TC). Fix this.
354 bool no_squash_from_TC = thread->noSquashFromTC;
355 thread->noSquashFromTC = true;
356
358
359 thread->noSquashFromTC = no_squash_from_TC;
360
361 return fault;
362}
363
364Fault
366{
367 // @todo: Pretty convoluted way to avoid squashing from happening
368 // when using the TC during an instruction's execution
369 // (specifically for instructions that have side-effects that use
370 // the TC). Fix this.
371 bool no_squash_from_TC = thread->noSquashFromTC;
372 thread->noSquashFromTC = true;
373
375
376 thread->noSquashFromTC = no_squash_from_TC;
377
378 return fault;
379}
380
381Fault
383{
384 // @todo: Pretty convoluted way to avoid squashing from happening
385 // when using the TC during an instruction's execution
386 // (specifically for instructions that have side-effects that use
387 // the TC). Fix this.
388 bool no_squash_from_TC = thread->noSquashFromTC;
389 thread->noSquashFromTC = true;
390
391 if (cpu->checker) {
392 if (isStoreConditional()) {
393 reqToVerify->setExtraData(pkt->req->getExtraData());
394 }
395 }
396
397 fault = staticInst->completeAcc(pkt, this, traceData);
398
399 thread->noSquashFromTC = no_squash_from_TC;
400
401 return fault;
402}
403
404void
405DynInst::trap(const Fault &fault)
406{
408}
409
410Fault
412 const std::vector<bool> &byte_enable)
413{
414 assert(byte_enable.size() == size);
415 return cpu->pushRequest(
416 dynamic_cast<DynInstPtr::PtrType>(this),
417 /* ld */ true, nullptr, size, addr, flags, nullptr, nullptr,
418 byte_enable);
419}
420
421Fault
423{
424 const unsigned int size = 8;
425 return cpu->pushRequest(
426 dynamic_cast<DynInstPtr::PtrType>(this),
427 /* ld */ true, nullptr, size, 0x0ul, flags, nullptr, nullptr,
428 std::vector<bool>(size, true));
429}
430
431Fault
432DynInst::writeMem(uint8_t *data, unsigned size, Addr addr,
433 Request::Flags flags, uint64_t *res,
434 const std::vector<bool> &byte_enable)
435{
436 assert(byte_enable.size() == size);
437 return cpu->pushRequest(
438 dynamic_cast<DynInstPtr::PtrType>(this),
439 /* st */ false, data, size, addr, flags, res, nullptr,
440 byte_enable);
441}
442
443Fault
445 AtomicOpFunctorPtr amo_op)
446{
447 // atomic memory instructions do not have data to be written to memory yet
448 // since the atomic operations will be executed directly in cache/memory.
449 // Therefore, its `data` field is nullptr.
450 // Atomic memory requests need to carry their `amo_op` fields to cache/
451 // memory
452 return cpu->pushRequest(
453 dynamic_cast<DynInstPtr::PtrType>(this),
454 /* atomic */ false, nullptr, size, addr, flags, nullptr,
455 std::move(amo_op), std::vector<bool>(size, true));
456}
457
458} // namespace o3
459} // namespace gem5
#define DPRINTFR(x,...)
Definition trace.hh:224
#define DPRINTF(x,...)
Definition trace.hh:210
const char data[]
virtual std::string name() const
Definition named.hh:47
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
RequestPtr req
A pointer to the original request.
Definition packet.hh:377
Physical register ID.
Definition reg_class.hh:415
void incrNumPinnedWritesToComplete()
Definition reg_class.hh:507
void incrNumPinnedWrites()
Definition reg_class.hh:490
bool isPinned() const
Definition reg_class.hh:492
Register ID: describe an architectural register with its class and index.
Definition reg_class.hh:94
virtual const std::string & disassemble(Addr pc, const loader::SymbolTable *symtab=nullptr) const
Return string representation of disassembled instruction.
virtual Fault execute(ExecContext *xc, trace::InstRecord *traceData) const =0
virtual Fault completeAcc(Packet *pkt, ExecContext *xc, trace::InstRecord *trace_data) const
virtual Fault initiateAcc(ExecContext *xc, trace::InstRecord *traceData) const
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition cpu.hh:94
gem5::Checker< DynInstPtr > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
Definition cpu.hh:527
void dumpInsts()
Debug function to print all instructions on the list.
Definition cpu.cc:1289
Fault pushRequest(const DynInstPtr &inst, bool isLoad, uint8_t *data, unsigned int size, Addr addr, Request::Flags flags, uint64_t *res, AtomicOpFunctorPtr amo_op=nullptr, const std::vector< bool > &byte_enable=std::vector< bool >())
CPU pushRequest function, forwards request to LSQ.
Definition cpu.hh:552
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
Definition cpu.cc:708
int instcount
Count of total number of dynamic instructions in flight.
Definition cpu.hh:380
uint8_t readyRegs
How many source registers are ready.
Definition dyn_inst.hh:330
uint8_t * memData
Pointer to the data for the memory access.
Definition dyn_inst.hh:347
bool isStoreConditional() const
Definition dyn_inst.hh:544
RequestPtr reqToVerify
Definition dyn_inst.hh:367
ThreadState * thread
Pointer to the thread state.
Definition dyn_inst.hh:135
PhysRegIdPtr * _prevDestIdx
Definition dyn_inst.hh:231
std::unique_ptr< PCStateBase > predPC
Predicted PC state after this instruction.
Definition dyn_inst.hh:324
RegId * _flatDestIdx
Definition dyn_inst.hh:223
Fault writeMem(uint8_t *data, unsigned size, Addr addr, Request::Flags flags, uint64_t *res, const std::vector< bool > &byte_enable) override
Definition dyn_inst.cc:432
uint8_t * _readySrcIdx
Definition dyn_inst.hh:237
bool readyToIssue() const
Returns whether or not this instruction is ready to issue.
Definition dyn_inst.hh:746
@ Squashed
Instruction has committed.
Definition dyn_inst.hh:157
Fault completeAcc(PacketPtr pkt)
Completes the access.
Definition dyn_inst.cc:382
Fault fault
The kind of fault this instruction has generated.
Definition dyn_inst.hh:138
std::unique_ptr< PCStateBase > pc
PC state for this instruction.
Definition dyn_inst.hh:207
ThreadID threadNumber
The thread this instruction is from.
Definition dyn_inst.hh:317
std::bitset< MaxFlags > instFlags
Definition dyn_inst.hh:195
bool readySrcIdx(int idx) const
Definition dyn_inst.hh:303
bool isPinnedRegsRenamed() const
Returns whether pinned registers are renamed.
Definition dyn_inst.hh:845
Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
Definition dyn_inst.cc:444
size_t numDestRegs() const
Returns the number of destination registers.
Definition dyn_inst.hh:681
void dump()
Dumps out contents of this BaseDynInst.
Definition dyn_inst.cc:287
const StaticInstPtr staticInst
The StaticInst used by this BaseDynInst.
Definition dyn_inst.hh:127
void setSquashed()
Sets this instruction as squashed.
Definition dyn_inst.cc:323
Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable) override
Definition dyn_inst.cc:411
CPU * cpu
Pointer to the Impl's CPU object.
Definition dyn_inst.hh:130
void trap(const Fault &fault)
Traps to handle specified fault.
Definition dyn_inst.cc:405
trace::InstRecord * traceData
InstRecord that tracks this instructions.
Definition dyn_inst.hh:141
Fault execute()
Executes the instruction.
Definition dyn_inst.cc:348
bool isPinnedRegsSquashDone() const
Return whether dest registers' pinning status updated after squash.
Definition dyn_inst.hh:870
PhysRegIdPtr renamedDestIdx(int idx) const
Definition dyn_inst.hh:262
std::bitset< NumStatus > status
The status of this BaseDynInst.
Definition dyn_inst.hh:198
const PCStateBase & pcState() const override
Read the PC state of this instruction.
Definition dyn_inst.hh:885
void setPinnedRegsSquashDone()
Sets dest registers' status updated after squash.
Definition dyn_inst.hh:877
DynInst(const StaticInstPtr &staticInst, const StaticInstPtr &macroop, InstSeqNum seq_num, CPU *cpu)
Fault initiateMemMgmtCmd(Request::Flags flags) override
Initiate a memory management command with no valid address.
Definition dyn_inst.cc:422
bool isPinnedRegsWritten() const
Returns whether destination registers are written.
Definition dyn_inst.hh:857
InstSeqNum seqNum
The sequence number of the instruction.
Definition dyn_inst.hh:124
void markSrcRegReady()
Records that one of the source registers is ready.
Definition dyn_inst.cc:305
size_t numSrcRegs() const
Returns the number of source registers.
Definition dyn_inst.hh:678
PhysRegIdPtr * _destIdx
Definition dyn_inst.hh:227
size_t numSrcs() const
Definition dyn_inst.hh:240
Fault initiateAcc()
Initiates the access.
Definition dyn_inst.cc:365
void setCanIssue()
Sets this instruction as ready to issue.
Definition dyn_inst.hh:743
size_t numDests() const
Definition dyn_inst.hh:241
PhysRegIdPtr * _srcIdx
Definition dyn_inst.hh:234
STL vector class.
Definition stl.hh:37
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Definition amo.hh:269
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:260
uint8_t flags
Definition helpers.cc:87
Bitfield< 4 > s
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 12, 11 > set
Bitfield< 63 > val
Definition misc.hh:804
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint16_t RegIndex
Definition types.hh:176
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
void cprintf(const char *format, const Args &...args)
Definition cprintf.hh:155
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
PhysRegId * PhysRegIdPtr
Definition reg_class.hh:510
uint64_t Tick
Tick count type.
Definition types.hh:58
constexpr decltype(nullptr) NoFault
Definition types.hh:253
uint64_t InstSeqNum
Definition inst_seq.hh:40

Generated on Tue Jun 18 2024 16:24:01 for gem5 by doxygen 1.11.0