gem5  [DEVELOP-FOR-23.0]
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
commit.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2014 Google, Inc.
3  * Copyright (c) 2010-2014, 2017, 2020 ARM Limited
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-2005 The Regents of The University of Michigan
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 #include "cpu/o3/commit.hh"
43 
44 #include <algorithm>
45 #include <set>
46 #include <string>
47 
48 #include "base/compiler.hh"
49 #include "base/loader/symtab.hh"
50 #include "base/logging.hh"
51 #include "cpu/base.hh"
52 #include "cpu/checker/cpu.hh"
53 #include "cpu/exetrace.hh"
54 #include "cpu/o3/cpu.hh"
55 #include "cpu/o3/dyn_inst.hh"
56 #include "cpu/o3/limits.hh"
57 #include "cpu/o3/thread_state.hh"
58 #include "cpu/timebuf.hh"
59 #include "debug/Activity.hh"
60 #include "debug/Commit.hh"
61 #include "debug/CommitRate.hh"
62 #include "debug/Drain.hh"
63 #include "debug/ExecFaulting.hh"
64 #include "debug/HtmCpu.hh"
65 #include "debug/O3PipeView.hh"
66 #include "params/BaseO3CPU.hh"
67 #include "sim/faults.hh"
68 #include "sim/full_system.hh"
69 
70 namespace gem5
71 {
72 
73 namespace o3
74 {
75 
76 void
78 {
79  // This will get reset by commit if it was switched out at the
80  // time of this event processing.
81  trapSquash[tid] = true;
82 }
83 
84 Commit::Commit(CPU *_cpu, const BaseO3CPUParams &params)
85  : commitPolicy(params.smtCommitPolicy),
86  cpu(_cpu),
87  iewToCommitDelay(params.iewToCommitDelay),
88  commitToIEWDelay(params.commitToIEWDelay),
89  renameToROBDelay(params.renameToROBDelay),
90  fetchToCommitDelay(params.commitToFetchDelay),
91  renameWidth(params.renameWidth),
92  commitWidth(params.commitWidth),
93  numThreads(params.numThreads),
94  drainPending(false),
95  drainImminent(false),
96  trapLatency(params.trapLatency),
97  canHandleInterrupts(true),
98  avoidQuiesceLiveLock(false),
99  stats(_cpu, this)
100 {
101  if (commitWidth > MaxWidth)
102  fatal("commitWidth (%d) is larger than compiled limit (%d),\n"
103  "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
104  commitWidth, static_cast<int>(MaxWidth));
105 
106  _status = Active;
108 
109  if (commitPolicy == CommitPolicy::RoundRobin) {
110  //Set-Up Priority List
111  for (ThreadID tid = 0; tid < numThreads; tid++) {
112  priority_list.push_back(tid);
113  }
114  }
115 
116  for (ThreadID tid = 0; tid < MaxThreads; tid++) {
117  commitStatus[tid] = Idle;
118  changedROBNumEntries[tid] = false;
119  trapSquash[tid] = false;
120  tcSquash[tid] = false;
121  squashAfterInst[tid] = nullptr;
122  pc[tid].reset(params.isa[0]->newPCState());
123  youngestSeqNum[tid] = 0;
124  lastCommitedSeqNum[tid] = 0;
125  trapInFlight[tid] = false;
126  committedStores[tid] = false;
127  checkEmptyROB[tid] = false;
128  renameMap[tid] = nullptr;
129  htmStarts[tid] = 0;
130  htmStops[tid] = 0;
131  }
132  interrupt = NoFault;
133 }
134 
135 std::string Commit::name() const { return cpu->name() + ".commit"; }
136 
137 void
139 {
141  cpu->getProbeManager(), "Commit");
143  cpu->getProbeManager(), "CommitStall");
145  cpu->getProbeManager(), "Squash");
146 }
147 
149  : statistics::Group(cpu, "commit"),
150  ADD_STAT(commitSquashedInsts, statistics::units::Count::get(),
151  "The number of squashed insts skipped by commit"),
152  ADD_STAT(commitNonSpecStalls, statistics::units::Count::get(),
153  "The number of times commit has been forced to stall to "
154  "communicate backwards"),
155  ADD_STAT(branchMispredicts, statistics::units::Count::get(),
156  "The number of times a branch was mispredicted"),
157  ADD_STAT(numCommittedDist, statistics::units::Count::get(),
158  "Number of insts commited each cycle"),
159  ADD_STAT(amos, statistics::units::Count::get(),
160  "Number of atomic instructions committed"),
161  ADD_STAT(membars, statistics::units::Count::get(),
162  "Number of memory barriers committed"),
163  ADD_STAT(functionCalls, statistics::units::Count::get(),
164  "Number of function calls committed."),
165  ADD_STAT(committedInstType, statistics::units::Count::get(),
166  "Class of committed instruction"),
167  ADD_STAT(commitEligibleSamples, statistics::units::Cycle::get(),
168  "number cycles where commit BW limit reached")
169 {
170  using namespace statistics;
171 
175 
177  .init(0,commit->commitWidth,1)
179 
180  amos
181  .init(cpu->numThreads)
182  .flags(total);
183 
184  membars
185  .init(cpu->numThreads)
186  .flags(total);
187 
189  .init(commit->numThreads)
190  .flags(total);
191 
193  .init(commit->numThreads,enums::Num_OpClass)
194  .flags(total | pdf | dist);
195 
196  committedInstType.ysubnames(enums::OpClassStrings);
197 }
198 
199 void
201 {
202  thread = threads;
203 }
204 
205 void
207 {
208  timeBuffer = tb_ptr;
209 
210  // Setup wire to send information back to IEW.
211  toIEW = timeBuffer->getWire(0);
212 
213  // Setup wire to read data from IEW (for the ROB).
215 }
216 
217 void
219 {
220  fetchQueue = fq_ptr;
221 
222  // Setup wire to get instructions from rename (for the ROB).
224 }
225 
226 void
228 {
229  renameQueue = rq_ptr;
230 
231  // Setup wire to get instructions from rename (for the ROB).
233 }
234 
235 void
237 {
238  iewQueue = iq_ptr;
239 
240  // Setup wire to get instructions from IEW.
241  fromIEW = iewQueue->getWire(-iewToCommitDelay);
242 }
243 
244 void
246 {
247  iewStage = iew_stage;
248 }
249 
250 void
252 {
253  activeThreads = at_ptr;
254 }
255 
256 void
258 {
259  for (ThreadID tid = 0; tid < numThreads; tid++)
260  renameMap[tid] = &rm_ptr[tid];
261 }
262 
263 void Commit::setROB(ROB *rob_ptr) { rob = rob_ptr; }
264 
265 void
267 {
269  rob->resetEntries();
270 
271  // Broadcast the number of free entries.
272  for (ThreadID tid = 0; tid < numThreads; tid++) {
273  toIEW->commitInfo[tid].usedROB = true;
274  toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
275  toIEW->commitInfo[tid].emptyROB = true;
276  }
277 
278  // Commit must broadcast the number of free entries it has at the
279  // start of the simulation, so it starts as active.
281 
283 }
284 
285 void
287 {
288  commitStatus[tid] = Idle;
289  changedROBNumEntries[tid] = false;
290  checkEmptyROB[tid] = false;
291  trapInFlight[tid] = false;
292  committedStores[tid] = false;
293  trapSquash[tid] = false;
294  tcSquash[tid] = false;
295  pc[tid].reset(cpu->tcBase(tid)->getIsaPtr()->newPCState());
296  lastCommitedSeqNum[tid] = 0;
297  squashAfterInst[tid] = NULL;
298 }
299 
300 void Commit::drain() { drainPending = true; }
301 
302 void
304 {
305  drainPending = false;
306  drainImminent = false;
307 }
308 
309 void
311 {
312  assert(isDrained());
314 
315  // hardware transactional memory
316  // cannot drain partially through a transaction
317  for (ThreadID tid = 0; tid < numThreads; tid++) {
318  if (executingHtmTransaction(tid)) {
319  panic("cannot drain partially through a HTM transaction");
320  }
321  }
322 }
323 
324 bool
326 {
327  /* Make sure no one is executing microcode. There are two reasons
328  * for this:
329  * - Hardware virtualized CPUs can't switch into the middle of a
330  * microcode sequence.
331  * - The current fetch implementation will most likely get very
332  * confused if it tries to start fetching an instruction that
333  * is executing in the middle of a ucode sequence that changes
334  * address mappings. This can happen on for example x86.
335  */
336  for (ThreadID tid = 0; tid < numThreads; tid++) {
337  if (pc[tid]->microPC() != 0)
338  return false;
339  }
340 
341  /* Make sure that all instructions have finished committing before
342  * declaring the system as drained. We want the pipeline to be
343  * completely empty when we declare the CPU to be drained. This
344  * makes debugging easier since CPU handover and restoring from a
345  * checkpoint with a different CPU should have the same timing.
346  */
347  return rob->isEmpty() &&
348  interrupt == NoFault;
349 }
350 
351 void
353 {
354  _status = Active;
356  for (ThreadID tid = 0; tid < numThreads; tid++) {
357  commitStatus[tid] = Idle;
358  changedROBNumEntries[tid] = false;
359  trapSquash[tid] = false;
360  tcSquash[tid] = false;
361  squashAfterInst[tid] = NULL;
362  }
363  rob->takeOverFrom();
364 }
365 
366 void
368 {
369  std::list<ThreadID>::iterator thread_it = std::find(priority_list.begin(),
370  priority_list.end(), tid);
371 
372  if (thread_it != priority_list.end()) {
373  priority_list.erase(thread_it);
374  }
375 }
376 
377 bool
379 {
380  if (tid == InvalidThreadID)
381  return false;
382  else
383  return (htmStarts[tid] > htmStops[tid]);
384 }
385 
386 void
388 {
389  if (tid != InvalidThreadID)
390  {
391  htmStarts[tid] = 0;
392  htmStops[tid] = 0;
393  }
394 }
395 
396 
397 void
399 {
400  // reset ROB changed variable
401  std::list<ThreadID>::iterator threads = activeThreads->begin();
403 
404  while (threads != end) {
405  ThreadID tid = *threads++;
406 
407  changedROBNumEntries[tid] = false;
408 
409  // Also check if any of the threads has a trap pending
410  if (commitStatus[tid] == TrapPending ||
411  commitStatus[tid] == FetchTrapPending) {
413  }
414  }
415 
416  if (_nextStatus == Inactive && _status == Active) {
417  DPRINTF(Activity, "Deactivating stage.\n");
419  } else if (_nextStatus == Active && _status == Inactive) {
420  DPRINTF(Activity, "Activating stage.\n");
422  }
423 
425 }
426 
427 bool
429 {
430  std::list<ThreadID>::iterator threads = activeThreads->begin();
432 
433  while (threads != end) {
434  ThreadID tid = *threads++;
435 
436  if (changedROBNumEntries[tid]) {
437  return true;
438  }
439  }
440 
441  return false;
442 }
443 
444 size_t
446 {
447  return rob->numFreeEntries(tid);
448 }
449 
450 void
452 {
453  DPRINTF(Commit, "Generating trap event for [tid:%i]\n", tid);
454 
456  [this, tid]{ processTrapEvent(tid); },
457  "Trap", true, Event::CPU_Tick_Pri);
458 
459  Cycles latency = std::dynamic_pointer_cast<SyscallRetryFault>(inst_fault) ?
461 
462  // hardware transactional memory
463  if (inst_fault != nullptr &&
464  std::dynamic_pointer_cast<GenericHtmFailureFault>(inst_fault)) {
465  // TODO
466  // latency = default abort/restore latency
467  // could also do some kind of exponential back off if desired
468  }
469 
470  cpu->schedule(trap, cpu->clockEdge(latency));
471  trapInFlight[tid] = true;
472  thread[tid]->trapPending = true;
473 }
474 
475 void
477 {
478  assert(!trapInFlight[tid]);
479  DPRINTF(Commit, "Generating TC squash event for [tid:%i]\n", tid);
480 
481  tcSquash[tid] = true;
482 }
483 
484 void
486 {
487  // If we want to include the squashing instruction in the squash,
488  // then use one older sequence number.
489  // Hopefully this doesn't mess things up. Basically I want to squash
490  // all instructions of this thread.
491  InstSeqNum squashed_inst = rob->isEmpty(tid) ?
492  lastCommitedSeqNum[tid] : rob->readHeadInst(tid)->seqNum - 1;
493 
494  // All younger instructions will be squashed. Set the sequence
495  // number as the youngest instruction in the ROB (0 in this case.
496  // Hopefully nothing breaks.)
498 
499  rob->squash(squashed_inst, tid);
500  changedROBNumEntries[tid] = true;
501 
502  // Send back the sequence number of the squashed instruction.
503  toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
504 
505  // Send back the squash signal to tell stages that they should
506  // squash.
507  toIEW->commitInfo[tid].squash = true;
508 
509  // Send back the rob squashing signal so other stages know that
510  // the ROB is in the process of squashing.
511  toIEW->commitInfo[tid].robSquashing = true;
512 
513  toIEW->commitInfo[tid].mispredictInst = NULL;
514  toIEW->commitInfo[tid].squashInst = NULL;
515 
516  set(toIEW->commitInfo[tid].pc, pc[tid]);
517 }
518 
519 void
521 {
522  squashAll(tid);
523 
524  DPRINTF(Commit, "Squashing from trap, restarting at PC %s\n", *pc[tid]);
525 
526  thread[tid]->trapPending = false;
527  thread[tid]->noSquashFromTC = false;
528  trapInFlight[tid] = false;
529 
530  trapSquash[tid] = false;
531 
532  commitStatus[tid] = ROBSquashing;
534 }
535 
536 void
538 {
539  squashAll(tid);
540 
541  DPRINTF(Commit, "Squashing from TC, restarting at PC %s\n", *pc[tid]);
542 
543  thread[tid]->noSquashFromTC = false;
544  assert(!thread[tid]->trapPending);
545 
546  commitStatus[tid] = ROBSquashing;
548 
549  tcSquash[tid] = false;
550 }
551 
552 void
554 {
555  DPRINTF(Commit, "Squashing after squash after request, "
556  "restarting at PC %s\n", *pc[tid]);
557 
558  squashAll(tid);
559  // Make sure to inform the fetch stage of which instruction caused
560  // the squash. It'll try to re-fetch an instruction executing in
561  // microcode unless this is set.
562  toIEW->commitInfo[tid].squashInst = squashAfterInst[tid];
563  squashAfterInst[tid] = NULL;
564 
565  commitStatus[tid] = ROBSquashing;
567 }
568 
569 void
571 {
572  DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%llu]\n",
573  tid, head_inst->seqNum);
574 
575  assert(!squashAfterInst[tid] || squashAfterInst[tid] == head_inst);
577  squashAfterInst[tid] = head_inst;
578 }
579 
580 void
582 {
583  wroteToTimeBuffer = false;
585 
586  if (activeThreads->empty())
587  return;
588 
589  std::list<ThreadID>::iterator threads = activeThreads->begin();
591 
592  // Check if any of the threads are done squashing. Change the
593  // status if they are done.
594  while (threads != end) {
595  ThreadID tid = *threads++;
596 
597  // Clear the bit saying if the thread has committed stores
598  // this cycle.
599  committedStores[tid] = false;
600 
601  if (commitStatus[tid] == ROBSquashing) {
602 
603  if (rob->isDoneSquashing(tid)) {
604  commitStatus[tid] = Running;
605  } else {
606  DPRINTF(Commit,"[tid:%i] Still Squashing, cannot commit any"
607  " insts this cycle.\n", tid);
608  rob->doSquash(tid);
609  toIEW->commitInfo[tid].robSquashing = true;
610  wroteToTimeBuffer = true;
611  }
612  }
613  }
614 
615  commit();
616 
618 
619  threads = activeThreads->begin();
620 
621  while (threads != end) {
622  ThreadID tid = *threads++;
623 
624  if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
625  // The ROB has more instructions it can commit. Its next status
626  // will be active.
628 
629  [[maybe_unused]] const DynInstPtr &inst = rob->readHeadInst(tid);
630 
631  DPRINTF(Commit,"[tid:%i] Instruction [sn:%llu] PC %s is head of"
632  " ROB and ready to commit\n",
633  tid, inst->seqNum, inst->pcState());
634 
635  } else if (!rob->isEmpty(tid)) {
636  const DynInstPtr &inst = rob->readHeadInst(tid);
637 
638  ppCommitStall->notify(inst);
639 
640  DPRINTF(Commit,"[tid:%i] Can't commit, Instruction [sn:%llu] PC "
641  "%s is head of ROB and not ready\n",
642  tid, inst->seqNum, inst->pcState());
643  }
644 
645  DPRINTF(Commit, "[tid:%i] ROB has %d insts & %d free entries.\n",
646  tid, rob->countInsts(tid), rob->numFreeEntries(tid));
647  }
648 
649 
650  if (wroteToTimeBuffer) {
651  DPRINTF(Activity, "Activity This Cycle.\n");
653  }
654 
655  updateStatus();
656 }
657 
658 void
660 {
661  // Verify that we still have an interrupt to handle
662  if (!cpu->checkInterrupts(0)) {
663  DPRINTF(Commit, "Pending interrupt is cleared by requestor before "
664  "it got handled. Restart fetching from the orig path.\n");
665  toIEW->commitInfo[0].clearInterrupt = true;
666  interrupt = NoFault;
667  avoidQuiesceLiveLock = true;
668  return;
669  }
670 
671  // Wait until all in flight instructions are finished before enterring
672  // the interrupt.
673  if (canHandleInterrupts && cpu->instList.empty()) {
674  // Squash or record that I need to squash this cycle if
675  // an interrupt needed to be handled.
676  DPRINTF(Commit, "Interrupt detected.\n");
677 
678  // Clear the interrupt now that it's going to be handled
679  toIEW->commitInfo[0].clearInterrupt = true;
680 
681  assert(!thread[0]->noSquashFromTC);
682  thread[0]->noSquashFromTC = true;
683 
684  if (cpu->checker) {
685  cpu->checker->handlePendingInt();
686  }
687 
688  // CPU will handle interrupt. Note that we ignore the local copy of
689  // interrupt. This is because the local copy may no longer be the
690  // interrupt that the interrupt controller thinks is being handled.
692 
693  thread[0]->noSquashFromTC = false;
694 
696 
697  interrupt = NoFault;
698 
699  // Generate trap squash event.
701 
702  avoidQuiesceLiveLock = false;
703  } else {
704  DPRINTF(Commit, "Interrupt pending: instruction is %sin "
705  "flight, ROB is %sempty\n",
706  canHandleInterrupts ? "not " : "",
707  cpu->instList.empty() ? "" : "not " );
708  }
709 }
710 
711 void
713 {
714  // Don't propagate intterupts if we are currently handling a trap or
715  // in draining and the last observable instruction has been committed.
716  if (commitStatus[0] == TrapPending || interrupt || trapSquash[0] ||
717  tcSquash[0] || drainImminent)
718  return;
719 
720  // Process interrupts if interrupts are enabled, not in PAL
721  // mode, and no other traps or external squashes are currently
722  // pending.
723  // @todo: Allow other threads to handle interrupts.
724 
725  // Get any interrupt that happened
727 
728  // Tell fetch that there is an interrupt pending. This
729  // will make fetch wait until it sees a non PAL-mode PC,
730  // at which point it stops fetching instructions.
731  if (interrupt != NoFault)
732  toIEW->commitInfo[0].interruptPending = true;
733 }
734 
735 void
737 {
738  if (FullSystem) {
739  // Check if we have a interrupt and get read to handle it
740  if (cpu->checkInterrupts(0))
742  }
743 
745  // Check for any possible squashes, handle them first
747  std::list<ThreadID>::iterator threads = activeThreads->begin();
749 
750  int num_squashing_threads = 0;
751 
752  while (threads != end) {
753  ThreadID tid = *threads++;
754 
755  // Not sure which one takes priority. I think if we have
756  // both, that's a bad sign.
757  if (trapSquash[tid]) {
758  assert(!tcSquash[tid]);
759  squashFromTrap(tid);
760 
761  // If the thread is trying to exit (i.e., an exit syscall was
762  // executed), this trapSquash was originated by the exit
763  // syscall earlier. In this case, schedule an exit event in
764  // the next cycle to fully terminate this thread
765  if (cpu->isThreadExiting(tid))
767  } else if (tcSquash[tid]) {
768  assert(commitStatus[tid] != TrapPending);
769  squashFromTC(tid);
770  } else if (commitStatus[tid] == SquashAfterPending) {
771  // A squash from the previous cycle of the commit stage (i.e.,
772  // commitInsts() called squashAfter) is pending. Squash the
773  // thread now.
775  }
776 
777  // Squashed sequence number must be older than youngest valid
778  // instruction in the ROB. This prevents squashes from younger
779  // instructions overriding squashes from older instructions.
780  if (fromIEW->squash[tid] &&
781  commitStatus[tid] != TrapPending &&
782  fromIEW->squashedSeqNum[tid] <= youngestSeqNum[tid]) {
783 
784  if (fromIEW->mispredictInst[tid]) {
785  DPRINTF(Commit,
786  "[tid:%i] Squashing due to branch mispred "
787  "PC:%#x [sn:%llu]\n",
788  tid,
789  fromIEW->mispredictInst[tid]->pcState().instAddr(),
790  fromIEW->squashedSeqNum[tid]);
791  } else {
792  DPRINTF(Commit,
793  "[tid:%i] Squashing due to order violation [sn:%llu]\n",
794  tid, fromIEW->squashedSeqNum[tid]);
795  }
796 
797  DPRINTF(Commit, "[tid:%i] Redirecting to PC %#x\n",
798  tid, *fromIEW->pc[tid]);
799 
800  commitStatus[tid] = ROBSquashing;
801 
802  // If we want to include the squashing instruction in the squash,
803  // then use one older sequence number.
804  InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];
805 
806  if (fromIEW->includeSquashInst[tid]) {
807  squashed_inst--;
808  }
809 
810  // All younger instructions will be squashed. Set the sequence
811  // number as the youngest instruction in the ROB.
812  youngestSeqNum[tid] = squashed_inst;
813 
814  rob->squash(squashed_inst, tid);
815  changedROBNumEntries[tid] = true;
816 
817  toIEW->commitInfo[tid].doneSeqNum = squashed_inst;
818 
819  toIEW->commitInfo[tid].squash = true;
820 
821  // Send back the rob squashing signal so other stages know that
822  // the ROB is in the process of squashing.
823  toIEW->commitInfo[tid].robSquashing = true;
824 
825  toIEW->commitInfo[tid].mispredictInst =
826  fromIEW->mispredictInst[tid];
827  toIEW->commitInfo[tid].branchTaken =
828  fromIEW->branchTaken[tid];
829  toIEW->commitInfo[tid].squashInst =
830  rob->findInst(tid, squashed_inst);
831  if (toIEW->commitInfo[tid].mispredictInst) {
832  if (toIEW->commitInfo[tid].mispredictInst->isUncondCtrl()) {
833  toIEW->commitInfo[tid].branchTaken = true;
834  }
835  ++stats.branchMispredicts;
836  }
837 
838  set(toIEW->commitInfo[tid].pc, fromIEW->pc[tid]);
839  }
840 
841  if (commitStatus[tid] == ROBSquashing) {
842  num_squashing_threads++;
843  }
844  }
845 
846  // If commit is currently squashing, then it will have activity for the
847  // next cycle. Set its next status as active.
848  if (num_squashing_threads) {
850  }
851 
852  if (num_squashing_threads != numThreads) {
853  // If we're not currently squashing, then get instructions.
854  getInsts();
855 
856  // Try to commit any instructions.
857  commitInsts();
858  }
859 
860  //Check for any activity
861  threads = activeThreads->begin();
862 
863  while (threads != end) {
864  ThreadID tid = *threads++;
865 
866  if (changedROBNumEntries[tid]) {
867  toIEW->commitInfo[tid].usedROB = true;
868  toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
869 
870  wroteToTimeBuffer = true;
871  changedROBNumEntries[tid] = false;
872  if (rob->isEmpty(tid))
873  checkEmptyROB[tid] = true;
874  }
875 
876  // ROB is only considered "empty" for previous stages if: a)
877  // ROB is empty, b) there are no outstanding stores, c) IEW
878  // stage has received any information regarding stores that
879  // committed.
880  // c) is checked by making sure to not consider the ROB empty
881  // on the same cycle as when stores have been committed.
882  // @todo: Make this handle multi-cycle communication between
883  // commit and IEW.
884  if (checkEmptyROB[tid] && rob->isEmpty(tid) &&
885  !iewStage->hasStoresToWB(tid) && !committedStores[tid]) {
886  checkEmptyROB[tid] = false;
887  toIEW->commitInfo[tid].usedROB = true;
888  toIEW->commitInfo[tid].emptyROB = true;
889  toIEW->commitInfo[tid].freeROBEntries = rob->numFreeEntries(tid);
890  wroteToTimeBuffer = true;
891  }
892 
893  }
894 }
895 
896 void
898 {
900  // Handle commit
901  // Note that commit will be handled prior to putting new
902  // instructions in the ROB so that the ROB only tries to commit
903  // instructions it has in this current cycle, and not instructions
904  // it is writing in during this cycle. Can't commit and squash
905  // things at the same time...
907 
908  DPRINTF(Commit, "Trying to commit instructions in the ROB.\n");
909 
910  unsigned num_committed = 0;
911 
912  DynInstPtr head_inst;
913 
914  // Commit as many instructions as possible until the commit bandwidth
915  // limit is reached, or it becomes impossible to commit any more.
916  while (num_committed < commitWidth) {
917  // hardware transactionally memory
918  // If executing within a transaction,
919  // need to handle interrupts specially
920 
921  ThreadID commit_thread = getCommittingThread();
922 
923  // Check for any interrupt that we've already squashed for
924  // and start processing it.
925  if (interrupt != NoFault) {
926  // If inside a transaction, postpone interrupts
927  if (executingHtmTransaction(commit_thread)) {
928  cpu->clearInterrupts(0);
929  toIEW->commitInfo[0].clearInterrupt = true;
930  interrupt = NoFault;
931  avoidQuiesceLiveLock = true;
932  } else {
933  handleInterrupt();
934  }
935  }
936 
937  // ThreadID commit_thread = getCommittingThread();
938 
939  if (commit_thread == -1 || !rob->isHeadReady(commit_thread))
940  break;
941 
942  head_inst = rob->readHeadInst(commit_thread);
943 
944  ThreadID tid = head_inst->threadNumber;
945 
946  assert(tid == commit_thread);
947 
948  DPRINTF(Commit,
949  "Trying to commit head instruction, [tid:%i] [sn:%llu]\n",
950  tid, head_inst->seqNum);
951 
952  // If the head instruction is squashed, it is ready to retire
953  // (be removed from the ROB) at any time.
954  if (head_inst->isSquashed()) {
955 
956  DPRINTF(Commit, "Retiring squashed instruction from "
957  "ROB.\n");
958 
959  rob->retireHead(commit_thread);
960 
961  ++stats.commitSquashedInsts;
962  // Notify potential listeners that this instruction is squashed
963  ppSquash->notify(head_inst);
964 
965  // Record that the number of ROB entries has changed.
966  changedROBNumEntries[tid] = true;
967  } else {
968  set(pc[tid], head_inst->pcState());
969 
970  // Try to commit the head instruction.
971  bool commit_success = commitHead(head_inst, num_committed);
972 
973  if (commit_success) {
974  ++num_committed;
975  cpu->commitStats[tid]
976  ->committedInstType[head_inst->opClass()]++;
977  stats.committedInstType[tid][head_inst->opClass()]++;
978  ppCommit->notify(head_inst);
979 
980  // hardware transactional memory
981 
982  // update nesting depth
983  if (head_inst->isHtmStart())
984  htmStarts[tid]++;
985 
986  // sanity check
987  if (head_inst->inHtmTransactionalState()) {
988  assert(executingHtmTransaction(tid));
989  } else {
990  assert(!executingHtmTransaction(tid));
991  }
992 
993  // update nesting depth
994  if (head_inst->isHtmStop())
995  htmStops[tid]++;
996 
997  changedROBNumEntries[tid] = true;
998 
999  // Set the doneSeqNum to the youngest committed instruction.
1000  toIEW->commitInfo[tid].doneSeqNum = head_inst->seqNum;
1001 
1002  if (tid == 0)
1003  canHandleInterrupts = !head_inst->isDelayedCommit();
1004 
1005  // at this point store conditionals should either have
1006  // been completed or predicated false
1007  assert(!head_inst->isStoreConditional() ||
1008  head_inst->isCompleted() ||
1009  !head_inst->readPredicate());
1010 
1011  // Updates misc. registers.
1012  head_inst->updateMiscRegs();
1013 
1014  // Check instruction execution if it successfully commits and
1015  // is not carrying a fault.
1016  if (cpu->checker) {
1017  cpu->checker->verify(head_inst);
1018  }
1019 
1020  cpu->traceFunctions(pc[tid]->instAddr());
1021 
1022  head_inst->staticInst->advancePC(*pc[tid]);
1023 
1024  // Keep track of the last sequence number commited
1025  lastCommitedSeqNum[tid] = head_inst->seqNum;
1026 
1027  // If this is an instruction that doesn't play nicely with
1028  // others squash everything and restart fetch
1029  if (head_inst->isSquashAfter())
1030  squashAfter(tid, head_inst);
1031 
1032  if (drainPending) {
1033  if (pc[tid]->microPC() == 0 && interrupt == NoFault &&
1034  !thread[tid]->trapPending) {
1035  // Last architectually committed instruction.
1036  // Squash the pipeline, stall fetch, and use
1037  // drainImminent to disable interrupts
1038  DPRINTF(Drain, "Draining: %i:%s\n", tid, *pc[tid]);
1039  squashAfter(tid, head_inst);
1040  cpu->commitDrained(tid);
1041  drainImminent = true;
1042  }
1043  }
1044 
1045  bool onInstBoundary = !head_inst->isMicroop() ||
1046  head_inst->isLastMicroop() ||
1047  !head_inst->isDelayedCommit();
1048 
1049  if (onInstBoundary) {
1050  int count = 0;
1051  Addr oldpc;
1052  // Make sure we're not currently updating state while
1053  // handling PC events.
1054  assert(!thread[tid]->noSquashFromTC &&
1055  !thread[tid]->trapPending);
1056  do {
1057  oldpc = pc[tid]->instAddr();
1058  thread[tid]->pcEventQueue.service(
1059  oldpc, thread[tid]->getTC());
1060  count++;
1061  } while (oldpc != pc[tid]->instAddr());
1062  if (count > 1) {
1063  DPRINTF(Commit,
1064  "PC skip function event, stopping commit\n");
1065  break;
1066  }
1067  }
1068 
1069  // Check if an instruction just enabled interrupts and we've
1070  // previously had an interrupt pending that was not handled
1071  // because interrupts were subsequently disabled before the
1072  // pipeline reached a place to handle the interrupt. In that
1073  // case squash now to make sure the interrupt is handled.
1074  //
1075  // If we don't do this, we might end up in a live lock
1076  // situation.
1077  if (!interrupt && avoidQuiesceLiveLock &&
1078  onInstBoundary && cpu->checkInterrupts(0))
1079  squashAfter(tid, head_inst);
1080  } else {
1081  DPRINTF(Commit, "Unable to commit head instruction PC:%s "
1082  "[tid:%i] [sn:%llu].\n",
1083  head_inst->pcState(), tid ,head_inst->seqNum);
1084  break;
1085  }
1086  }
1087  }
1088 
1089  DPRINTF(CommitRate, "%i\n", num_committed);
1090  stats.numCommittedDist.sample(num_committed);
1091 
1092  if (num_committed == commitWidth) {
1093  stats.commitEligibleSamples++;
1094  }
1095 }
1096 
1097 bool
1098 Commit::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
1099 {
1100  assert(head_inst);
1101 
1102  ThreadID tid = head_inst->threadNumber;
1103 
1104  // If the instruction is not executed yet, then it will need extra
1105  // handling. Signal backwards that it should be executed.
1106  if (!head_inst->isExecuted()) {
1107  // Make sure we are only trying to commit un-executed instructions we
1108  // think are possible.
1109  assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
1110  || head_inst->isReadBarrier() || head_inst->isWriteBarrier()
1111  || head_inst->isAtomic()
1112  || (head_inst->isLoad() && head_inst->strictlyOrdered()));
1113 
1114  DPRINTF(Commit,
1115  "Encountered a barrier or non-speculative "
1116  "instruction [tid:%i] [sn:%llu] "
1117  "at the head of the ROB, PC %s.\n",
1118  tid, head_inst->seqNum, head_inst->pcState());
1119 
1120  if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
1121  DPRINTF(Commit,
1122  "[tid:%i] [sn:%llu] "
1123  "Waiting for all stores to writeback.\n",
1124  tid, head_inst->seqNum);
1125  return false;
1126  }
1127 
1128  toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
1129 
1130  // Change the instruction so it won't try to commit again until
1131  // it is executed.
1132  head_inst->clearCanCommit();
1133 
1134  if (head_inst->isLoad() && head_inst->strictlyOrdered()) {
1135  DPRINTF(Commit, "[tid:%i] [sn:%llu] "
1136  "Strictly ordered load, PC %s.\n",
1137  tid, head_inst->seqNum, head_inst->pcState());
1138  toIEW->commitInfo[tid].strictlyOrdered = true;
1139  toIEW->commitInfo[tid].strictlyOrderedLoad = head_inst;
1140  } else {
1141  ++stats.commitNonSpecStalls;
1142  }
1143 
1144  return false;
1145  }
1146 
1147  // Check if the instruction caused a fault. If so, trap.
1148  Fault inst_fault = head_inst->getFault();
1149 
1150  // hardware transactional memory
1151  // if a fault occurred within a HTM transaction
1152  // ensure that the transaction aborts
1153  if (inst_fault != NoFault && head_inst->inHtmTransactionalState()) {
1154  // There exists a generic HTM fault common to all ISAs
1155  if (!std::dynamic_pointer_cast<GenericHtmFailureFault>(inst_fault)) {
1156  DPRINTF(HtmCpu, "%s - fault (%s) encountered within transaction"
1157  " - converting to GenericHtmFailureFault\n",
1158  head_inst->staticInst->getName(), inst_fault->name());
1159  inst_fault = std::make_shared<GenericHtmFailureFault>(
1160  head_inst->getHtmTransactionUid(),
1162  }
1163  // If this point is reached and the fault inherits from the HTM fault,
1164  // then there is no need to raise a new fault
1165  }
1166 
1167  // Stores mark themselves as completed.
1168  if (!head_inst->isStore() && inst_fault == NoFault) {
1169  head_inst->setCompleted();
1170  }
1171 
1172  if (inst_fault != NoFault) {
1173  DPRINTF(Commit, "Inst [tid:%i] [sn:%llu] PC %s has a fault\n",
1174  tid, head_inst->seqNum, head_inst->pcState());
1175 
1176  if (iewStage->hasStoresToWB(tid) || inst_num > 0) {
1177  DPRINTF(Commit,
1178  "[tid:%i] [sn:%llu] "
1179  "Stores outstanding, fault must wait.\n",
1180  tid, head_inst->seqNum);
1181  return false;
1182  }
1183 
1184  head_inst->setCompleted();
1185 
1186  // If instruction has faulted, let the checker execute it and
1187  // check if it sees the same fault and control flow.
1188  if (cpu->checker) {
1189  // Need to check the instruction before its fault is processed
1190  cpu->checker->verify(head_inst);
1191  }
1192 
1193  assert(!thread[tid]->noSquashFromTC);
1194 
1195  // Mark that we're in state update mode so that the trap's
1196  // execution doesn't generate extra squashes.
1197  thread[tid]->noSquashFromTC = true;
1198 
1199  // Execute the trap. Although it's slightly unrealistic in
1200  // terms of timing (as it doesn't wait for the full timing of
1201  // the trap event to complete before updating state), it's
1202  // needed to update the state as soon as possible. This
1203  // prevents external agents from changing any specific state
1204  // that the trap need.
1205  cpu->trap(inst_fault, tid,
1206  head_inst->notAnInst() ? nullStaticInstPtr :
1207  head_inst->staticInst);
1208 
1209  // Exit state update mode to avoid accidental updating.
1210  thread[tid]->noSquashFromTC = false;
1211 
1212  commitStatus[tid] = TrapPending;
1213 
1214  DPRINTF(Commit,
1215  "[tid:%i] [sn:%llu] Committing instruction with fault\n",
1216  tid, head_inst->seqNum);
1217  if (head_inst->traceData) {
1218  // We ignore ReExecution "faults" here as they are not real
1219  // (architectural) faults but signal flush/replays.
1220  if (debug::ExecFaulting
1221  && dynamic_cast<ReExec*>(inst_fault.get()) == nullptr) {
1222 
1223  head_inst->traceData->setFaulting(true);
1224  head_inst->traceData->setFetchSeq(head_inst->seqNum);
1225  head_inst->traceData->setCPSeq(thread[tid]->numOp);
1226  head_inst->traceData->dump();
1227  }
1228  delete head_inst->traceData;
1229  head_inst->traceData = NULL;
1230  }
1231 
1232  // Generate trap squash event.
1233  generateTrapEvent(tid, inst_fault);
1234  return false;
1235  }
1236 
1237  updateComInstStats(head_inst);
1238 
1239  DPRINTF(Commit,
1240  "[tid:%i] [sn:%llu] Committing instruction with PC %s\n",
1241  tid, head_inst->seqNum, head_inst->pcState());
1242  if (head_inst->traceData) {
1243  head_inst->traceData->setFetchSeq(head_inst->seqNum);
1244  head_inst->traceData->setCPSeq(thread[tid]->numOp);
1245  head_inst->traceData->dump();
1246  delete head_inst->traceData;
1247  head_inst->traceData = NULL;
1248  }
1249  if (head_inst->isReturn()) {
1250  DPRINTF(Commit,
1251  "[tid:%i] [sn:%llu] Return Instruction Committed PC %s \n",
1252  tid, head_inst->seqNum, head_inst->pcState());
1253  }
1254 
1255  // Update the commit rename map
1256  for (int i = 0; i < head_inst->numDestRegs(); i++) {
1257  renameMap[tid]->setEntry(head_inst->flattenedDestIdx(i),
1258  head_inst->renamedDestIdx(i));
1259  }
1260 
1261  // hardware transactional memory
1262  // the HTM UID is purely for correctness and debugging purposes
1263  if (head_inst->isHtmStart())
1264  iewStage->setLastRetiredHtmUid(tid, head_inst->getHtmTransactionUid());
1265 
1266  // Finally clear the head ROB entry.
1267  rob->retireHead(tid);
1268 
1269 #if TRACING_ON
1270  if (debug::O3PipeView) {
1271  head_inst->commitTick = curTick() - head_inst->fetchTick;
1272  }
1273 #endif
1274 
1275  // If this was a store, record it for this cycle.
1276  if (head_inst->isStore() || head_inst->isAtomic())
1277  committedStores[tid] = true;
1278 
1279  // Return true to indicate that we have committed an instruction.
1280  return true;
1281 }
1282 
1283 void
1285 {
1286  DPRINTF(Commit, "Getting instructions from Rename stage.\n");
1287 
1288  // Read any renamed instructions and place them into the ROB.
1289  int insts_to_process = std::min((int)renameWidth, fromRename->size);
1290 
1291  for (int inst_num = 0; inst_num < insts_to_process; ++inst_num) {
1292  const DynInstPtr &inst = fromRename->insts[inst_num];
1293  ThreadID tid = inst->threadNumber;
1294 
1295  if (!inst->isSquashed() &&
1296  commitStatus[tid] != ROBSquashing &&
1297  commitStatus[tid] != TrapPending) {
1298  changedROBNumEntries[tid] = true;
1299 
1300  DPRINTF(Commit, "[tid:%i] [sn:%llu] Inserting PC %s into ROB.\n",
1301  tid, inst->seqNum, inst->pcState());
1302 
1303  rob->insertInst(inst);
1304 
1305  assert(rob->getThreadEntries(tid) <= rob->getMaxEntries(tid));
1306 
1307  youngestSeqNum[tid] = inst->seqNum;
1308  } else {
1309  DPRINTF(Commit, "[tid:%i] [sn:%llu] "
1310  "Instruction PC %s was squashed, skipping.\n",
1311  tid, inst->seqNum, inst->pcState());
1312  }
1313  }
1314 }
1315 
1316 void
1318 {
1319  // Grab completed insts out of the IEW instruction queue, and mark
1320  // instructions completed within the ROB.
1321  for (int inst_num = 0; inst_num < fromIEW->size; ++inst_num) {
1322  assert(fromIEW->insts[inst_num]);
1323  if (!fromIEW->insts[inst_num]->isSquashed()) {
1324  DPRINTF(Commit, "[tid:%i] Marking PC %s, [sn:%llu] ready "
1325  "within ROB.\n",
1326  fromIEW->insts[inst_num]->threadNumber,
1327  fromIEW->insts[inst_num]->pcState(),
1328  fromIEW->insts[inst_num]->seqNum);
1329 
1330  // Mark the instruction as ready to commit.
1331  fromIEW->insts[inst_num]->setCanCommit();
1332  }
1333  }
1334 }
1335 
1336 void
1338 {
1339  ThreadID tid = inst->threadNumber;
1340 
1341  if (!inst->isMicroop() || inst->isLastMicroop()) {
1342  cpu->commitStats[tid]->numInsts++;
1343  cpu->baseStats.numInsts++;
1344  }
1345  cpu->commitStats[tid]->numOps++;
1346 
1347  // To match the old model, don't count nops and instruction
1348  // prefetches towards the total commit count.
1349  if (!inst->isNop() && !inst->isInstPrefetch()) {
1350  cpu->instDone(tid, inst);
1351  }
1352 
1353  //
1354  // Control Instructions
1355  //
1356  cpu->commitStats[tid]->updateComCtrlStats(inst->staticInst);
1357 
1358  //
1359  // Memory references
1360  //
1361  if (inst->isMemRef()) {
1362  cpu->commitStats[tid]->numMemRefs++;
1363 
1364  if (inst->isLoad()) {
1365  cpu->commitStats[tid]->numLoadInsts++;
1366  }
1367 
1368  if (inst->isStore()) {
1369  cpu->commitStats[tid]->numStoreInsts++;
1370  }
1371  }
1372 
1373  if (inst->isFullMemBarrier()) {
1374  stats.membars[tid]++;
1375  }
1376 
1377  // Integer Instruction
1378  if (inst->isInteger()) {
1379  cpu->commitStats[tid]->numIntInsts++;
1380  }
1381 
1382  // Floating Point Instruction
1383  if (inst->isFloating()) {
1384  cpu->commitStats[tid]->numFpInsts++;
1385  }
1386  // Vector Instruction
1387  if (inst->isVector()) {
1388  cpu->commitStats[tid]->numVecInsts++;
1389  }
1390 
1391  // Function Calls
1392  if (inst->isCall())
1393  stats.functionCalls[tid]++;
1394 
1395 }
1396 
1398 // //
1399 // SMT COMMIT POLICY MAINTAINED HERE //
1400 // //
1402 ThreadID
1404 {
1405  if (numThreads > 1) {
1406  switch (commitPolicy) {
1407  case CommitPolicy::RoundRobin:
1408  return roundRobin();
1409 
1410  case CommitPolicy::OldestReady:
1411  return oldestReady();
1412 
1413  default:
1414  return InvalidThreadID;
1415  }
1416  } else {
1417  assert(!activeThreads->empty());
1418  ThreadID tid = activeThreads->front();
1419 
1420  if (commitStatus[tid] == Running ||
1421  commitStatus[tid] == Idle ||
1422  commitStatus[tid] == FetchTrapPending) {
1423  return tid;
1424  } else {
1425  return InvalidThreadID;
1426  }
1427  }
1428 }
1429 
1430 ThreadID
1432 {
1433  std::list<ThreadID>::iterator pri_iter = priority_list.begin();
1435 
1436  while (pri_iter != end) {
1437  ThreadID tid = *pri_iter;
1438 
1439  if (commitStatus[tid] == Running ||
1440  commitStatus[tid] == Idle ||
1441  commitStatus[tid] == FetchTrapPending) {
1442 
1443  if (rob->isHeadReady(tid)) {
1444  priority_list.erase(pri_iter);
1445  priority_list.push_back(tid);
1446 
1447  return tid;
1448  }
1449  }
1450 
1451  pri_iter++;
1452  }
1453 
1454  return InvalidThreadID;
1455 }
1456 
1457 ThreadID
1459 {
1460  unsigned oldest = 0;
1461  unsigned oldest_seq_num = 0;
1462  bool first = true;
1463 
1464  std::list<ThreadID>::iterator threads = activeThreads->begin();
1466 
1467  while (threads != end) {
1468  ThreadID tid = *threads++;
1469 
1470  if (!rob->isEmpty(tid) &&
1471  (commitStatus[tid] == Running ||
1472  commitStatus[tid] == Idle ||
1473  commitStatus[tid] == FetchTrapPending)) {
1474 
1475  if (rob->isHeadReady(tid)) {
1476 
1477  const DynInstPtr &head_inst = rob->readHeadInst(tid);
1478 
1479  if (first) {
1480  oldest = tid;
1481  oldest_seq_num = head_inst->seqNum;
1482  first = false;
1483  } else if (head_inst->seqNum < oldest_seq_num) {
1484  oldest = tid;
1485  oldest_seq_num = head_inst->seqNum;
1486  }
1487  }
1488  }
1489  }
1490 
1491  if (!first) {
1492  return oldest;
1493  } else {
1494  return InvalidThreadID;
1495  }
1496 }
1497 
1498 } // namespace o3
1499 } // namespace gem5
gem5::o3::Commit::drainPending
bool drainPending
Is a drain pending? Commit is looking for an instruction boundary while there are no pending interrup...
Definition: commit.hh:404
gem5::o3::Commit::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition: commit.cc:251
gem5::o3::Commit::renameMap
UnifiedRenameMap * renameMap[MaxThreads]
Rename map interface.
Definition: commit.hh:446
gem5::o3::Commit::setROB
void setROB(ROB *rob_ptr)
Sets pointer to the ROB.
Definition: commit.cc:263
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::o3::Commit::TrapPending
@ TrapPending
Definition: commit.hh:109
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:200
gem5::o3::Commit::fetchToCommitDelay
const Cycles fetchToCommitDelay
Definition: commit.hh:388
gem5::o3::ROB::doSquash
void doSquash(ThreadID tid)
Executes the squash, marking squashed instructions.
Definition: rob.cc:309
gem5::o3::Commit::takeOverFrom
void takeOverFrom()
Takes over from another CPU's thread.
Definition: commit.cc:352
gem5::o3::Commit::Commit
Commit(CPU *_cpu, const BaseO3CPUParams &params)
Construct a Commit with the given parameters.
Definition: commit.cc:84
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
gem5::o3::Commit::squashFromTC
void squashFromTC(ThreadID tid)
Handles squashing due to an TC write.
Definition: commit.cc:537
gem5::o3::ROB::squash
void squash(InstSeqNum squash_num, ThreadID tid)
Squashes all instructions younger than the given sequence number for the specific thread.
Definition: rob.cc:473
gem5::o3::Commit::regProbePoints
void regProbePoints()
Registers probes.
Definition: commit.cc:138
commit.hh
gem5::o3::Commit::renameWidth
const unsigned renameWidth
Rename width, in instructions.
Definition: commit.hh:393
gem5::o3::Commit::setIEWQueue
void setIEWQueue(TimeBuffer< IEWStruct > *iq_ptr)
Sets the pointer to the queue coming from IEW.
Definition: commit.cc:236
gem5::o3::Commit::CommitStats::numCommittedDist
statistics::Distribution numCommittedDist
Distribution of the number of committed instructions each cycle.
Definition: commit.hh:480
gem5::o3::Commit::drain
void drain()
Initializes the draining of commit.
Definition: commit.cc:300
gem5::MipsISA::misc_reg::Count
@ Count
Definition: misc.hh:94
gem5::o3::Commit::CommitStats::committedInstType
statistics::Vector2d committedInstType
Committed instructions by instruction type (OpClass)
Definition: commit.hh:489
gem5::o3::Commit::renameQueue
TimeBuffer< RenameStruct > * renameQueue
Rename instruction queue interface, for ROB.
Definition: commit.hh:335
gem5::o3::Commit::ppSquash
ProbePointArg< DynInstPtr > * ppSquash
To probe when an instruction is squashed.
Definition: commit.hh:128
gem5::o3::Commit::squashAfterInst
DynInstPtr squashAfterInst[MaxThreads]
Instruction passed to squashAfter().
Definition: commit.hh:374
gem5::statistics::Vector2dBase::init
Derived & init(size_type _x, size_type _y)
Definition: statistics.hh:1173
gem5::o3::Commit::setThreads
void setThreads(std::vector< ThreadState * > &threads)
Sets the list of threads.
Definition: commit.cc:200
gem5::o3::Commit::timeBuffer
TimeBuffer< TimeStruct > * timeBuffer
Time buffer interface.
Definition: commit.hh:316
gem5::o3::Commit::fromIEW
TimeBuffer< IEWStruct >::wire fromIEW
Wire to read information from IEW queue.
Definition: commit.hh:332
gem5::o3::CPU::processInterrupts
void processInterrupts(const Fault &interrupt)
Processes any an interrupt fault.
Definition: cpu.cc:674
gem5::o3::CPU::getInterrupts
Fault getInterrupts()
Returns the Fault for any valid interrupt.
Definition: cpu.cc:667
gem5::ArmISA::set
Bitfield< 12, 11 > set
Definition: misc_types.hh:760
gem5::o3::Commit::priority_list
std::list< ThreadID > priority_list
Priority List used for Commit Policy.
Definition: commit.hh:377
gem5::o3::Commit::wroteToTimeBuffer
bool wroteToTimeBuffer
Records that commit has written to the time buffer this cycle.
Definition: commit.hh:354
gem5::o3::ROB::insertInst
void insertInst(const DynInstPtr &inst)
Function to insert an instruction into the ROB.
Definition: rob.cc:197
gem5::o3::Commit::changedROBEntries
bool changedROBEntries()
Returns if any of the threads have the number of ROB entries changed on this cycle.
Definition: commit.cc:428
gem5::o3::Commit::startupStage
void startupStage()
Initializes stage by sending back the number of free entries.
Definition: commit.cc:266
gem5::o3::ROB::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: rob.cc:134
exetrace.hh
gem5::o3::Commit::setRenameMap
void setRenameMap(UnifiedRenameMap rm_ptr[MaxThreads])
Sets pointer to the commited state rename map.
Definition: commit.cc:257
gem5::o3::Commit::commitInsts
void commitInsts()
Commits as many instructions as possible.
Definition: commit.cc:897
gem5::o3::Commit::ppCommit
ProbePointArg< DynInstPtr > * ppCommit
Probe Points.
Definition: commit.hh:125
gem5::o3::ROB::isDoneSquashing
bool isDoneSquashing(ThreadID tid) const
Reads the PC of the oldest head instruction.
Definition: rob.hh:249
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1012
std::vector
STL vector class.
Definition: stl.hh:37
dyn_inst.hh
gem5::BaseCPU::commitStats
std::vector< std::unique_ptr< CommitCPUStats > > commitStats
Definition: base.hh:821
gem5::o3::CPU::instList
std::list< DynInstPtr > instList
List of all the instructions in flight.
Definition: cpu.hh:381
gem5::o3::Commit::FetchTrapPending
@ FetchTrapPending
Definition: commit.hh:110
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
faults.hh
gem5::o3::Commit::squashFromSquashAfter
void squashFromSquashAfter(ThreadID tid)
Handles a squash from a squashAfter() request.
Definition: commit.cc:553
gem5::o3::ROB::numFreeEntries
unsigned numFreeEntries()
Returns the number of total free entries in the ROB.
Definition: rob.cc:297
gem5::o3::Commit::setRenameQueue
void setRenameQueue(TimeBuffer< RenameStruct > *rq_ptr)
Sets the pointer to the queue coming from rename.
Definition: commit.cc:227
gem5::o3::Commit::committedStores
bool committedStores[MaxThreads]
Records if there were any stores committed this cycle.
Definition: commit.hh:436
gem5::o3::Commit::generateTrapEvent
void generateTrapEvent(ThreadID tid, Fault inst_fault)
Generates an event to schedule a squash due to a trap.
Definition: commit.cc:451
gem5::o3::Commit::deactivateThread
void deactivateThread(ThreadID tid)
Deschedules a thread from scheduling.
Definition: commit.cc:367
gem5::o3::ROB::resetEntries
void resetEntries()
Re-adjust ROB partitioning.
Definition: rob.cc:148
gem5::statistics::dist
const FlagsType dist
Print the distribution.
Definition: info.hh:65
gem5::RefCountingPtr< DynInst >
gem5::TimeBuffer
Definition: timebuf.hh:40
gem5::o3::Commit::numROBFreeEntries
size_t numROBFreeEntries(ThreadID tid)
Returns the number of free ROB entries for a specific thread.
Definition: commit.cc:445
gem5::o3::CPU::checker
gem5::Checker< DynInstPtr > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
Definition: cpu.hh:524
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
gem5::o3::Commit::htmStarts
int htmStarts[MaxThreads]
Definition: commit.hh:461
gem5::o3::ROB::getMaxEntries
unsigned getMaxEntries(ThreadID tid)
Returns the maximum number of entries for a specific thread.
Definition: rob.hh:178
gem5::o3::CPU::deactivateStage
void deactivateStage(const StageIdx idx)
Changes a stage's status to inactive within the activity recorder.
Definition: cpu.hh:496
gem5::HtmFailureFaultCause::EXCEPTION
@ EXCEPTION
gem5::o3::Commit::name
std::string name() const
Returns the name of the Commit.
Definition: commit.cc:135
gem5::o3::Commit::CommitStats::branchMispredicts
statistics::Scalar branchMispredicts
Stat for the total number of branch mispredicts that caused a squash.
Definition: commit.hh:478
gem5::o3::Commit::iewStage
IEW * iewStage
The pointer to the IEW stage.
Definition: commit.hh:164
gem5::statistics::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:61
timebuf.hh
gem5::BaseCPU::numThreads
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:384
gem5::o3::Commit::activeThreads
std::list< ThreadID > * activeThreads
Pointer to the list of active threads.
Definition: commit.hh:443
gem5::o3::Commit::changedROBNumEntries
bool changedROBNumEntries[MaxThreads]
Records if the number of ROB entries has changed this cycle.
Definition: commit.hh:359
gem5::o3::Commit::iewQueue
TimeBuffer< IEWStruct > * iewQueue
IEW instruction queue interface.
Definition: commit.hh:329
gem5::nullStaticInstPtr
const StaticInstPtr nullStaticInstPtr
Statically allocated null StaticInstPtr.
Definition: null_static_inst.cc:36
gem5::o3::Commit::generateTCEvent
void generateTCEvent(ThreadID tid)
Records that commit needs to initiate a squash due to an external state update through the TC.
Definition: commit.cc:476
gem5::BaseCPU::baseStats
gem5::BaseCPU::BaseCPUStats baseStats
gem5::o3::Commit::renameToROBDelay
const Cycles renameToROBDelay
Rename to ROB delay.
Definition: commit.hh:386
gem5::o3::Commit::squashAll
void squashAll(ThreadID tid)
Squashes all in flight instructions.
Definition: commit.cc:485
gem5::o3::CPU
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition: cpu.hh:93
gem5::statistics::Distribution::init
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
Definition: statistics.hh:2112
gem5::o3::Commit
Commit handles single threaded and SMT commit.
Definition: commit.hh:91
gem5::o3::Commit::propagateInterrupt
void propagateInterrupt()
Get fetch redirecting so we can handle an interrupt.
Definition: commit.cc:712
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
gem5::BaseISA::newPCState
virtual PCStateBase * newPCState(Addr new_inst_addr=0) const =0
gem5::o3::Commit::Running
@ Running
Definition: commit.hh:106
gem5::o3::Commit::processTrapEvent
void processTrapEvent(ThreadID tid)
Mark the thread as processing a trap.
Definition: commit.cc:77
gem5::o3::Commit::isDrained
bool isDrained() const
Has the stage drained?
Definition: commit.cc:325
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:210
gem5::o3::Commit::rob
ROB * rob
ROB interface.
Definition: commit.hh:342
gem5::o3::Commit::commitStatus
ThreadStatus commitStatus[MaxThreads]
Per-thread status.
Definition: commit.hh:120
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::o3::Commit::roundRobin
ThreadID roundRobin()
Returns the thread ID to use based on a round robin policy.
Definition: commit.cc:1431
gem5::X86ISA::count
count
Definition: misc.hh:710
gem5::o3::Commit::Active
@ Active
Definition: commit.hh:99
gem5::o3::Commit::getInsts
void getInsts()
Gets instructions from rename and inserts them into the ROB.
Definition: commit.cc:1284
gem5::o3::ROB::readHeadInst
const DynInstPtr & readHeadInst(ThreadID tid)
Returns pointer to the head instruction within the ROB.
Definition: rob.cc:502
gem5::o3::Commit::avoidQuiesceLiveLock
bool avoidQuiesceLiveLock
Have we had an interrupt pending and then seen it de-asserted because of a masking change?...
Definition: commit.hh:455
gem5::o3::Commit::htmStops
int htmStops[MaxThreads]
Definition: commit.hh:462
gem5::o3::Commit::ROBSquashing
@ ROBSquashing
Definition: commit.hh:108
gem5::o3::CPU::scheduleThreadExitEvent
void scheduleThreadExitEvent(ThreadID tid)
If a thread is trying to exit and its corresponding trap event has been completed,...
Definition: cpu.cc:1385
gem5::o3::CPU::CommitIdx
@ CommitIdx
Definition: cpu.hh:457
gem5::o3::IEW
IEW handles both single threaded and SMT IEW (issue/execute/writeback).
Definition: iew.hh:87
cpu.hh
gem5::o3::Commit::pc
std::unique_ptr< PCStateBase > pc[MaxThreads]
The commit PC state of each thread.
Definition: commit.hh:424
gem5::o3::Commit::commitHead
bool commitHead(const DynInstPtr &head_inst, unsigned inst_num)
Tries to commit the head ROB instruction passed in.
Definition: commit.cc:1098
gem5::o3::CPU::activateStage
void activateStage(const StageIdx idx)
Changes a stage's status to active within the activity recorder.
Definition: cpu.hh:489
gem5::o3::Commit::toIEW
TimeBuffer< TimeStruct >::wire toIEW
Wire to write information heading to previous stages.
Definition: commit.hh:319
gem5::o3::Commit::resetHtmStartsStops
void resetHtmStartsStops(ThreadID)
Definition: commit.cc:387
gem5::ReExec
Definition: faults.hh:92
gem5::o3::CPU::tcBase
gem5::ThreadContext * tcBase(ThreadID tid)
Returns a pointer to a thread context.
Definition: cpu.hh:512
gem5::o3::Commit::squashAfter
void squashAfter(ThreadID tid, const DynInstPtr &head_inst)
Handle squashing from instruction with SquashAfter set.
Definition: commit.cc:570
gem5::o3::Commit::oldestReady
ThreadID oldestReady()
Returns the thread ID to use based on an oldest instruction policy.
Definition: commit.cc:1458
gem5::o3::ROB::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to the list of active threads.
Definition: rob.cc:127
gem5::o3::Commit::CommitStats::commitSquashedInsts
statistics::Scalar commitSquashedInsts
Stat for the total number of squashed instructions discarded by commit.
Definition: commit.hh:470
gem5::o3::Commit::commitWidth
const unsigned commitWidth
Commit width, in instructions.
Definition: commit.hh:396
gem5::o3::Commit::clearStates
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: commit.cc:286
thread_state.hh
gem5::InvalidThreadID
const ThreadID InvalidThreadID
Definition: types.hh:236
gem5::o3::MaxWidth
static constexpr int MaxWidth
Definition: limits.hh:37
gem5::o3::Commit::thread
std::vector< ThreadState * > thread
Vector of all of the threads.
Definition: commit.hh:349
compiler.hh
gem5::o3::Commit::cpu
CPU * cpu
Pointer to O3CPU.
Definition: commit.hh:346
gem5::o3::ROB::isHeadReady
bool isHeadReady(ThreadID tid)
Is the oldest instruction across all threads ready.
Definition: rob.cc:268
gem5::o3::Commit::checkEmptyROB
bool checkEmptyROB[MaxThreads]
Records if commit should check if the ROB is truly empty (see commit_impl.hh).
Definition: commit.hh:440
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::o3::Commit::fromFetch
TimeBuffer< FetchStruct >::wire fromFetch
Definition: commit.hh:326
gem5::o3::Commit::updateComInstStats
void updateComInstStats(const DynInstPtr &inst)
Updates commit stats based on this instruction.
Definition: commit.cc:1337
gem5::Clocked::clockEdge
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Definition: clocked_object.hh:177
full_system.hh
gem5::o3::Commit::getCommittingThread
ThreadID getCommittingThread()
Gets the thread to commit, based on the SMT policy.
Definition: commit.cc:1403
gem5::ProbePointArg
ProbePointArg generates a point for the class of Arg.
Definition: thermal_domain.hh:54
gem5::EventFunctionWrapper
Definition: eventq.hh:1136
gem5::o3::Commit::commit
void commit()
Handles any squashes that are sent from IEW, and adds instructions to the ROB and tries to commit ins...
Definition: commit.cc:736
gem5::FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
gem5::o3::ROB::getThreadEntries
unsigned getThreadEntries(ThreadID tid)
Returns the number of entries being used by a specific thread.
Definition: rob.hh:182
gem5::o3::IEW::setLastRetiredHtmUid
void setLastRetiredHtmUid(ThreadID tid, uint64_t htmUid)
Definition: iew.hh:234
gem5::SimObject::getProbeManager
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:117
gem5::o3::MaxThreads
static constexpr int MaxThreads
Definition: limits.hh:38
gem5::o3::CPU::activityThisCycle
void activityThisCycle()
Records that there was time buffer activity this cycle.
Definition: cpu.hh:485
gem5::o3::Commit::CommitStats::amos
statistics::Vector amos
Stat for the total number of committed atomics.
Definition: commit.hh:483
gem5::o3::Commit::drainResume
void drainResume()
Resumes execution after draining.
Definition: commit.cc:303
gem5::o3::ROB::findInst
DynInstPtr findInst(ThreadID tid, InstSeqNum squash_inst)
Returns a pointer to the instruction with the given sequence if it is in the ROB.
Definition: rob.cc:534
gem5::o3::Commit::executingHtmTransaction
bool executingHtmTransaction(ThreadID) const
Is the CPU currently processing a HTM transaction?
Definition: commit.cc:378
base.hh
gem5::BaseCPU::traceFunctions
void traceFunctions(Addr pc)
Definition: base.hh:601
gem5::statistics::DataWrap::prereq
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
Definition: statistics.hh:371
gem5::o3::CPU::commitDrained
void commitDrained(ThreadID tid)
Commit has reached a safe point to drain a thread.
Definition: cpu.cc:834
gem5::o3::Commit::SquashAfterPending
@ SquashAfterPending
Definition: commit.hh:111
gem5::o3::Commit::Idle
@ Idle
Definition: commit.hh:107
gem5::o3::CPU::trap
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
Definition: cpu.cc:690
gem5::BaseCPU::BaseCPUStats::numInsts
statistics::Scalar numInsts
Definition: base.hh:637
gem5::o3::Commit::interrupt
Fault interrupt
The interrupt fault.
Definition: commit.hh:419
gem5::BaseCPU::checkInterrupts
bool checkInterrupts(ThreadID tid) const
Definition: base.hh:254
gem5::o3::Commit::lastCommitedSeqNum
InstSeqNum lastCommitedSeqNum[MaxThreads]
The sequence number of the last commited instruction.
Definition: commit.hh:430
gem5::o3::ROB::isEmpty
bool isEmpty() const
Returns if the ROB is empty.
Definition: rob.hh:194
gem5::o3::Commit::setFetchQueue
void setFetchQueue(TimeBuffer< FetchStruct > *fq_ptr)
Definition: commit.cc:218
gem5::o3::Commit::trapSquash
bool trapSquash[MaxThreads]
Records if a thread has to squash this cycle due to a trap.
Definition: commit.hh:362
gem5::o3::CPU::isThreadExiting
bool isThreadExiting(ThreadID tid) const
Is the thread trying to exit?
Definition: cpu.cc:1379
gem5::o3::Commit::commitPolicy
CommitPolicy commitPolicy
Commit policy used in SMT mode.
Definition: commit.hh:122
gem5::o3::Commit::trapInFlight
bool trapInFlight[MaxThreads]
Records if there is a trap currently in flight.
Definition: commit.hh:433
gem5::o3::Commit::_status
CommitStatus _status
Overall commit status.
Definition: commit.hh:116
logging.hh
gem5::BaseCPU::syscallRetryLatency
Cycles syscallRetryLatency
Definition: base.hh:662
gem5::statistics::Group
Statistics container.
Definition: group.hh:92
gem5::o3::Commit::_nextStatus
CommitStatus _nextStatus
Next commit status, to be set at the end of the cycle.
Definition: commit.hh:118
gem5::statistics::Group::stats
std::vector< Info * > stats
Definition: group.hh:220
gem5::statistics::DataWrapVec2d::ysubnames
Derived & ysubnames(const char **names)
Definition: statistics.hh:477
gem5::InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:40
gem5::o3::ROB::retireHead
void retireHead(ThreadID tid)
Retires the head instruction, removing it from the ROB.
Definition: rob.cc:234
gem5::o3::Commit::CommitStats::CommitStats
CommitStats(CPU *cpu, Commit *commit)
Definition: commit.cc:148
gem5::o3::Commit::CommitStats::commitNonSpecStalls
statistics::Scalar commitNonSpecStalls
Stat for the total number of times commit has had to stall due to a non-speculative instruction reach...
Definition: commit.hh:474
gem5::o3::Commit::tick
void tick()
Ticks the commit stage, which tries to commit instructions.
Definition: commit.cc:581
gem5::o3::Commit::Inactive
@ Inactive
Definition: commit.hh:100
symtab.hh
gem5::statistics::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:357
gem5::ThreadContext::getIsaPtr
virtual BaseISA * getIsaPtr() const =0
gem5::o3::Commit::ppCommitStall
ProbePointArg< DynInstPtr > * ppCommitStall
Definition: commit.hh:126
cpu.hh
std::list< ThreadID >
gem5::EventBase::CPU_Tick_Pri
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Definition: eventq.hh:207
gem5::o3::Commit::youngestSeqNum
InstSeqNum youngestSeqNum[MaxThreads]
The sequence number of the youngest valid instruction in the ROB.
Definition: commit.hh:427
gem5::o3::Commit::CommitStats::functionCalls
statistics::Vector functionCalls
Total number of function calls.
Definition: commit.hh:487
gem5::o3::IEW::hasStoresToWB
bool hasStoresToWB()
Returns if the LSQ has any stores to writeback.
Definition: iew.hh:221
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::o3::ROB::countInsts
int countInsts()
This is more of a debugging function than anything.
Definition: rob.cc:180
gem5::o3::Commit::numThreads
const ThreadID numThreads
Number of Active Threads.
Definition: commit.hh:399
gem5::statistics::total
const FlagsType total
Print the total.
Definition: info.hh:59
limits.hh
gem5::statistics::VectorBase::init
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1039
gem5::o3::Commit::markCompletedInsts
void markCompletedInsts()
Marks completed instructions using information sent from IEW.
Definition: commit.cc:1317
gem5::o3::Commit::drainImminent
bool drainImminent
Is a drain imminent? Commit has found an instruction boundary while no interrupts were present or in ...
Definition: commit.hh:411
gem5::o3::Commit::updateStatus
void updateStatus()
Updates the overall status of commit with the nextStatus, and tell the CPU if commit is active/inacti...
Definition: commit.cc:398
gem5::o3::ROB
ROB class.
Definition: rob.hh:71
gem5::o3::Commit::setTimeBuffer
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main time buffer pointer, used for backwards communication.
Definition: commit.cc:206
gem5::BaseCPU::clearInterrupts
void clearInterrupts(ThreadID tid)
Definition: base.hh:248
gem5::o3::Commit::squashFromTrap
void squashFromTrap(ThreadID tid)
Handles squashing due to a trap.
Definition: commit.cc:520
gem5::o3::Commit::trapLatency
const Cycles trapLatency
The latency to handle a trap.
Definition: commit.hh:416
gem5::o3::Commit::canHandleInterrupts
bool canHandleInterrupts
True if last committed microop can be followed by an interrupt.
Definition: commit.hh:449
gem5::o3::Commit::handleInterrupt
void handleInterrupt()
Handles processing an interrupt.
Definition: commit.cc:659
gem5::o3::Commit::setIEWStage
void setIEWStage(IEW *iew_stage)
Sets the pointer to the IEW stage.
Definition: commit.cc:245
gem5::o3::Commit::fromRename
TimeBuffer< RenameStruct >::wire fromRename
Wire to read information from rename queue.
Definition: commit.hh:338
gem5::o3::Commit::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: commit.cc:310
gem5::o3::CPU::instDone
void instDone(ThreadID tid, const DynInstPtr &inst)
Function to tell the CPU that an instruction has completed.
Definition: cpu.cc:1123
gem5::ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
gem5::o3::ROB::takeOverFrom
void takeOverFrom()
Takes over another CPU's thread.
Definition: rob.cc:142
gem5::o3::Commit::CommitStats::membars
statistics::Vector membars
Total number of committed memory barriers.
Definition: commit.hh:485
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:188
gem5::o3::UnifiedRenameMap::setEntry
void setEntry(const RegId &arch_reg, PhysRegIdPtr phys_reg)
Update rename map with a specific mapping.
Definition: rename_map.hh:247
gem5::o3::UnifiedRenameMap
Unified register rename map for all classes of registers.
Definition: rename_map.hh:168
gem5::o3::Commit::iewToCommitDelay
const Cycles iewToCommitDelay
IEW to Commit delay.
Definition: commit.hh:380
gem5::o3::Commit::robInfoFromIEW
TimeBuffer< TimeStruct >::wire robInfoFromIEW
Wire to read information from IEW (for ROB).
Definition: commit.hh:322
gem5::o3::Commit::fetchQueue
TimeBuffer< FetchStruct > * fetchQueue
Definition: commit.hh:324
gem5::o3::Commit::tcSquash
bool tcSquash[MaxThreads]
Records if a thread has to squash this cycle due to an XC write.
Definition: commit.hh:365

Generated on Sun Jul 30 2023 01:56:52 for gem5 by doxygen 1.8.17