cpu: make ExecSymbol show the symbol in addition to address
[gem5.git] / src / cpu / base_dyn_inst.hh
1 /*
2 * Copyright (c) 2011, 2013, 2016-2020 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2004-2006 The Regents of The University of Michigan
16 * Copyright (c) 2009 The University of Edinburgh
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are
21 * met: redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer;
23 * redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution;
26 * neither the name of the copyright holders nor the names of its
27 * contributors may be used to endorse or promote products derived from
28 * this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 */
42
43 #ifndef __CPU_BASE_DYN_INST_HH__
44 #define __CPU_BASE_DYN_INST_HH__
45
46 #include <array>
47 #include <bitset>
48 #include <deque>
49 #include <list>
50 #include <string>
51
52 #include "arch/generic/tlb.hh"
53 #include "arch/utility.hh"
54 #include "base/trace.hh"
55 #include "config/the_isa.hh"
56 #include "cpu/checker/cpu.hh"
57 #include "cpu/exec_context.hh"
58 #include "cpu/exetrace.hh"
59 #include "cpu/inst_res.hh"
60 #include "cpu/inst_seq.hh"
61 #include "cpu/op_class.hh"
62 #include "cpu/static_inst.hh"
63 #include "cpu/translation.hh"
64 #include "debug/HtmCpu.hh"
65 #include "mem/packet.hh"
66 #include "mem/request.hh"
67 #include "sim/byteswap.hh"
68 #include "sim/system.hh"
69
70 /**
71 * @file
72 * Defines a dynamic instruction context.
73 */
74
75 template <class Impl>
76 class BaseDynInst : public ExecContext, public RefCounted
77 {
78 public:
79 // Typedef for the CPU.
80 typedef typename Impl::CPUType ImplCPU;
81 typedef typename ImplCPU::ImplState ImplState;
82 using VecRegContainer = TheISA::VecRegContainer;
83
84 using LSQRequestPtr = typename Impl::CPUPol::LSQ::LSQRequest*;
85 using LQIterator = typename Impl::CPUPol::LSQUnit::LQIterator;
86 using SQIterator = typename Impl::CPUPol::LSQUnit::SQIterator;
87
88 // The DynInstPtr type.
89 typedef typename Impl::DynInstPtr DynInstPtr;
90 typedef RefCountingPtr<BaseDynInst<Impl> > BaseDynInstPtr;
91
92 // The list of instructions iterator type.
93 typedef typename std::list<DynInstPtr>::iterator ListIt;
94
95 enum {
96 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs
97 MaxInstDestRegs = TheISA::MaxInstDestRegs /// Max dest regs
98 };
99
100 protected:
101 enum Status {
102 IqEntry, /// Instruction is in the IQ
103 RobEntry, /// Instruction is in the ROB
104 LsqEntry, /// Instruction is in the LSQ
105 Completed, /// Instruction has completed
106 ResultReady, /// Instruction has its result
107 CanIssue, /// Instruction can issue and execute
108 Issued, /// Instruction has issued
109 Executed, /// Instruction has executed
110 CanCommit, /// Instruction can commit
111 AtCommit, /// Instruction has reached commit
112 Committed, /// Instruction has committed
113 Squashed, /// Instruction is squashed
114 SquashedInIQ, /// Instruction is squashed in the IQ
115 SquashedInLSQ, /// Instruction is squashed in the LSQ
116 SquashedInROB, /// Instruction is squashed in the ROB
117 PinnedRegsRenamed, /// Pinned registers are renamed
118 PinnedRegsWritten, /// Pinned registers are written back
119 PinnedRegsSquashDone, /// Regs pinning status updated after squash
120 RecoverInst, /// Is a recover instruction
121 BlockingInst, /// Is a blocking instruction
122 ThreadsyncWait, /// Is a thread synchronization instruction
123 SerializeBefore, /// Needs to serialize on
124 /// instructions ahead of it
125 SerializeAfter, /// Needs to serialize instructions behind it
126 SerializeHandled, /// Serialization has been handled
127 NumStatus
128 };
129
130 enum Flags {
131 NotAnInst,
132 TranslationStarted,
133 TranslationCompleted,
134 PossibleLoadViolation,
135 HitExternalSnoop,
136 EffAddrValid,
137 RecordResult,
138 Predicate,
139 MemAccPredicate,
140 PredTaken,
141 IsStrictlyOrdered,
142 ReqMade,
143 MemOpDone,
144 HtmFromTransaction,
145 MaxFlags
146 };
147
148 public:
149 /** The sequence number of the instruction. */
150 InstSeqNum seqNum;
151
152 /** The StaticInst used by this BaseDynInst. */
153 const StaticInstPtr staticInst;
154
155 /** Pointer to the Impl's CPU object. */
156 ImplCPU *cpu;
157
158 BaseCPU *getCpuPtr() { return cpu; }
159
160 /** Pointer to the thread state. */
161 ImplState *thread;
162
163 /** The kind of fault this instruction has generated. */
164 Fault fault;
165
166 /** InstRecord that tracks this instructions. */
167 Trace::InstRecord *traceData;
168
169 protected:
170 /** The result of the instruction; assumes an instruction can have many
171 * destination registers.
172 */
173 std::queue<InstResult> instResult;
174
175 /** PC state for this instruction. */
176 TheISA::PCState pc;
177
178 private:
179 /* An amalgamation of a lot of boolean values into one */
180 std::bitset<MaxFlags> instFlags;
181
182 /** The status of this BaseDynInst. Several bits can be set. */
183 std::bitset<NumStatus> status;
184
185 protected:
186 /** Whether or not the source register is ready.
187 * @todo: Not sure this should be here vs the derived class.
188 */
189 std::bitset<MaxInstSrcRegs> _readySrcRegIdx;
190
191 public:
192 /** The thread this instruction is from. */
193 ThreadID threadNumber;
194
195 /** Iterator pointing to this BaseDynInst in the list of all insts. */
196 ListIt instListIt;
197
198 ////////////////////// Branch Data ///////////////
199 /** Predicted PC state after this instruction. */
200 TheISA::PCState predPC;
201
202 /** The Macroop if one exists */
203 const StaticInstPtr macroop;
204
205 /** How many source registers are ready. */
206 uint8_t readyRegs;
207
208 public:
209 /////////////////////// Load Store Data //////////////////////
210 /** The effective virtual address (lds & stores only). */
211 Addr effAddr;
212
213 /** The effective physical address. */
214 Addr physEffAddr;
215
216 /** The memory request flags (from translation). */
217 unsigned memReqFlags;
218
219 /** The size of the request */
220 unsigned effSize;
221
222 /** Pointer to the data for the memory access. */
223 uint8_t *memData;
224
225 /** Load queue index. */
226 int16_t lqIdx;
227 LQIterator lqIt;
228
229 /** Store queue index. */
230 int16_t sqIdx;
231 SQIterator sqIt;
232
233
234 /////////////////////// TLB Miss //////////////////////
235 /**
236 * Saved memory request (needed when the DTB address translation is
237 * delayed due to a hw page table walk).
238 */
239 LSQRequestPtr savedReq;
240
241 /////////////////////// Checker //////////////////////
242 // Need a copy of main request pointer to verify on writes.
243 RequestPtr reqToVerify;
244
245 private:
246 // hardware transactional memory
247 uint64_t htmUid;
248 uint64_t htmDepth;
249
250 protected:
251 /** Flattened register index of the destination registers of this
252 * instruction.
253 */
254 std::array<RegId, TheISA::MaxInstDestRegs> _flatDestRegIdx;
255
256 /** Physical register index of the destination registers of this
257 * instruction.
258 */
259 std::array<PhysRegIdPtr, TheISA::MaxInstDestRegs> _destRegIdx;
260
261 /** Physical register index of the source registers of this
262 * instruction.
263 */
264 std::array<PhysRegIdPtr, TheISA::MaxInstSrcRegs> _srcRegIdx;
265
266 /** Physical register index of the previous producers of the
267 * architected destinations.
268 */
269 std::array<PhysRegIdPtr, TheISA::MaxInstDestRegs> _prevDestRegIdx;
270
271
272 public:
273 /** Records changes to result? */
274 void recordResult(bool f) { instFlags[RecordResult] = f; }
275
276 /** Is the effective virtual address valid. */
277 bool effAddrValid() const { return instFlags[EffAddrValid]; }
278 void effAddrValid(bool b) { instFlags[EffAddrValid] = b; }
279
280 /** Whether or not the memory operation is done. */
281 bool memOpDone() const { return instFlags[MemOpDone]; }
282 void memOpDone(bool f) { instFlags[MemOpDone] = f; }
283
284 bool notAnInst() const { return instFlags[NotAnInst]; }
285 void setNotAnInst() { instFlags[NotAnInst] = true; }
286
287
288 ////////////////////////////////////////////
289 //
290 // INSTRUCTION EXECUTION
291 //
292 ////////////////////////////////////////////
293
294 void
295 demapPage(Addr vaddr, uint64_t asn) override
296 {
297 cpu->demapPage(vaddr, asn);
298 }
299 void
300 demapInstPage(Addr vaddr, uint64_t asn)
301 {
302 cpu->demapPage(vaddr, asn);
303 }
304 void
305 demapDataPage(Addr vaddr, uint64_t asn)
306 {
307 cpu->demapPage(vaddr, asn);
308 }
309
310 Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags,
311 const std::vector<bool> &byte_enable=std::vector<bool>()) override;
312
313 Fault initiateHtmCmd(Request::Flags flags) override;
314
315 Fault writeMem(uint8_t *data, unsigned size, Addr addr,
316 Request::Flags flags, uint64_t *res,
317 const std::vector<bool> &byte_enable=std::vector<bool>())
318 override;
319
320 Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags,
321 AtomicOpFunctorPtr amo_op) override;
322
323 /** True if the DTB address translation has started. */
324 bool translationStarted() const { return instFlags[TranslationStarted]; }
325 void translationStarted(bool f) { instFlags[TranslationStarted] = f; }
326
327 /** True if the DTB address translation has completed. */
328 bool translationCompleted() const { return instFlags[TranslationCompleted]; }
329 void translationCompleted(bool f) { instFlags[TranslationCompleted] = f; }
330
331 /** True if this address was found to match a previous load and they issued
332 * out of order. If that happend, then it's only a problem if an incoming
333 * snoop invalidate modifies the line, in which case we need to squash.
334 * If nothing modified the line the order doesn't matter.
335 */
336 bool
337 possibleLoadViolation() const
338 {
339 return instFlags[PossibleLoadViolation];
340 }
341 void
342 possibleLoadViolation(bool f)
343 {
344 instFlags[PossibleLoadViolation] = f;
345 }
346
347 /** True if the address hit a external snoop while sitting in the LSQ.
348 * If this is true and a older instruction sees it, this instruction must
349 * reexecute
350 */
351 bool hitExternalSnoop() const { return instFlags[HitExternalSnoop]; }
352 void hitExternalSnoop(bool f) { instFlags[HitExternalSnoop] = f; }
353
354 /**
355 * Returns true if the DTB address translation is being delayed due to a hw
356 * page table walk.
357 */
358 bool
359 isTranslationDelayed() const
360 {
361 return (translationStarted() && !translationCompleted());
362 }
363
364 public:
365 #ifdef DEBUG
366 void dumpSNList();
367 #endif
368
369 /** Returns the physical register index of the i'th destination
370 * register.
371 */
372 PhysRegIdPtr
373 renamedDestRegIdx(int idx) const
374 {
375 return _destRegIdx[idx];
376 }
377
378 /** Returns the physical register index of the i'th source register. */
379 PhysRegIdPtr
380 renamedSrcRegIdx(int idx) const
381 {
382 assert(TheISA::MaxInstSrcRegs > idx);
383 return _srcRegIdx[idx];
384 }
385
386 /** Returns the flattened register index of the i'th destination
387 * register.
388 */
389 const RegId &
390 flattenedDestRegIdx(int idx) const
391 {
392 return _flatDestRegIdx[idx];
393 }
394
395 /** Returns the physical register index of the previous physical register
396 * that remapped to the same logical register index.
397 */
398 PhysRegIdPtr
399 prevDestRegIdx(int idx) const
400 {
401 return _prevDestRegIdx[idx];
402 }
403
404 /** Renames a destination register to a physical register. Also records
405 * the previous physical register that the logical register mapped to.
406 */
407 void
408 renameDestReg(int idx, PhysRegIdPtr renamed_dest,
409 PhysRegIdPtr previous_rename)
410 {
411 _destRegIdx[idx] = renamed_dest;
412 _prevDestRegIdx[idx] = previous_rename;
413 if (renamed_dest->isPinned())
414 setPinnedRegsRenamed();
415 }
416
417 /** Renames a source logical register to the physical register which
418 * has/will produce that logical register's result.
419 * @todo: add in whether or not the source register is ready.
420 */
421 void
422 renameSrcReg(int idx, PhysRegIdPtr renamed_src)
423 {
424 _srcRegIdx[idx] = renamed_src;
425 }
426
427 /** Flattens a destination architectural register index into a logical
428 * index.
429 */
430 void
431 flattenDestReg(int idx, const RegId &flattened_dest)
432 {
433 _flatDestRegIdx[idx] = flattened_dest;
434 }
435 /** BaseDynInst constructor given a binary instruction.
436 * @param staticInst A StaticInstPtr to the underlying instruction.
437 * @param pc The PC state for the instruction.
438 * @param predPC The predicted next PC state for the instruction.
439 * @param seq_num The sequence number of the instruction.
440 * @param cpu Pointer to the instruction's CPU.
441 */
442 BaseDynInst(const StaticInstPtr &staticInst, const StaticInstPtr &macroop,
443 TheISA::PCState pc, TheISA::PCState predPC,
444 InstSeqNum seq_num, ImplCPU *cpu);
445
446 /** BaseDynInst constructor given a StaticInst pointer.
447 * @param _staticInst The StaticInst for this BaseDynInst.
448 */
449 BaseDynInst(const StaticInstPtr &staticInst, const StaticInstPtr &macroop);
450
451 /** BaseDynInst destructor. */
452 ~BaseDynInst();
453
454 private:
455 /** Function to initialize variables in the constructors. */
456 void initVars();
457
458 public:
459 /** Dumps out contents of this BaseDynInst. */
460 void dump();
461
462 /** Dumps out contents of this BaseDynInst into given string. */
463 void dump(std::string &outstring);
464
465 /** Read this CPU's ID. */
466 int cpuId() const { return cpu->cpuId(); }
467
468 /** Read this CPU's Socket ID. */
469 uint32_t socketId() const { return cpu->socketId(); }
470
471 /** Read this CPU's data requestor ID */
472 RequestorID requestorId() const { return cpu->dataRequestorId(); }
473
474 /** Read this context's system-wide ID **/
475 ContextID contextId() const { return thread->contextId(); }
476
477 /** Returns the fault type. */
478 Fault getFault() const { return fault; }
479 /** TODO: This I added for the LSQRequest side to be able to modify the
480 * fault. There should be a better mechanism in place. */
481 Fault& getFault() { return fault; }
482
483 /** Checks whether or not this instruction has had its branch target
484 * calculated yet. For now it is not utilized and is hacked to be
485 * always false.
486 * @todo: Actually use this instruction.
487 */
488 bool doneTargCalc() { return false; }
489
490 /** Set the predicted target of this current instruction. */
491 void setPredTarg(const TheISA::PCState &_predPC) { predPC = _predPC; }
492
493 const TheISA::PCState &readPredTarg() { return predPC; }
494
495 /** Returns the predicted PC immediately after the branch. */
496 Addr predInstAddr() { return predPC.instAddr(); }
497
498 /** Returns the predicted PC two instructions after the branch */
499 Addr predNextInstAddr() { return predPC.nextInstAddr(); }
500
501 /** Returns the predicted micro PC after the branch */
502 Addr predMicroPC() { return predPC.microPC(); }
503
504 /** Returns whether the instruction was predicted taken or not. */
505 bool readPredTaken() { return instFlags[PredTaken]; }
506
507 void
508 setPredTaken(bool predicted_taken)
509 {
510 instFlags[PredTaken] = predicted_taken;
511 }
512
513 /** Returns whether the instruction mispredicted. */
514 bool
515 mispredicted()
516 {
517 TheISA::PCState tempPC = pc;
518 TheISA::advancePC(tempPC, staticInst);
519 return !(tempPC == predPC);
520 }
521
522 //
523 // Instruction types. Forward checks to StaticInst object.
524 //
525 bool isNop() const { return staticInst->isNop(); }
526 bool isMemRef() const { return staticInst->isMemRef(); }
527 bool isLoad() const { return staticInst->isLoad(); }
528 bool isStore() const { return staticInst->isStore(); }
529 bool isAtomic() const { return staticInst->isAtomic(); }
530 bool isStoreConditional() const
531 { return staticInst->isStoreConditional(); }
532 bool isInstPrefetch() const { return staticInst->isInstPrefetch(); }
533 bool isDataPrefetch() const { return staticInst->isDataPrefetch(); }
534 bool isInteger() const { return staticInst->isInteger(); }
535 bool isFloating() const { return staticInst->isFloating(); }
536 bool isVector() const { return staticInst->isVector(); }
537 bool isControl() const { return staticInst->isControl(); }
538 bool isCall() const { return staticInst->isCall(); }
539 bool isReturn() const { return staticInst->isReturn(); }
540 bool isDirectCtrl() const { return staticInst->isDirectCtrl(); }
541 bool isIndirectCtrl() const { return staticInst->isIndirectCtrl(); }
542 bool isCondCtrl() const { return staticInst->isCondCtrl(); }
543 bool isUncondCtrl() const { return staticInst->isUncondCtrl(); }
544 bool isSerializing() const { return staticInst->isSerializing(); }
545 bool
546 isSerializeBefore() const
547 {
548 return staticInst->isSerializeBefore() || status[SerializeBefore];
549 }
550 bool
551 isSerializeAfter() const
552 {
553 return staticInst->isSerializeAfter() || status[SerializeAfter];
554 }
555 bool isSquashAfter() const { return staticInst->isSquashAfter(); }
556 bool isFullMemBarrier() const { return staticInst->isFullMemBarrier(); }
557 bool isReadBarrier() const { return staticInst->isReadBarrier(); }
558 bool isWriteBarrier() const { return staticInst->isWriteBarrier(); }
559 bool isNonSpeculative() const { return staticInst->isNonSpeculative(); }
560 bool isQuiesce() const { return staticInst->isQuiesce(); }
561 bool isUnverifiable() const { return staticInst->isUnverifiable(); }
562 bool isSyscall() const { return staticInst->isSyscall(); }
563 bool isMacroop() const { return staticInst->isMacroop(); }
564 bool isMicroop() const { return staticInst->isMicroop(); }
565 bool isDelayedCommit() const { return staticInst->isDelayedCommit(); }
566 bool isLastMicroop() const { return staticInst->isLastMicroop(); }
567 bool isFirstMicroop() const { return staticInst->isFirstMicroop(); }
568 // hardware transactional memory
569 bool isHtmStart() const { return staticInst->isHtmStart(); }
570 bool isHtmStop() const { return staticInst->isHtmStop(); }
571 bool isHtmCancel() const { return staticInst->isHtmCancel(); }
572 bool isHtmCmd() const { return staticInst->isHtmCmd(); }
573
574 uint64_t
575 getHtmTransactionUid() const override
576 {
577 assert(instFlags[HtmFromTransaction]);
578 return this->htmUid;
579 }
580
581 uint64_t
582 newHtmTransactionUid() const override
583 {
584 panic("Not yet implemented\n");
585 return 0;
586 }
587
588 bool
589 inHtmTransactionalState() const override
590 {
591 return instFlags[HtmFromTransaction];
592 }
593
594 uint64_t
595 getHtmTransactionalDepth() const override
596 {
597 if (inHtmTransactionalState())
598 return this->htmDepth;
599 else
600 return 0;
601 }
602
603 void
604 setHtmTransactionalState(uint64_t htm_uid, uint64_t htm_depth)
605 {
606 instFlags.set(HtmFromTransaction);
607 htmUid = htm_uid;
608 htmDepth = htm_depth;
609 }
610
611 void
612 clearHtmTransactionalState()
613 {
614 if (inHtmTransactionalState()) {
615 DPRINTF(HtmCpu,
616 "clearing instuction's transactional state htmUid=%u\n",
617 getHtmTransactionUid());
618
619 instFlags.reset(HtmFromTransaction);
620 htmUid = -1;
621 htmDepth = 0;
622 }
623 }
624
625 /** Temporarily sets this instruction as a serialize before instruction. */
626 void setSerializeBefore() { status.set(SerializeBefore); }
627
628 /** Clears the serializeBefore part of this instruction. */
629 void clearSerializeBefore() { status.reset(SerializeBefore); }
630
631 /** Checks if this serializeBefore is only temporarily set. */
632 bool isTempSerializeBefore() { return status[SerializeBefore]; }
633
634 /** Temporarily sets this instruction as a serialize after instruction. */
635 void setSerializeAfter() { status.set(SerializeAfter); }
636
637 /** Clears the serializeAfter part of this instruction.*/
638 void clearSerializeAfter() { status.reset(SerializeAfter); }
639
640 /** Checks if this serializeAfter is only temporarily set. */
641 bool isTempSerializeAfter() { return status[SerializeAfter]; }
642
643 /** Sets the serialization part of this instruction as handled. */
644 void setSerializeHandled() { status.set(SerializeHandled); }
645
646 /** Checks if the serialization part of this instruction has been
647 * handled. This does not apply to the temporary serializing
648 * state; it only applies to this instruction's own permanent
649 * serializing state.
650 */
651 bool isSerializeHandled() { return status[SerializeHandled]; }
652
653 /** Returns the opclass of this instruction. */
654 OpClass opClass() const { return staticInst->opClass(); }
655
656 /** Returns the branch target address. */
657 TheISA::PCState branchTarget() const
658 { return staticInst->branchTarget(pc); }
659
660 /** Returns the number of source registers. */
661 int8_t numSrcRegs() const { return staticInst->numSrcRegs(); }
662
663 /** Returns the number of destination registers. */
664 int8_t numDestRegs() const { return staticInst->numDestRegs(); }
665
666 // the following are used to track physical register usage
667 // for machines with separate int & FP reg files
668 int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); }
669 int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); }
670 int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); }
671 int8_t numVecDestRegs() const { return staticInst->numVecDestRegs(); }
672 int8_t
673 numVecElemDestRegs() const
674 {
675 return staticInst->numVecElemDestRegs();
676 }
677 int8_t
678 numVecPredDestRegs() const
679 {
680 return staticInst->numVecPredDestRegs();
681 }
682
683 /** Returns the logical register index of the i'th destination register. */
684 const RegId& destRegIdx(int i) const { return staticInst->destRegIdx(i); }
685
686 /** Returns the logical register index of the i'th source register. */
687 const RegId& srcRegIdx(int i) const { return staticInst->srcRegIdx(i); }
688
689 /** Return the size of the instResult queue. */
690 uint8_t resultSize() { return instResult.size(); }
691
692 /** Pops a result off the instResult queue.
693 * If the result stack is empty, return the default value.
694 * */
695 InstResult
696 popResult(InstResult dflt=InstResult())
697 {
698 if (!instResult.empty()) {
699 InstResult t = instResult.front();
700 instResult.pop();
701 return t;
702 }
703 return dflt;
704 }
705
706 /** Pushes a result onto the instResult queue. */
707 /** @{ */
708 /** Scalar result. */
709 template<typename T>
710 void
711 setScalarResult(T &&t)
712 {
713 if (instFlags[RecordResult]) {
714 instResult.push(InstResult(std::forward<T>(t),
715 InstResult::ResultType::Scalar));
716 }
717 }
718
719 /** Full vector result. */
720 template<typename T>
721 void
722 setVecResult(T &&t)
723 {
724 if (instFlags[RecordResult]) {
725 instResult.push(InstResult(std::forward<T>(t),
726 InstResult::ResultType::VecReg));
727 }
728 }
729
730 /** Vector element result. */
731 template<typename T>
732 void
733 setVecElemResult(T &&t)
734 {
735 if (instFlags[RecordResult]) {
736 instResult.push(InstResult(std::forward<T>(t),
737 InstResult::ResultType::VecElem));
738 }
739 }
740
741 /** Predicate result. */
742 template<typename T>
743 void
744 setVecPredResult(T &&t)
745 {
746 if (instFlags[RecordResult]) {
747 instResult.push(InstResult(std::forward<T>(t),
748 InstResult::ResultType::VecPredReg));
749 }
750 }
751 /** @} */
752
753 /** Records an integer register being set to a value. */
754 void
755 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
756 {
757 setScalarResult(val);
758 }
759
760 /** Records a CC register being set to a value. */
761 void
762 setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
763 {
764 setScalarResult(val);
765 }
766
767 /** Record a vector register being set to a value */
768 void
769 setVecRegOperand(const StaticInst *si, int idx,
770 const VecRegContainer &val) override
771 {
772 setVecResult(val);
773 }
774
775 /** Records an fp register being set to an integer value. */
776 void
777 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
778 {
779 setScalarResult(val);
780 }
781
782 /** Record a vector register being set to a value */
783 void
784 setVecElemOperand(const StaticInst *si, int idx,
785 const VecElem val) override
786 {
787 setVecElemResult(val);
788 }
789
790 /** Record a vector register being set to a value */
791 void
792 setVecPredRegOperand(const StaticInst *si, int idx,
793 const VecPredRegContainer &val) override
794 {
795 setVecPredResult(val);
796 }
797
798 /** Records that one of the source registers is ready. */
799 void markSrcRegReady();
800
801 /** Marks a specific register as ready. */
802 void markSrcRegReady(RegIndex src_idx);
803
804 /** Returns if a source register is ready. */
805 bool
806 isReadySrcRegIdx(int idx) const
807 {
808 return this->_readySrcRegIdx[idx];
809 }
810
811 /** Sets this instruction as completed. */
812 void setCompleted() { status.set(Completed); }
813
814 /** Returns whether or not this instruction is completed. */
815 bool isCompleted() const { return status[Completed]; }
816
817 /** Marks the result as ready. */
818 void setResultReady() { status.set(ResultReady); }
819
820 /** Returns whether or not the result is ready. */
821 bool isResultReady() const { return status[ResultReady]; }
822
823 /** Sets this instruction as ready to issue. */
824 void setCanIssue() { status.set(CanIssue); }
825
826 /** Returns whether or not this instruction is ready to issue. */
827 bool readyToIssue() const { return status[CanIssue]; }
828
829 /** Clears this instruction being able to issue. */
830 void clearCanIssue() { status.reset(CanIssue); }
831
832 /** Sets this instruction as issued from the IQ. */
833 void setIssued() { status.set(Issued); }
834
835 /** Returns whether or not this instruction has issued. */
836 bool isIssued() const { return status[Issued]; }
837
838 /** Clears this instruction as being issued. */
839 void clearIssued() { status.reset(Issued); }
840
841 /** Sets this instruction as executed. */
842 void setExecuted() { status.set(Executed); }
843
844 /** Returns whether or not this instruction has executed. */
845 bool isExecuted() const { return status[Executed]; }
846
847 /** Sets this instruction as ready to commit. */
848 void setCanCommit() { status.set(CanCommit); }
849
850 /** Clears this instruction as being ready to commit. */
851 void clearCanCommit() { status.reset(CanCommit); }
852
853 /** Returns whether or not this instruction is ready to commit. */
854 bool readyToCommit() const { return status[CanCommit]; }
855
856 void setAtCommit() { status.set(AtCommit); }
857
858 bool isAtCommit() { return status[AtCommit]; }
859
860 /** Sets this instruction as committed. */
861 void setCommitted() { status.set(Committed); }
862
863 /** Returns whether or not this instruction is committed. */
864 bool isCommitted() const { return status[Committed]; }
865
866 /** Sets this instruction as squashed. */
867 void setSquashed();
868
869 /** Returns whether or not this instruction is squashed. */
870 bool isSquashed() const { return status[Squashed]; }
871
872 //Instruction Queue Entry
873 //-----------------------
874 /** Sets this instruction as a entry the IQ. */
875 void setInIQ() { status.set(IqEntry); }
876
877 /** Sets this instruction as a entry the IQ. */
878 void clearInIQ() { status.reset(IqEntry); }
879
880 /** Returns whether or not this instruction has issued. */
881 bool isInIQ() const { return status[IqEntry]; }
882
883 /** Sets this instruction as squashed in the IQ. */
884 void setSquashedInIQ() { status.set(SquashedInIQ); status.set(Squashed);}
885
886 /** Returns whether or not this instruction is squashed in the IQ. */
887 bool isSquashedInIQ() const { return status[SquashedInIQ]; }
888
889
890 //Load / Store Queue Functions
891 //-----------------------
892 /** Sets this instruction as a entry the LSQ. */
893 void setInLSQ() { status.set(LsqEntry); }
894
895 /** Sets this instruction as a entry the LSQ. */
896 void removeInLSQ() { status.reset(LsqEntry); }
897
898 /** Returns whether or not this instruction is in the LSQ. */
899 bool isInLSQ() const { return status[LsqEntry]; }
900
901 /** Sets this instruction as squashed in the LSQ. */
902 void setSquashedInLSQ() { status.set(SquashedInLSQ); status.set(Squashed);}
903
904 /** Returns whether or not this instruction is squashed in the LSQ. */
905 bool isSquashedInLSQ() const { return status[SquashedInLSQ]; }
906
907
908 //Reorder Buffer Functions
909 //-----------------------
910 /** Sets this instruction as a entry the ROB. */
911 void setInROB() { status.set(RobEntry); }
912
913 /** Sets this instruction as a entry the ROB. */
914 void clearInROB() { status.reset(RobEntry); }
915
916 /** Returns whether or not this instruction is in the ROB. */
917 bool isInROB() const { return status[RobEntry]; }
918
919 /** Sets this instruction as squashed in the ROB. */
920 void setSquashedInROB() { status.set(SquashedInROB); }
921
922 /** Returns whether or not this instruction is squashed in the ROB. */
923 bool isSquashedInROB() const { return status[SquashedInROB]; }
924
925 /** Returns whether pinned registers are renamed */
926 bool isPinnedRegsRenamed() const { return status[PinnedRegsRenamed]; }
927
928 /** Sets the destination registers as renamed */
929 void
930 setPinnedRegsRenamed()
931 {
932 assert(!status[PinnedRegsSquashDone]);
933 assert(!status[PinnedRegsWritten]);
934 status.set(PinnedRegsRenamed);
935 }
936
937 /** Returns whether destination registers are written */
938 bool isPinnedRegsWritten() const { return status[PinnedRegsWritten]; }
939
940 /** Sets destination registers as written */
941 void
942 setPinnedRegsWritten()
943 {
944 assert(!status[PinnedRegsSquashDone]);
945 assert(status[PinnedRegsRenamed]);
946 status.set(PinnedRegsWritten);
947 }
948
949 /** Return whether dest registers' pinning status updated after squash */
950 bool
951 isPinnedRegsSquashDone() const { return status[PinnedRegsSquashDone]; }
952
953 /** Sets dest registers' status updated after squash */
954 void
955 setPinnedRegsSquashDone() {
956 assert(!status[PinnedRegsSquashDone]);
957 status.set(PinnedRegsSquashDone);
958 }
959
960 /** Read the PC state of this instruction. */
961 TheISA::PCState pcState() const override { return pc; }
962
963 /** Set the PC state of this instruction. */
964 void pcState(const TheISA::PCState &val) override { pc = val; }
965
966 /** Read the PC of this instruction. */
967 Addr instAddr() const { return pc.instAddr(); }
968
969 /** Read the PC of the next instruction. */
970 Addr nextInstAddr() const { return pc.nextInstAddr(); }
971
972 /**Read the micro PC of this instruction. */
973 Addr microPC() const { return pc.microPC(); }
974
975 bool readPredicate() const override { return instFlags[Predicate]; }
976
977 void
978 setPredicate(bool val) override
979 {
980 instFlags[Predicate] = val;
981
982 if (traceData) {
983 traceData->setPredicate(val);
984 }
985 }
986
987 bool
988 readMemAccPredicate() const override
989 {
990 return instFlags[MemAccPredicate];
991 }
992
993 void
994 setMemAccPredicate(bool val) override
995 {
996 instFlags[MemAccPredicate] = val;
997 }
998
999 /** Sets the thread id. */
1000 void setTid(ThreadID tid) { threadNumber = tid; }
1001
1002 /** Sets the pointer to the thread state. */
1003 void setThreadState(ImplState *state) { thread = state; }
1004
1005 /** Returns the thread context. */
1006 ThreadContext *tcBase() const override { return thread->getTC(); }
1007
1008 public:
1009 /** Returns whether or not the eff. addr. source registers are ready. */
1010 bool eaSrcsReady() const;
1011
1012 /** Is this instruction's memory access strictly ordered? */
1013 bool strictlyOrdered() const { return instFlags[IsStrictlyOrdered]; }
1014 void strictlyOrdered(bool so) { instFlags[IsStrictlyOrdered] = so; }
1015
1016 /** Has this instruction generated a memory request. */
1017 bool hasRequest() const { return instFlags[ReqMade]; }
1018 /** Assert this instruction has generated a memory request. */
1019 void setRequest() { instFlags[ReqMade] = true; }
1020
1021 /** Returns iterator to this instruction in the list of all insts. */
1022 ListIt &getInstListIt() { return instListIt; }
1023
1024 /** Sets iterator for this instruction in the list of all insts. */
1025 void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; }
1026
1027 public:
1028 /** Returns the number of consecutive store conditional failures. */
1029 unsigned int
1030 readStCondFailures() const override
1031 {
1032 return thread->storeCondFailures;
1033 }
1034
1035 /** Sets the number of consecutive store conditional failures. */
1036 void
1037 setStCondFailures(unsigned int sc_failures) override
1038 {
1039 thread->storeCondFailures = sc_failures;
1040 }
1041
1042 public:
1043 // monitor/mwait funtions
1044 void
1045 armMonitor(Addr address) override
1046 {
1047 cpu->armMonitor(threadNumber, address);
1048 }
1049 bool
1050 mwait(PacketPtr pkt) override
1051 {
1052 return cpu->mwait(threadNumber, pkt);
1053 }
1054 void
1055 mwaitAtomic(ThreadContext *tc) override
1056 {
1057 return cpu->mwaitAtomic(threadNumber, tc, cpu->dtb);
1058 }
1059 AddressMonitor *
1060 getAddrMonitor() override
1061 {
1062 return cpu->getCpuAddrMonitor(threadNumber);
1063 }
1064 };
1065
1066 template<class Impl>
1067 Fault
1068 BaseDynInst<Impl>::initiateMemRead(Addr addr, unsigned size,
1069 Request::Flags flags,
1070 const std::vector<bool> &byte_enable)
1071 {
1072 assert(byte_enable.empty() || byte_enable.size() == size);
1073 return cpu->pushRequest(
1074 dynamic_cast<typename DynInstPtr::PtrType>(this),
1075 /* ld */ true, nullptr, size, addr, flags, nullptr, nullptr,
1076 byte_enable);
1077 }
1078
1079 template<class Impl>
1080 Fault
1081 BaseDynInst<Impl>::initiateHtmCmd(Request::Flags flags)
1082 {
1083 return cpu->pushRequest(
1084 dynamic_cast<typename DynInstPtr::PtrType>(this),
1085 /* ld */ true, nullptr, 8, 0x0ul, flags, nullptr, nullptr);
1086 }
1087
1088 template<class Impl>
1089 Fault
1090 BaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size, Addr addr,
1091 Request::Flags flags, uint64_t *res,
1092 const std::vector<bool> &byte_enable)
1093 {
1094 assert(byte_enable.empty() || byte_enable.size() == size);
1095 return cpu->pushRequest(
1096 dynamic_cast<typename DynInstPtr::PtrType>(this),
1097 /* st */ false, data, size, addr, flags, res, nullptr,
1098 byte_enable);
1099 }
1100
1101 template<class Impl>
1102 Fault
1103 BaseDynInst<Impl>::initiateMemAMO(Addr addr, unsigned size,
1104 Request::Flags flags,
1105 AtomicOpFunctorPtr amo_op)
1106 {
1107 // atomic memory instructions do not have data to be written to memory yet
1108 // since the atomic operations will be executed directly in cache/memory.
1109 // Therefore, its `data` field is nullptr.
1110 // Atomic memory requests need to carry their `amo_op` fields to cache/
1111 // memory
1112 return cpu->pushRequest(
1113 dynamic_cast<typename DynInstPtr::PtrType>(this),
1114 /* atomic */ false, nullptr, size, addr, flags, nullptr,
1115 std::move(amo_op));
1116 }
1117
1118 #endif // __CPU_BASE_DYN_INST_HH__