gem5  [DEVELOP-FOR-23.0]
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
rename.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2012, 2014-2019 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  * 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/rename.hh"
43 
44 #include <list>
45 
46 #include "cpu/o3/cpu.hh"
47 #include "cpu/o3/dyn_inst.hh"
48 #include "cpu/o3/limits.hh"
49 #include "cpu/reg_class.hh"
50 #include "debug/Activity.hh"
51 #include "debug/O3PipeView.hh"
52 #include "debug/Rename.hh"
53 #include "params/BaseO3CPU.hh"
54 
55 namespace gem5
56 {
57 
58 namespace o3
59 {
60 
61 Rename::Rename(CPU *_cpu, const BaseO3CPUParams &params)
62  : cpu(_cpu),
63  iewToRenameDelay(params.iewToRenameDelay),
64  decodeToRenameDelay(params.decodeToRenameDelay),
65  commitToRenameDelay(params.commitToRenameDelay),
66  renameWidth(params.renameWidth),
67  numThreads(params.numThreads),
68  stats(_cpu)
69 {
70  if (renameWidth > MaxWidth)
71  fatal("renameWidth (%d) is larger than compiled limit (%d),\n"
72  "\tincrease MaxWidth in src/cpu/o3/limits.hh\n",
73  renameWidth, static_cast<int>(MaxWidth));
74 
75  // @todo: Make into a parameter.
76  skidBufferMax = (decodeToRenameDelay + 1) * params.decodeWidth;
77  for (uint32_t tid = 0; tid < MaxThreads; tid++) {
78  renameStatus[tid] = Idle;
79  renameMap[tid] = nullptr;
80  instsInProgress[tid] = 0;
81  loadsInProgress[tid] = 0;
82  storesInProgress[tid] = 0;
83  freeEntries[tid] = {0, 0, 0, 0};
84  emptyROB[tid] = true;
85  stalls[tid] = {false, false};
86  serializeInst[tid] = nullptr;
87  serializeOnNextInst[tid] = false;
88  }
89 }
90 
91 std::string
92 Rename::name() const
93 {
94  return cpu->name() + ".rename";
95 }
96 
98  : statistics::Group(parent, "rename"),
99  ADD_STAT(squashCycles, statistics::units::Cycle::get(),
100  "Number of cycles rename is squashing"),
101  ADD_STAT(idleCycles, statistics::units::Cycle::get(),
102  "Number of cycles rename is idle"),
103  ADD_STAT(blockCycles, statistics::units::Cycle::get(),
104  "Number of cycles rename is blocking"),
105  ADD_STAT(serializeStallCycles, statistics::units::Cycle::get(),
106  "count of cycles rename stalled for serializing inst"),
107  ADD_STAT(runCycles, statistics::units::Cycle::get(),
108  "Number of cycles rename is running"),
109  ADD_STAT(unblockCycles, statistics::units::Cycle::get(),
110  "Number of cycles rename is unblocking"),
111  ADD_STAT(renamedInsts, statistics::units::Count::get(),
112  "Number of instructions processed by rename"),
113  ADD_STAT(squashedInsts, statistics::units::Count::get(),
114  "Number of squashed instructions processed by rename"),
115  ADD_STAT(ROBFullEvents, statistics::units::Count::get(),
116  "Number of times rename has blocked due to ROB full"),
117  ADD_STAT(IQFullEvents, statistics::units::Count::get(),
118  "Number of times rename has blocked due to IQ full"),
119  ADD_STAT(LQFullEvents, statistics::units::Count::get(),
120  "Number of times rename has blocked due to LQ full" ),
121  ADD_STAT(SQFullEvents, statistics::units::Count::get(),
122  "Number of times rename has blocked due to SQ full"),
123  ADD_STAT(fullRegistersEvents, statistics::units::Count::get(),
124  "Number of times there has been no free registers"),
125  ADD_STAT(renamedOperands, statistics::units::Count::get(),
126  "Number of destination operands rename has renamed"),
127  ADD_STAT(lookups, statistics::units::Count::get(),
128  "Number of register rename lookups that rename has made"),
129  ADD_STAT(intLookups, statistics::units::Count::get(),
130  "Number of integer rename lookups"),
131  ADD_STAT(fpLookups, statistics::units::Count::get(),
132  "Number of floating rename lookups"),
133  ADD_STAT(vecLookups, statistics::units::Count::get(),
134  "Number of vector rename lookups"),
135  ADD_STAT(vecPredLookups, statistics::units::Count::get(),
136  "Number of vector predicate rename lookups"),
137  ADD_STAT(matLookups, statistics::units::Count::get(),
138  "Number of matrix rename lookups"),
139  ADD_STAT(committedMaps, statistics::units::Count::get(),
140  "Number of HB maps that are committed"),
141  ADD_STAT(undoneMaps, statistics::units::Count::get(),
142  "Number of HB maps that are undone due to squashing"),
143  ADD_STAT(serializing, statistics::units::Count::get(),
144  "count of serializing insts renamed"),
145  ADD_STAT(tempSerializing, statistics::units::Count::get(),
146  "count of temporary serializing insts renamed"),
147  ADD_STAT(skidInsts, statistics::units::Count::get(),
148  "count of insts added to the skid buffer")
149 {
156 
159 
165 
173 
179 }
180 
181 void
183 {
185  cpu->getProbeManager(), "Rename");
187  "SquashInRename");
188 }
189 
190 void
192 {
193  timeBuffer = tb_ptr;
194 
195  // Setup wire to read information from time buffer, from IEW stage.
196  fromIEW = timeBuffer->getWire(-iewToRenameDelay);
197 
198  // Setup wire to read infromation from time buffer, from commit stage.
200 
201  // Setup wire to write information to previous stages.
202  toDecode = timeBuffer->getWire(0);
203 }
204 
205 void
207 {
208  renameQueue = rq_ptr;
209 
210  // Setup wire to write information to future stages.
211  toIEW = renameQueue->getWire(0);
212 }
213 
214 void
216 {
217  decodeQueue = dq_ptr;
218 
219  // Setup wire to get information from decode.
221 }
222 
223 void
225 {
226  resetStage();
227 }
228 
229 void
231 {
232  renameStatus[tid] = Idle;
233 
238  emptyROB[tid] = true;
239 
240  stalls[tid].iew = false;
241  serializeInst[tid] = NULL;
242 
243  instsInProgress[tid] = 0;
244  loadsInProgress[tid] = 0;
245  storesInProgress[tid] = 0;
246 
247  serializeOnNextInst[tid] = false;
248 }
249 
250 void
252 {
253  _status = Inactive;
254 
255  resumeSerialize = false;
256  resumeUnblocking = false;
257 
258  // Grab the number of free entries directly from the stages.
259  for (ThreadID tid = 0; tid < numThreads; tid++) {
260  renameStatus[tid] = Idle;
261 
263  freeEntries[tid].lqEntries =
265  freeEntries[tid].sqEntries =
268  emptyROB[tid] = true;
269 
270  stalls[tid].iew = false;
271  serializeInst[tid] = NULL;
272 
273  instsInProgress[tid] = 0;
274  loadsInProgress[tid] = 0;
275  storesInProgress[tid] = 0;
276 
277  serializeOnNextInst[tid] = false;
278  }
279 }
280 
281 void
283 {
284  activeThreads = at_ptr;
285 }
286 
287 
288 void
290 {
291  for (ThreadID tid = 0; tid < numThreads; tid++)
292  renameMap[tid] = &rm_ptr[tid];
293 }
294 
295 void
297 {
298  freeList = fl_ptr;
299 }
300 
301 void
303 {
304  scoreboard = _scoreboard;
305 }
306 
307 bool
309 {
310  for (ThreadID tid = 0; tid < numThreads; tid++) {
311  if (instsInProgress[tid] != 0 ||
312  !historyBuffer[tid].empty() ||
313  !skidBuffer[tid].empty() ||
314  !insts[tid].empty() ||
315  (renameStatus[tid] != Idle && renameStatus[tid] != Running))
316  return false;
317  }
318  return true;
319 }
320 
321 void
323 {
324  resetStage();
325 }
326 
327 void
329 {
330  for (ThreadID tid = 0; tid < numThreads; tid++) {
331  assert(historyBuffer[tid].empty());
332  assert(insts[tid].empty());
333  assert(skidBuffer[tid].empty());
334  assert(instsInProgress[tid] == 0);
335  }
336 }
337 
338 void
339 Rename::squash(const InstSeqNum &squash_seq_num, ThreadID tid)
340 {
341  DPRINTF(Rename, "[tid:%i] [squash sn:%llu] Squashing instructions.\n",
342  tid,squash_seq_num);
343 
344  // Clear the stall signal if rename was blocked or unblocking before.
345  // If it still needs to block, the blocking should happen the next
346  // cycle and there should be space to hold everything due to the squash.
347  if (renameStatus[tid] == Blocked ||
348  renameStatus[tid] == Unblocking) {
349  toDecode->renameUnblock[tid] = 1;
350 
351  resumeSerialize = false;
352  serializeInst[tid] = NULL;
353  } else if (renameStatus[tid] == SerializeStall) {
354  if (serializeInst[tid]->seqNum <= squash_seq_num) {
355  DPRINTF(Rename, "[tid:%i] [squash sn:%llu] "
356  "Rename will resume serializing after squash\n",
357  tid,squash_seq_num);
358  resumeSerialize = true;
359  assert(serializeInst[tid]);
360  } else {
361  resumeSerialize = false;
362  toDecode->renameUnblock[tid] = 1;
363 
364  serializeInst[tid] = NULL;
365  }
366  }
367 
368  // Set the status to Squashing.
369  renameStatus[tid] = Squashing;
370 
371  // Squash any instructions from decode.
372  for (int i=0; i<fromDecode->size; i++) {
373  if (fromDecode->insts[i]->threadNumber == tid &&
374  fromDecode->insts[i]->seqNum > squash_seq_num) {
375  fromDecode->insts[i]->setSquashed();
376  wroteToTimeBuffer = true;
377  }
378 
379  }
380 
381  // Clear the instruction list and skid buffer in case they have any
382  // insts in them.
383  insts[tid].clear();
384 
385  // Clear the skid buffer in case it has any data in it.
386  skidBuffer[tid].clear();
387 
388  doSquash(squash_seq_num, tid);
389 }
390 
391 void
393 {
394  wroteToTimeBuffer = false;
395 
396  blockThisCycle = false;
397 
398  bool status_change = false;
399 
400  toIEWIndex = 0;
401 
402  sortInsts();
403 
404  std::list<ThreadID>::iterator threads = activeThreads->begin();
406 
407  // Check stall and squash signals.
408  while (threads != end) {
409  ThreadID tid = *threads++;
410 
411  DPRINTF(Rename, "Processing [tid:%i]\n", tid);
412 
413  status_change = checkSignalsAndUpdate(tid) || status_change;
414 
415  rename(status_change, tid);
416  }
417 
418  if (status_change) {
419  updateStatus();
420  }
421 
422  if (wroteToTimeBuffer) {
423  DPRINTF(Activity, "Activity this cycle.\n");
425  }
426 
427  threads = activeThreads->begin();
428 
429  while (threads != end) {
430  ThreadID tid = *threads++;
431 
432  // If we committed this cycle then doneSeqNum will be > 0
433  if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
434  !fromCommit->commitInfo[tid].squash &&
435  renameStatus[tid] != Squashing) {
436 
437  removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum,
438  tid);
439  }
440  }
441 
442  // @todo: make into updateProgress function
443  for (ThreadID tid = 0; tid < numThreads; tid++) {
444  instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
445  loadsInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToLQ;
446  storesInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToSQ;
447  assert(loadsInProgress[tid] >= 0);
448  assert(storesInProgress[tid] >= 0);
449  assert(instsInProgress[tid] >=0);
450  }
451 
452 }
453 
454 void
455 Rename::rename(bool &status_change, ThreadID tid)
456 {
457  // If status is Running or idle,
458  // call renameInsts()
459  // If status is Unblocking,
460  // buffer any instructions coming from decode
461  // continue trying to empty skid buffer
462  // check if stall conditions have passed
463 
464  if (renameStatus[tid] == Blocked) {
465  ++stats.blockCycles;
466  } else if (renameStatus[tid] == Squashing) {
468  } else if (renameStatus[tid] == SerializeStall) {
470  // If we are currently in SerializeStall and resumeSerialize
471  // was set, then that means that we are resuming serializing
472  // this cycle. Tell the previous stages to block.
473  if (resumeSerialize) {
474  resumeSerialize = false;
475  block(tid);
476  toDecode->renameUnblock[tid] = false;
477  }
478  } else if (renameStatus[tid] == Unblocking) {
479  if (resumeUnblocking) {
480  block(tid);
481  resumeUnblocking = false;
482  toDecode->renameUnblock[tid] = false;
483  }
484  }
485 
486  if (renameStatus[tid] == Running ||
487  renameStatus[tid] == Idle) {
488  DPRINTF(Rename,
489  "[tid:%i] "
490  "Not blocked, so attempting to run stage.\n",
491  tid);
492 
493  renameInsts(tid);
494  } else if (renameStatus[tid] == Unblocking) {
495  renameInsts(tid);
496 
497  if (validInsts()) {
498  // Add the current inputs to the skid buffer so they can be
499  // reprocessed when this stage unblocks.
500  skidInsert(tid);
501  }
502 
503  // If we switched over to blocking, then there's a potential for
504  // an overall status change.
505  status_change = unblock(tid) || status_change || blockThisCycle;
506  }
507 }
508 
509 void
511 {
512  // Instructions can be either in the skid buffer or the queue of
513  // instructions coming from decode, depending on the status.
514  int insts_available = renameStatus[tid] == Unblocking ?
515  skidBuffer[tid].size() : insts[tid].size();
516 
517  // Check the decode queue to see if instructions are available.
518  // If there are no available instructions to rename, then do nothing.
519  if (insts_available == 0) {
520  DPRINTF(Rename, "[tid:%i] Nothing to do, breaking out early.\n",
521  tid);
522  // Should I change status to idle?
523  ++stats.idleCycles;
524  return;
525  } else if (renameStatus[tid] == Unblocking) {
527  } else if (renameStatus[tid] == Running) {
528  ++stats.runCycles;
529  }
530 
531  // Will have to do a different calculation for the number of free
532  // entries.
533  int free_rob_entries = calcFreeROBEntries(tid);
534  int free_iq_entries = calcFreeIQEntries(tid);
535  int min_free_entries = free_rob_entries;
536 
537  FullSource source = ROB;
538 
539  if (free_iq_entries < min_free_entries) {
540  min_free_entries = free_iq_entries;
541  source = IQ;
542  }
543 
544  // Check if there's any space left.
545  if (min_free_entries <= 0) {
546  DPRINTF(Rename,
547  "[tid:%i] Blocking due to no free ROB/IQ/ entries.\n"
548  "ROB has %i free entries.\n"
549  "IQ has %i free entries.\n",
550  tid, free_rob_entries, free_iq_entries);
551 
552  blockThisCycle = true;
553 
554  block(tid);
555 
556  incrFullStat(source);
557 
558  return;
559  } else if (min_free_entries < insts_available) {
560  DPRINTF(Rename,
561  "[tid:%i] "
562  "Will have to block this cycle. "
563  "%i insts available, "
564  "but only %i insts can be renamed due to ROB/IQ/LSQ limits.\n",
565  tid, insts_available, min_free_entries);
566 
567  insts_available = min_free_entries;
568 
569  blockThisCycle = true;
570 
571  incrFullStat(source);
572  }
573 
574  InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ?
575  skidBuffer[tid] : insts[tid];
576 
577  DPRINTF(Rename,
578  "[tid:%i] "
579  "%i available instructions to send iew.\n",
580  tid, insts_available);
581 
582  DPRINTF(Rename,
583  "[tid:%i] "
584  "%i insts pipelining from Rename | "
585  "%i insts dispatched to IQ last cycle.\n",
586  tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched);
587 
588  // Handle serializing the next instruction if necessary.
589  if (serializeOnNextInst[tid]) {
590  if (emptyROB[tid] && instsInProgress[tid] == 0) {
591  // ROB already empty; no need to serialize.
592  serializeOnNextInst[tid] = false;
593  } else if (!insts_to_rename.empty()) {
594  insts_to_rename.front()->setSerializeBefore();
595  }
596  }
597 
598  int renamed_insts = 0;
599 
600  while (insts_available > 0 && toIEWIndex < renameWidth) {
601  DPRINTF(Rename, "[tid:%i] Sending instructions to IEW.\n", tid);
602 
603  assert(!insts_to_rename.empty());
604 
605  DynInstPtr inst = insts_to_rename.front();
606 
607  //For all kind of instructions, check ROB and IQ first For load
608  //instruction, check LQ size and take into account the inflight loads
609  //For store instruction, check SQ size and take into account the
610  //inflight stores
611 
612  if (inst->isLoad()) {
613  if (calcFreeLQEntries(tid) <= 0) {
614  DPRINTF(Rename, "[tid:%i] Cannot rename due to no free LQ\n",
615  tid);
616  source = LQ;
617  incrFullStat(source);
618  break;
619  }
620  }
621 
622  if (inst->isStore() || inst->isAtomic()) {
623  if (calcFreeSQEntries(tid) <= 0) {
624  DPRINTF(Rename, "[tid:%i] Cannot rename due to no free SQ\n",
625  tid);
626  source = SQ;
627  incrFullStat(source);
628  break;
629  }
630  }
631 
632  insts_to_rename.pop_front();
633 
634  if (renameStatus[tid] == Unblocking) {
635  DPRINTF(Rename,
636  "[tid:%i] "
637  "Removing [sn:%llu] PC:%s from rename skidBuffer\n",
638  tid, inst->seqNum, inst->pcState());
639  }
640 
641  if (inst->isSquashed()) {
642  DPRINTF(Rename,
643  "[tid:%i] "
644  "instruction %i with PC %s is squashed, skipping.\n",
645  tid, inst->seqNum, inst->pcState());
646 
648 
649  // Decrement how many instructions are available.
650  --insts_available;
651 
652  continue;
653  }
654 
655  DPRINTF(Rename,
656  "[tid:%i] "
657  "Processing instruction [sn:%llu] with PC %s.\n",
658  tid, inst->seqNum, inst->pcState());
659 
660  // Check here to make sure there are enough destination registers
661  // to rename to. Otherwise block.
662  if (!renameMap[tid]->canRename(inst)) {
663  DPRINTF(Rename,
664  "Blocking due to "
665  " lack of free physical registers to rename to.\n");
666  blockThisCycle = true;
667  insts_to_rename.push_front(inst);
669 
670  break;
671  }
672 
673  // Handle serializeAfter/serializeBefore instructions.
674  // serializeAfter marks the next instruction as serializeBefore.
675  // serializeBefore makes the instruction wait in rename until the ROB
676  // is empty.
677 
678  // In this model, IPR accesses are serialize before
679  // instructions, and store conditionals are serialize after
680  // instructions. This is mainly due to lack of support for
681  // out-of-order operations of either of those classes of
682  // instructions.
683  if (inst->isSerializeBefore() && !inst->isSerializeHandled()) {
684  DPRINTF(Rename, "Serialize before instruction encountered.\n");
685 
686  if (!inst->isTempSerializeBefore()) {
687  stats.serializing++;
688  inst->setSerializeHandled();
689  } else {
691  }
692 
693  // Change status over to SerializeStall so that other stages know
694  // what this is blocked on.
696 
697  serializeInst[tid] = inst;
698 
699  blockThisCycle = true;
700 
701  break;
702  } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
703  !inst->isSerializeHandled()) {
704  DPRINTF(Rename, "Serialize after instruction encountered.\n");
705 
706  stats.serializing++;
707 
708  inst->setSerializeHandled();
709 
710  serializeAfter(insts_to_rename, tid);
711  }
712 
713  renameSrcRegs(inst, inst->threadNumber);
714 
715  renameDestRegs(inst, inst->threadNumber);
716 
717  if (inst->isAtomic() || inst->isStore()) {
718  storesInProgress[tid]++;
719  } else if (inst->isLoad()) {
720  loadsInProgress[tid]++;
721  }
722 
723  ++renamed_insts;
724  // Notify potential listeners that source and destination registers for
725  // this instruction have been renamed.
726  ppRename->notify(inst);
727 
728  // Put instruction in rename queue.
729  toIEW->insts[toIEWIndex] = inst;
730  ++(toIEW->size);
731 
732  // Increment which instruction we're on.
733  ++toIEWIndex;
734 
735  // Decrement how many instructions are available.
736  --insts_available;
737  }
738 
739  instsInProgress[tid] += renamed_insts;
740  stats.renamedInsts += renamed_insts;
741 
742  // If we wrote to the time buffer, record this.
743  if (toIEWIndex) {
744  wroteToTimeBuffer = true;
745  }
746 
747  // Check if there's any instructions left that haven't yet been renamed.
748  // If so then block.
749  if (insts_available) {
750  blockThisCycle = true;
751  }
752 
753  if (blockThisCycle) {
754  block(tid);
755  toDecode->renameUnblock[tid] = false;
756  }
757 }
758 
759 void
761 {
762  DynInstPtr inst = NULL;
763 
764  while (!insts[tid].empty()) {
765  inst = insts[tid].front();
766 
767  insts[tid].pop_front();
768 
769  assert(tid == inst->threadNumber);
770 
771  DPRINTF(Rename, "[tid:%i] Inserting [sn:%llu] PC: %s into Rename "
772  "skidBuffer\n", tid, inst->seqNum, inst->pcState());
773 
774  ++stats.skidInsts;
775 
776  skidBuffer[tid].push_back(inst);
777  }
778 
779  if (skidBuffer[tid].size() > skidBufferMax) {
780  InstQueue::iterator it;
781  warn("Skidbuffer contents:\n");
782  for (it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++) {
783  warn("[tid:%i] %s [sn:%llu].\n", tid,
784  (*it)->staticInst->disassemble(
785  inst->pcState().instAddr()),
786  (*it)->seqNum);
787  }
788  panic("Skidbuffer Exceeded Max Size");
789  }
790 }
791 
792 void
794 {
795  int insts_from_decode = fromDecode->size;
796  for (int i = 0; i < insts_from_decode; ++i) {
797  const DynInstPtr &inst = fromDecode->insts[i];
798  insts[inst->threadNumber].push_back(inst);
799 #if TRACING_ON
800  if (debug::O3PipeView) {
801  inst->renameTick = curTick() - inst->fetchTick;
802  }
803 #endif
804  }
805 }
806 
807 bool
809 {
810  std::list<ThreadID>::iterator threads = activeThreads->begin();
812 
813  while (threads != end) {
814  ThreadID tid = *threads++;
815 
816  if (!skidBuffer[tid].empty())
817  return false;
818  }
819 
820  return true;
821 }
822 
823 void
825 {
826  bool any_unblocking = false;
827 
828  std::list<ThreadID>::iterator threads = activeThreads->begin();
830 
831  while (threads != end) {
832  ThreadID tid = *threads++;
833 
834  if (renameStatus[tid] == Unblocking) {
835  any_unblocking = true;
836  break;
837  }
838  }
839 
840  // Rename will have activity if it's unblocking.
841  if (any_unblocking) {
842  if (_status == Inactive) {
843  _status = Active;
844 
845  DPRINTF(Activity, "Activating stage.\n");
846 
848  }
849  } else {
850  // If it's not unblocking, then rename will not have any internal
851  // activity. Switch it to inactive.
852  if (_status == Active) {
853  _status = Inactive;
854  DPRINTF(Activity, "Deactivating stage.\n");
855 
857  }
858  }
859 }
860 
861 bool
863 {
864  DPRINTF(Rename, "[tid:%i] Blocking.\n", tid);
865 
866  // Add the current inputs onto the skid buffer, so they can be
867  // reprocessed when this stage unblocks.
868  skidInsert(tid);
869 
870  // Only signal backwards to block if the previous stages do not think
871  // rename is already blocked.
872  if (renameStatus[tid] != Blocked) {
873  // If resumeUnblocking is set, we unblocked during the squash,
874  // but now we're have unblocking status. We need to tell earlier
875  // stages to block.
876  if (resumeUnblocking || renameStatus[tid] != Unblocking) {
877  toDecode->renameBlock[tid] = true;
878  toDecode->renameUnblock[tid] = false;
879  wroteToTimeBuffer = true;
880  }
881 
882  // Rename can not go from SerializeStall to Blocked, otherwise
883  // it would not know to complete the serialize stall.
884  if (renameStatus[tid] != SerializeStall) {
885  // Set status to Blocked.
886  renameStatus[tid] = Blocked;
887  return true;
888  }
889  }
890 
891  return false;
892 }
893 
894 bool
896 {
897  DPRINTF(Rename, "[tid:%i] Trying to unblock.\n", tid);
898 
899  // Rename is done unblocking if the skid buffer is empty.
900  if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) {
901 
902  DPRINTF(Rename, "[tid:%i] Done unblocking.\n", tid);
903 
904  toDecode->renameUnblock[tid] = true;
905  wroteToTimeBuffer = true;
906 
907  renameStatus[tid] = Running;
908  return true;
909  }
910 
911  return false;
912 }
913 
914 void
915 Rename::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
916 {
917  auto hb_it = historyBuffer[tid].begin();
918 
919  // After a syscall squashes everything, the history buffer may be empty
920  // but the ROB may still be squashing instructions.
921  // Go through the most recent instructions, undoing the mappings
922  // they did and freeing up the registers.
923  while (!historyBuffer[tid].empty() &&
924  hb_it->instSeqNum > squashed_seq_num) {
925  assert(hb_it != historyBuffer[tid].end());
926 
927  DPRINTF(Rename, "[tid:%i] Removing history entry with sequence "
928  "number %i (archReg: %d, newPhysReg: %d, prevPhysReg: %d).\n",
929  tid, hb_it->instSeqNum, hb_it->archReg.index(),
930  hb_it->newPhysReg->index(), hb_it->prevPhysReg->index());
931 
932  // Undo the rename mapping only if it was really a change.
933  // Special regs that are not really renamed (like misc regs
934  // and the zero reg) can be recognized because the new mapping
935  // is the same as the old one. While it would be merely a
936  // waste of time to update the rename table, we definitely
937  // don't want to put these on the free list.
938  if (hb_it->newPhysReg != hb_it->prevPhysReg) {
939  // Tell the rename map to set the architected register to the
940  // previous physical register that it was renamed to.
941  renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
942 
943  // Put the renamed physical register back on the free list.
944  freeList->addReg(hb_it->newPhysReg);
945  }
946 
947  // Notify potential listeners that the register mapping needs to be
948  // removed because the instruction it was mapped to got squashed. Note
949  // that this is done before hb_it is incremented.
950  ppSquashInRename->notify(std::make_pair(hb_it->instSeqNum,
951  hb_it->newPhysReg));
952 
953  historyBuffer[tid].erase(hb_it++);
954 
955  ++stats.undoneMaps;
956  }
957 }
958 
959 void
961 {
962  DPRINTF(Rename, "[tid:%i] Removing a committed instruction from the "
963  "history buffer %u (size=%i), until [sn:%llu].\n",
964  tid, tid, historyBuffer[tid].size(), inst_seq_num);
965 
966  auto hb_it = historyBuffer[tid].end();
967 
968  --hb_it;
969 
970  if (historyBuffer[tid].empty()) {
971  DPRINTF(Rename, "[tid:%i] History buffer is empty.\n", tid);
972  return;
973  } else if (hb_it->instSeqNum > inst_seq_num) {
974  DPRINTF(Rename, "[tid:%i] [sn:%llu] "
975  "Old sequence number encountered. "
976  "Ensure that a syscall happened recently.\n",
977  tid,inst_seq_num);
978  return;
979  }
980 
981  // Commit all the renames up until (and including) the committed sequence
982  // number. Some or even all of the committed instructions may not have
983  // rename histories if they did not have destination registers that were
984  // renamed.
985  while (!historyBuffer[tid].empty() &&
986  hb_it != historyBuffer[tid].end() &&
987  hb_it->instSeqNum <= inst_seq_num) {
988 
989  DPRINTF(Rename, "[tid:%i] Freeing up older rename of reg %i (%s), "
990  "[sn:%llu].\n",
991  tid, hb_it->prevPhysReg->index(),
992  hb_it->prevPhysReg->className(),
993  hb_it->instSeqNum);
994 
995  // Don't free special phys regs like misc and zero regs, which
996  // can be recognized because the new mapping is the same as
997  // the old one.
998  if (hb_it->newPhysReg != hb_it->prevPhysReg) {
999  freeList->addReg(hb_it->prevPhysReg);
1000  }
1001 
1002  ++stats.committedMaps;
1003 
1004  historyBuffer[tid].erase(hb_it--);
1005  }
1006 }
1007 
1008 void
1010 {
1011  gem5::ThreadContext *tc = inst->tcBase();
1012  UnifiedRenameMap *map = renameMap[tid];
1013  unsigned num_src_regs = inst->numSrcRegs();
1014  auto *isa = tc->getIsaPtr();
1015 
1016  // Get the architectual register numbers from the source and
1017  // operands, and redirect them to the right physical register.
1018  for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
1019  const RegId& src_reg = inst->srcRegIdx(src_idx);
1020  const RegId flat_reg = src_reg.flatten(*isa);
1021  PhysRegIdPtr renamed_reg;
1022 
1023  renamed_reg = map->lookup(flat_reg);
1024  switch (flat_reg.classValue()) {
1025  case InvalidRegClass:
1026  break;
1027  case IntRegClass:
1028  stats.intLookups++;
1029  break;
1030  case FloatRegClass:
1031  stats.fpLookups++;
1032  break;
1033  case VecRegClass:
1034  case VecElemClass:
1035  stats.vecLookups++;
1036  break;
1037  case VecPredRegClass:
1039  break;
1040  case MatRegClass:
1041  stats.matLookups++;
1042  break;
1043  case CCRegClass:
1044  case MiscRegClass:
1045  break;
1046 
1047  default:
1048  panic("Invalid register class: %d.", flat_reg.classValue());
1049  }
1050 
1051  DPRINTF(Rename,
1052  "[tid:%i] "
1053  "Looking up %s arch reg %i, got phys reg %i (%s)\n",
1054  tid, flat_reg.className(),
1055  src_reg.index(), renamed_reg->index(),
1056  renamed_reg->className());
1057 
1058  inst->renameSrcReg(src_idx, renamed_reg);
1059 
1060  // See if the register is ready or not.
1061  if (scoreboard->getReg(renamed_reg)) {
1062  DPRINTF(Rename,
1063  "[tid:%i] "
1064  "Register %d (flat: %d) (%s) is ready.\n",
1065  tid, renamed_reg->index(), renamed_reg->flatIndex(),
1066  renamed_reg->className());
1067 
1068  inst->markSrcRegReady(src_idx);
1069  } else {
1070  DPRINTF(Rename,
1071  "[tid:%i] "
1072  "Register %d (flat: %d) (%s) is not ready.\n",
1073  tid, renamed_reg->index(), renamed_reg->flatIndex(),
1074  renamed_reg->className());
1075  }
1076 
1077  ++stats.lookups;
1078  }
1079 }
1080 
1081 void
1083 {
1084  gem5::ThreadContext *tc = inst->tcBase();
1085  UnifiedRenameMap *map = renameMap[tid];
1086  unsigned num_dest_regs = inst->numDestRegs();
1087  auto *isa = tc->getIsaPtr();
1088 
1089  // Rename the destination registers.
1090  for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
1091  const RegId& dest_reg = inst->destRegIdx(dest_idx);
1092  UnifiedRenameMap::RenameInfo rename_result;
1093 
1094  RegId flat_dest_regid = dest_reg.flatten(*isa);
1095  flat_dest_regid.setNumPinnedWrites(dest_reg.getNumPinnedWrites());
1096 
1097  rename_result = map->rename(flat_dest_regid);
1098 
1099  inst->flattenedDestIdx(dest_idx, flat_dest_regid);
1100 
1101  scoreboard->unsetReg(rename_result.first);
1102 
1103  DPRINTF(Rename,
1104  "[tid:%i] "
1105  "Renaming arch reg %i (%s) to physical reg %i (%i).\n",
1106  tid, dest_reg.index(), dest_reg.className(),
1107  rename_result.first->index(),
1108  rename_result.first->flatIndex());
1109 
1110  // Record the rename information so that a history can be kept.
1111  RenameHistory hb_entry(inst->seqNum, flat_dest_regid,
1112  rename_result.first,
1113  rename_result.second);
1114 
1115  historyBuffer[tid].push_front(hb_entry);
1116 
1117  DPRINTF(Rename, "[tid:%i] [sn:%llu] "
1118  "Adding instruction to history buffer (size=%i).\n",
1119  tid,(*historyBuffer[tid].begin()).instSeqNum,
1120  historyBuffer[tid].size());
1121 
1122  // Tell the instruction to rename the appropriate destination
1123  // register (dest_idx) to the new physical register
1124  // (rename_result.first), and record the previous physical
1125  // register that the same logical register was renamed to
1126  // (rename_result.second).
1127  inst->renameDestReg(dest_idx,
1128  rename_result.first,
1129  rename_result.second);
1130 
1132  }
1133 }
1134 
1135 int
1137 {
1138  int num_free = freeEntries[tid].robEntries -
1139  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1140 
1141  //DPRINTF(Rename,"[tid:%i] %i rob free\n",tid,num_free);
1142 
1143  return num_free;
1144 }
1145 
1146 int
1148 {
1149  int num_free = freeEntries[tid].iqEntries -
1150  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
1151 
1152  //DPRINTF(Rename,"[tid:%i] %i iq free\n",tid,num_free);
1153 
1154  return num_free;
1155 }
1156 
1157 int
1159 {
1160  int num_free = freeEntries[tid].lqEntries -
1161  (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
1162  DPRINTF(Rename,
1163  "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, "
1164  "loads dispatchedToLQ: %d\n",
1165  freeEntries[tid].lqEntries, loadsInProgress[tid],
1166  fromIEW->iewInfo[tid].dispatchedToLQ);
1167  return num_free;
1168 }
1169 
1170 int
1172 {
1173  int num_free = freeEntries[tid].sqEntries -
1174  (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
1175  DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, "
1176  "storesInProgress: %d, stores dispatchedToSQ: %d\n",
1177  freeEntries[tid].sqEntries, storesInProgress[tid],
1178  fromIEW->iewInfo[tid].dispatchedToSQ);
1179  return num_free;
1180 }
1181 
1182 unsigned
1184 {
1185  unsigned inst_count = 0;
1186 
1187  for (int i=0; i<fromDecode->size; i++) {
1188  if (!fromDecode->insts[i]->isSquashed())
1189  inst_count++;
1190  }
1191 
1192  return inst_count;
1193 }
1194 
1195 void
1197 {
1198  if (fromIEW->iewBlock[tid]) {
1199  stalls[tid].iew = true;
1200  }
1201 
1202  if (fromIEW->iewUnblock[tid]) {
1203  assert(stalls[tid].iew);
1204  stalls[tid].iew = false;
1205  }
1206 }
1207 
1208 bool
1210 {
1211  bool ret_val = false;
1212 
1213  if (stalls[tid].iew) {
1214  DPRINTF(Rename,"[tid:%i] Stall from IEW stage detected.\n", tid);
1215  ret_val = true;
1216  } else if (calcFreeROBEntries(tid) <= 0) {
1217  DPRINTF(Rename,"[tid:%i] Stall: ROB has 0 free entries.\n", tid);
1218  ret_val = true;
1219  } else if (calcFreeIQEntries(tid) <= 0) {
1220  DPRINTF(Rename,"[tid:%i] Stall: IQ has 0 free entries.\n", tid);
1221  ret_val = true;
1222  } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) {
1223  DPRINTF(Rename,"[tid:%i] Stall: LSQ has 0 free entries.\n", tid);
1224  ret_val = true;
1225  } else if (renameMap[tid]->numFreeEntries() <= 0) {
1226  DPRINTF(Rename,"[tid:%i] Stall: RenameMap has 0 free entries.\n", tid);
1227  ret_val = true;
1228  } else if (renameStatus[tid] == SerializeStall &&
1229  (!emptyROB[tid] || instsInProgress[tid])) {
1230  DPRINTF(Rename,"[tid:%i] Stall: Serialize stall and ROB is not "
1231  "empty.\n",
1232  tid);
1233  ret_val = true;
1234  }
1235 
1236  return ret_val;
1237 }
1238 
1239 void
1241 {
1242  if (fromIEW->iewInfo[tid].usedIQ)
1243  freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries;
1244 
1245  if (fromIEW->iewInfo[tid].usedLSQ) {
1246  freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries;
1247  freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries;
1248  }
1249 
1250  if (fromCommit->commitInfo[tid].usedROB) {
1251  freeEntries[tid].robEntries =
1252  fromCommit->commitInfo[tid].freeROBEntries;
1253  emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
1254  }
1255 
1256  DPRINTF(Rename, "[tid:%i] Free IQ: %i, Free ROB: %i, "
1257  "Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i %i %i %i)\n",
1258  tid,
1259  freeEntries[tid].iqEntries,
1260  freeEntries[tid].robEntries,
1261  freeEntries[tid].lqEntries,
1262  freeEntries[tid].sqEntries,
1263  renameMap[tid]->numFreeEntries(),
1264  renameMap[tid]->numFreeEntries(IntRegClass),
1265  renameMap[tid]->numFreeEntries(FloatRegClass),
1266  renameMap[tid]->numFreeEntries(VecRegClass),
1267  renameMap[tid]->numFreeEntries(VecElemClass),
1268  renameMap[tid]->numFreeEntries(VecPredRegClass),
1269  renameMap[tid]->numFreeEntries(MatRegClass),
1270  renameMap[tid]->numFreeEntries(CCRegClass));
1271 
1272  DPRINTF(Rename, "[tid:%i] %i instructions not yet in ROB\n",
1273  tid, instsInProgress[tid]);
1274 }
1275 
1276 bool
1278 {
1279  // Check if there's a squash signal, squash if there is
1280  // Check stall signals, block if necessary.
1281  // If status was blocked
1282  // check if stall conditions have passed
1283  // if so then go to unblocking
1284  // If status was Squashing
1285  // check if squashing is not high. Switch to running this cycle.
1286  // If status was serialize stall
1287  // check if ROB is empty and no insts are in flight to the ROB
1288 
1289  readFreeEntries(tid);
1290  readStallSignals(tid);
1291 
1292  if (fromCommit->commitInfo[tid].squash) {
1293  DPRINTF(Rename, "[tid:%i] Squashing instructions due to squash from "
1294  "commit.\n", tid);
1295 
1296  squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
1297 
1298  return true;
1299  }
1300 
1301  if (checkStall(tid)) {
1302  return block(tid);
1303  }
1304 
1305  if (renameStatus[tid] == Blocked) {
1306  DPRINTF(Rename, "[tid:%i] Done blocking, switching to unblocking.\n",
1307  tid);
1308 
1309  renameStatus[tid] = Unblocking;
1310 
1311  unblock(tid);
1312 
1313  return true;
1314  }
1315 
1316  if (renameStatus[tid] == Squashing) {
1317  // Switch status to running if rename isn't being told to block or
1318  // squash this cycle.
1319  if (resumeSerialize) {
1320  DPRINTF(Rename,
1321  "[tid:%i] Done squashing, switching to serialize.\n", tid);
1322 
1324  return true;
1325  } else if (resumeUnblocking) {
1326  DPRINTF(Rename,
1327  "[tid:%i] Done squashing, switching to unblocking.\n",
1328  tid);
1329  renameStatus[tid] = Unblocking;
1330  return true;
1331  } else {
1332  DPRINTF(Rename, "[tid:%i] Done squashing, switching to running.\n",
1333  tid);
1334  renameStatus[tid] = Running;
1335  return false;
1336  }
1337  }
1338 
1339  if (renameStatus[tid] == SerializeStall) {
1340  // Stall ends once the ROB is free.
1341  DPRINTF(Rename, "[tid:%i] Done with serialize stall, switching to "
1342  "unblocking.\n", tid);
1343 
1344  DynInstPtr serial_inst = serializeInst[tid];
1345 
1346  renameStatus[tid] = Unblocking;
1347 
1348  unblock(tid);
1349 
1350  DPRINTF(Rename, "[tid:%i] Processing instruction [%lli] with "
1351  "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState());
1352 
1353  // Put instruction into queue here.
1354  serial_inst->clearSerializeBefore();
1355 
1356  if (!skidBuffer[tid].empty()) {
1357  skidBuffer[tid].push_front(serial_inst);
1358  } else {
1359  insts[tid].push_front(serial_inst);
1360  }
1361 
1362  DPRINTF(Rename, "[tid:%i] Instruction must be processed by rename."
1363  " Adding to front of list.\n", tid);
1364 
1365  serializeInst[tid] = NULL;
1366 
1367  return true;
1368  }
1369 
1370  // If we've reached this point, we have not gotten any signals that
1371  // cause rename to change its status. Rename remains the same as before.
1372  return false;
1373 }
1374 
1375 void
1377 {
1378  if (inst_list.empty()) {
1379  // Mark a bit to say that I must serialize on the next instruction.
1380  serializeOnNextInst[tid] = true;
1381  return;
1382  }
1383 
1384  // Set the next instruction as serializing.
1385  inst_list.front()->setSerializeBefore();
1386 }
1387 
1388 void
1390 {
1391  switch (source) {
1392  case ROB:
1393  ++stats.ROBFullEvents;
1394  break;
1395  case IQ:
1396  ++stats.IQFullEvents;
1397  break;
1398  case LQ:
1399  ++stats.LQFullEvents;
1400  break;
1401  case SQ:
1402  ++stats.SQFullEvents;
1403  break;
1404  default:
1405  panic("Rename full stall stat should be incremented for a reason!");
1406  break;
1407  }
1408 }
1409 
1410 void
1412 {
1414 
1415  for (ThreadID tid = 0; tid < numThreads; tid++) {
1416 
1417  buf_it = historyBuffer[tid].begin();
1418 
1419  while (buf_it != historyBuffer[tid].end()) {
1420  cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:"
1421  " %i[%s] Old phys reg: %i[%s]\n",
1422  (*buf_it).instSeqNum,
1423  (*buf_it).archReg.className(),
1424  (*buf_it).archReg.index(),
1425  (*buf_it).newPhysReg->index(),
1426  (*buf_it).newPhysReg->className(),
1427  (*buf_it).prevPhysReg->index(),
1428  (*buf_it).prevPhysReg->className());
1429 
1430  buf_it++;
1431  }
1432  }
1433 }
1434 
1435 } // namespace o3
1436 } // namespace gem5
gem5::o3::Rename::isDrained
bool isDrained() const
Has the stage drained?
Definition: rename.cc:308
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:200
gem5::o3::Rename::decodeToRenameDelay
int decodeToRenameDelay
Delay between decode and rename, in ticks.
Definition: rename.hh:432
gem5::RegId::flatten
RegId flatten(const BaseISA &isa) const
Definition: reg_class.hh:279
gem5::o3::Rename::freeEntries
FreeEntries freeEntries[MaxThreads]
Per-thread tracking of the number of free entries of back-end structures.
Definition: rename.hh:402
gem5::o3::Rename::storesInProgress
int storesInProgress[MaxThreads]
Count of Store instructions in progress that have been sent off to the IQ and ROB,...
Definition: rename.hh:381
gem5::o3::Rename::tick
void tick()
Ticks rename, which processes all input signals and attempts to rename as many instructions as possib...
Definition: rename.cc:392
gem5::o3::Rename::serializeOnNextInst
bool serializeOnNextInst[MaxThreads]
Records if rename needs to serialize on the next instruction for any thread.
Definition: rename.hh:426
warn
#define warn(...)
Definition: logging.hh:256
gem5::o3::Rename::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: rename.cc:328
gem5::o3::Rename::squash
void squash(const InstSeqNum &squash_seq_num, ThreadID tid)
Squashes all instructions in a thread.
Definition: rename.cc:339
gem5::o3::Rename::iew_ptr
IEW * iew_ptr
Pointer to IEW stage.
Definition: rename.hh:157
gem5::cprintf
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155
gem5::o3::Rename::FreeEntries::sqEntries
unsigned sqEntries
Definition: rename.hh:396
gem5::MipsISA::misc_reg::Count
@ Count
Definition: misc.hh:94
gem5::RegId::getNumPinnedWrites
int getNumPinnedWrites() const
Definition: reg_class.hh:161
gem5::o3::Rename::dumpHistory
void dumpHistory()
Debugging function used to dump history buffer of renamings.
Definition: rename.cc:1411
gem5::o3::Rename::setRenameQueue
void setRenameQueue(TimeBuffer< RenameStruct > *rq_ptr)
Sets pointer to time buffer used to communicate to the next stage.
Definition: rename.cc:206
gem5::o3::Rename::calcFreeROBEntries
int calcFreeROBEntries(ThreadID tid)
Calculates the number of free ROB entries for a specific thread.
Definition: rename.cc:1136
gem5::o3::Rename::validInsts
unsigned validInsts()
Returns the number of valid instructions coming from decode.
Definition: rename.cc:1183
gem5::o3::Rename::RenameStats::blockCycles
statistics::Scalar blockCycles
Stat for total number of cycles spent blocking.
Definition: rename.hh:488
gem5::VecElemClass
@ VecElemClass
Vector Register Native Elem lane.
Definition: reg_class.hh:65
gem5::o3::Scoreboard::getReg
bool getReg(PhysRegIdPtr phys_reg) const
Checks if the register is ready.
Definition: scoreboard.hh:83
rename.hh
gem5::o3::Rename::setRenameMap
void setRenameMap(UnifiedRenameMap rm_ptr[MaxThreads])
Sets pointer to rename maps (per-thread structures).
Definition: rename.cc:289
gem5::InvalidRegClass
@ InvalidRegClass
Definition: reg_class.hh:70
gem5::o3::Rename::RenameStats::runCycles
statistics::Scalar runCycles
Stat for total number of cycles spent running normally.
Definition: rename.hh:493
gem5::o3::Rename::wroteToTimeBuffer
bool wroteToTimeBuffer
Variable that tracks if decode has written to the time buffer this cycle.
Definition: rename.hh:386
gem5::o3::Rename::_status
RenameStatus _status
Rename status.
Definition: rename.hh:111
gem5::o3::Rename::Squashing
@ Squashing
Definition: rename.hh:103
gem5::o3::Rename::resumeSerialize
bool resumeSerialize
Whether or not rename needs to resume a serialize instruction after squashing.
Definition: rename.hh:450
gem5::o3::Rename::instsInProgress
int instsInProgress[MaxThreads]
Count of instructions in progress that have been sent off to the IQ and ROB, but are not yet included...
Definition: rename.hh:371
gem5::o3::Rename::skidInsert
void skidInsert(ThreadID tid)
Inserts unused instructions from a given thread into the skid buffer, to be renamed once rename unblo...
Definition: rename.cc:760
gem5::o3::Rename::commitToRenameDelay
unsigned commitToRenameDelay
Delay between commit and rename, in ticks.
Definition: rename.hh:435
gem5::o3::Rename::removeFromHistory
void removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
Removes a committed instruction's rename history.
Definition: rename.cc:960
gem5::o3::Rename::RenameStats::RenameStats
RenameStats(statistics::Group *parent)
Definition: rename.cc:97
gem5::o3::Rename::freeList
UnifiedFreeList * freeList
Free list interface.
Definition: rename.hh:360
gem5::CCRegClass
@ CCRegClass
Condition-code register.
Definition: reg_class.hh:68
gem5::o3::CPU::RenameIdx
@ RenameIdx
Definition: cpu.hh:455
gem5::o3::Rename::renameQueue
TimeBuffer< RenameStruct > * renameQueue
Rename instruction queue.
Definition: rename.hh:339
gem5::o3::Rename::setScoreboard
void setScoreboard(Scoreboard *_scoreboard)
Sets pointer to the scoreboard.
Definition: rename.cc:302
gem5::o3::Rename::RenameStats::renamedInsts
statistics::Scalar renamedInsts
Stat for total number of renamed instructions.
Definition: rename.hh:497
gem5::o3::Rename::RenameStats::vecPredLookups
statistics::Scalar vecPredLookups
Definition: rename.hh:523
gem5::o3::Rename::historyBuffer
std::list< RenameHistory > historyBuffer[MaxThreads]
A per-thread list of all destination register renames, used to either undo rename mappings or free ol...
Definition: rename.hh:321
gem5::o3::Rename::block
bool block(ThreadID tid)
Switches rename to blocking, and signals back that rename has become blocked.
Definition: rename.cc:862
gem5::o3::Rename::FreeEntries::iqEntries
unsigned iqEntries
Definition: rename.hh:393
gem5::o3::Rename::unblock
bool unblock(ThreadID tid)
Switches rename to unblocking if the skid buffer is empty, and signals back that rename has unblocked...
Definition: rename.cc:895
gem5::o3::Rename::timeBuffer
TimeBuffer< TimeStruct > * timeBuffer
Pointer to main time buffer used for backwards communication.
Definition: rename.hh:327
gem5::o3::Rename::renameDestRegs
void renameDestRegs(const DynInstPtr &inst, ThreadID tid)
Renames the destination registers of an instruction.
Definition: rename.cc:1082
gem5::o3::Rename::ppSquashInRename
ProbePointArg< SeqNumRegPair > * ppSquashInRename
To probe when an instruction is squashed and the register mapping for it needs to be undone.
Definition: rename.hh:124
gem5::o3::UnifiedFreeList
FreeList class that simply holds the list of free integer and floating point registers.
Definition: free_list.hh:124
gem5::o3::Rename::RenameStats::fpLookups
statistics::Scalar fpLookups
Definition: rename.hh:521
gem5::o3::Scoreboard
Implements a simple scoreboard to track which registers are ready.
Definition: scoreboard.hh:54
gem5::o3::Rename::numThreads
ThreadID numThreads
The number of threads active in rename.
Definition: rename.hh:457
gem5::o3::Rename::skidsEmpty
bool skidsEmpty()
Returns if all of the skid buffers are empty.
Definition: rename.cc:808
dyn_inst.hh
gem5::o3::Rename::RenameStats::SQFullEvents
statistics::Scalar SQFullEvents
Stat for total number of times that the SQ starts a stall in rename.
Definition: rename.hh:512
gem5::o3::Rename::sortInsts
void sortInsts()
Separates instructions from decode into individual lists of instructions sorted by thread.
Definition: rename.cc:793
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
gem5::o3::Rename::skidBufferMax
unsigned skidBufferMax
The maximum skid buffer size.
Definition: rename.hh:460
gem5::o3::Rename::RenameStats::undoneMaps
statistics::Scalar undoneMaps
Stat for total number of mappings that were undone due to a squash.
Definition: rename.hh:529
gem5::o3::Rename::Stalls::iew
bool iew
Definition: rename.hh:413
gem5::o3::Rename::RenameStats::serializeStallCycles
statistics::Scalar serializeStallCycles
Stat for total number of cycles spent stalling for a serializing inst.
Definition: rename.hh:491
gem5::o3::Rename::RenameStats::skidInsts
statistics::Scalar skidInsts
Number of instructions inserted into skid buffers.
Definition: rename.hh:535
gem5::o3::Rename::RenameStats::unblockCycles
statistics::Scalar unblockCycles
Stat for total number of cycles spent unblocking.
Definition: rename.hh:495
gem5::VecPredRegClass
@ VecPredRegClass
Definition: reg_class.hh:66
gem5::RefCountingPtr< DynInst >
gem5::TimeBuffer
Definition: timebuf.hh:40
gem5::o3::Rename::Blocked
@ Blocked
Definition: rename.hh:104
gem5::o3::Rename::Unblocking
@ Unblocking
Definition: rename.hh:105
gem5::o3::Rename::calcFreeLQEntries
int calcFreeLQEntries(ThreadID tid)
Calculates the number of free LQ entries for a specific thread.
Definition: rename.cc:1158
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::Rename::Inactive
@ Inactive
Definition: rename.hh:94
gem5::o3::Rename::RenameStats::serializing
statistics::Scalar serializing
Number of serialize instructions handled.
Definition: rename.hh:531
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::o3::Rename::decodeQueue
TimeBuffer< DecodeStruct > * decodeQueue
Decode instruction queue interface.
Definition: rename.hh:345
gem5::o3::Rename::rename
void rename(bool &status_change, ThreadID tid)
Determines what to do based on rename's current status.
Definition: rename.cc:455
gem5::o3::IEW::instQueue
InstructionQueue instQueue
Instruction queue.
Definition: iew.hh:355
gem5::o3::Rename::Running
@ Running
Definition: rename.hh:100
gem5::FloatRegClass
@ FloatRegClass
Floating-point register.
Definition: reg_class.hh:61
gem5::o3::Rename::Active
@ Active
Definition: rename.hh:93
gem5::o3::Rename::clearStates
void clearStates(ThreadID tid)
Clear all thread-specific states.
Definition: rename.cc:230
gem5::o3::Rename::renameSrcRegs
void renameSrcRegs(const DynInstPtr &inst, ThreadID tid)
Renames the source registers of an instruction.
Definition: rename.cc:1009
gem5::o3::Rename::ROB
@ ROB
Definition: rename.hh:467
gem5::o3::Rename::renameWidth
unsigned renameWidth
Rename width, in instructions.
Definition: rename.hh:438
gem5::o3::Rename::scoreboard
Scoreboard * scoreboard
Pointer to the scoreboard.
Definition: rename.hh:366
gem5::RegId::setNumPinnedWrites
void setNumPinnedWrites(int num_writes)
Definition: reg_class.hh:162
gem5::PhysRegId::flatIndex
const RegIndex & flatIndex() const
Flat index accessor.
Definition: reg_class.hh:451
gem5::o3::Rename::LQ
@ LQ
Definition: rename.hh:469
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::o3::Rename::stalls
Stalls stalls[MaxThreads]
Tracks which stages are telling decode to stall.
Definition: rename.hh:418
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
gem5::o3::Rename::IQ
@ IQ
Definition: rename.hh:468
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::MatRegClass
@ MatRegClass
Matrix Register.
Definition: reg_class.hh:67
gem5::o3::Rename::name
std::string name() const
Returns the name of rename.
Definition: rename.cc:92
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:210
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::o3::Rename::updateStatus
void updateStatus()
Updates overall rename status based on all of the threads' statuses.
Definition: rename.cc:824
gem5::o3::Rename::Idle
@ Idle
Definition: rename.hh:101
gem5::o3::Rename::RenameStats::idleCycles
statistics::Scalar idleCycles
Stat for total number of cycles spent idle.
Definition: rename.hh:486
gem5::o3::Rename::fromDecode
TimeBuffer< DecodeStruct >::wire fromDecode
Wire to get decode's output from decode queue.
Definition: rename.hh:348
gem5::o3::Rename::ppRename
ProbePointArg< DynInstPtr > * ppRename
To probe when register renaming for an instruction is complete.
Definition: rename.hh:119
gem5::o3::Rename::RenameStats::tempSerializing
statistics::Scalar tempSerializing
Number of instructions marked as temporarily serializing.
Definition: rename.hh:533
gem5::o3::Rename::doSquash
void doSquash(const InstSeqNum &squash_seq_num, ThreadID tid)
Executes actual squash, removing squashed instructions.
Definition: rename.cc:915
gem5::o3::Rename::checkStall
bool checkStall(ThreadID tid)
Checks if any stages are telling rename to block.
Definition: rename.cc:1209
gem5::o3::Rename::resetStage
void resetStage()
Reset this pipeline stage.
Definition: rename.cc:251
gem5::o3::Rename::RenameHistory
Holds the information for each destination register rename.
Definition: rename.hh:297
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::LSQ::numFreeLoadEntries
unsigned numFreeLoadEntries()
Returns the number of free load entries.
Definition: lsq.cc:524
gem5::o3::InstructionQueue::numFreeEntries
unsigned numFreeEntries()
Returns total number of free entries.
Definition: inst_queue.cc:513
gem5::o3::Rename::insts
InstQueue insts[MaxThreads]
Queue of all instructions coming from decode this cycle.
Definition: rename.hh:351
gem5::o3::Rename::calcFreeIQEntries
int calcFreeIQEntries(ThreadID tid)
Calculates the number of free IQ entries for a specific thread.
Definition: rename.cc:1147
gem5::o3::Rename::SQ
@ SQ
Definition: rename.hh:470
gem5::RegId::className
constexpr const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:275
gem5::o3::MaxWidth
static constexpr int MaxWidth
Definition: limits.hh:37
gem5::o3::Rename::loadsInProgress
int loadsInProgress[MaxThreads]
Count of Load instructions in progress that have been sent off to the IQ and ROB, but are not yet inc...
Definition: rename.hh:376
gem5::o3::Rename::RenameStats::lookups
statistics::Scalar lookups
Stat for total number of source register rename lookups.
Definition: rename.hh:519
std::pair
STL pair class.
Definition: stl.hh:58
gem5::o3::Rename::cpu
CPU * cpu
Pointer to CPU.
Definition: rename.hh:324
gem5::o3::Rename::toIEWIndex
unsigned toIEWIndex
The index of the instruction in the time buffer to IEW that rename is currently using.
Definition: rename.hh:443
gem5::o3::Rename::renameMap
UnifiedRenameMap * renameMap[MaxThreads]
Rename map interface.
Definition: rename.hh:357
gem5::o3::Rename::RenameStats::fullRegistersEvents
statistics::Scalar fullRegistersEvents
Stat for total number of times that rename runs out of free registers to use to rename.
Definition: rename.hh:515
gem5::o3::Rename::RenameStats::renamedOperands
statistics::Scalar renamedOperands
Stat for total number of renamed destination registers.
Definition: rename.hh:517
gem5::o3::Scoreboard::unsetReg
void unsetReg(PhysRegIdPtr phys_reg)
Sets the register as not ready.
Definition: scoreboard.hh:115
gem5::o3::Rename::RenameStats::matLookups
statistics::Scalar matLookups
Definition: rename.hh:524
gem5::o3::Rename::RenameStats::IQFullEvents
statistics::Scalar IQFullEvents
Stat for total number of times that the IQ starts a stall in rename.
Definition: rename.hh:506
gem5::o3::Rename::Rename
Rename(CPU *_cpu, const BaseO3CPUParams &params)
Rename constructor.
Definition: rename.cc:61
gem5::o3::Rename::setTimeBuffer
void setTimeBuffer(TimeBuffer< TimeStruct > *tb_ptr)
Sets the main backwards communication time buffer pointer.
Definition: rename.cc:191
gem5::ProbePointArg
ProbePointArg generates a point for the class of Arg.
Definition: thermal_domain.hh:54
gem5::o3::Rename::serializeAfter
void serializeAfter(InstQueue &inst_list, ThreadID tid)
Either serializes on the next instruction available in the InstQueue, or records that it must seriali...
Definition: rename.cc:1376
gem5::o3::Rename::FreeEntries::robEntries
unsigned robEntries
Definition: rename.hh:394
gem5::IntRegClass
@ IntRegClass
Integer register.
Definition: reg_class.hh:60
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::Rename
Rename handles both single threaded and SMT rename.
Definition: rename.hh:78
gem5::o3::CPU::activityThisCycle
void activityThisCycle()
Records that there was time buffer activity this cycle.
Definition: cpu.hh:485
gem5::o3::Rename::iewToRenameDelay
int iewToRenameDelay
Delay between iew and rename, in ticks.
Definition: rename.hh:429
gem5::o3::Rename::stats
gem5::o3::Rename::RenameStats stats
gem5::o3::Rename::RenameStats::ROBFullEvents
statistics::Scalar ROBFullEvents
Stat for total number of times that the ROB starts a stall in rename.
Definition: rename.hh:503
gem5::o3::Rename::incrFullStat
void incrFullStat(const FullSource &source)
Function used to increment the stat that corresponds to the source of the stall.
Definition: rename.cc:1389
gem5::MiscRegClass
@ MiscRegClass
Control (misc) register.
Definition: reg_class.hh:69
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::Rename::calcFreeSQEntries
int calcFreeSQEntries(ThreadID tid)
Calculates the number of free SQ entries for a specific thread.
Definition: rename.cc:1171
gem5::o3::Rename::RenameStats::vecLookups
statistics::Scalar vecLookups
Definition: rename.hh:522
gem5::o3::Rename::setDecodeQueue
void setDecodeQueue(TimeBuffer< DecodeStruct > *dq_ptr)
Sets pointer to time buffer coming from decode.
Definition: rename.cc:215
gem5::o3::Rename::fromCommit
TimeBuffer< TimeStruct >::wire fromCommit
Wire to get commit's output from backwards time buffer.
Definition: rename.hh:333
std::deque< DynInstPtr >
gem5::o3::Rename::emptyROB
bool emptyROB[MaxThreads]
Records if the ROB is empty.
Definition: rename.hh:408
gem5::o3::Rename::SerializeStall
@ SerializeStall
Definition: rename.hh:106
gem5::o3::LSQ::numFreeStoreEntries
unsigned numFreeStoreEntries()
Returns the number of free store entries.
Definition: lsq.cc:541
reg_class.hh
gem5::o3::UnifiedRenameMap::lookup
PhysRegIdPtr lookup(const RegId &arch_reg) const
Look up the physical register mapped to an architectural register.
Definition: rename_map.hh:225
gem5::o3::Rename::checkSignalsAndUpdate
bool checkSignalsAndUpdate(ThreadID tid)
Checks the signals and updates the status.
Definition: rename.cc:1277
gem5::statistics::Group
Statistics container.
Definition: group.hh:92
gem5::InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:40
gem5::PhysRegId
Physical register ID.
Definition: reg_class.hh:393
gem5::o3::Rename::startupStage
void startupStage()
Initializes variables for the stage.
Definition: rename.cc:224
gem5::PhysRegId::index
constexpr RegIndex index() const
Visible RegId methods.
Definition: reg_class.hh:150
gem5::o3::Rename::setFreeList
void setFreeList(UnifiedFreeList *fl_ptr)
Sets pointer to the free list.
Definition: rename.cc:296
gem5::o3::Rename::RenameStats::committedMaps
statistics::Scalar committedMaps
Stat for total number of committed renaming mappings.
Definition: rename.hh:526
gem5::o3::Rename::blockThisCycle
bool blockThisCycle
Whether or not rename needs to block this cycle.
Definition: rename.hh:446
gem5::o3::Rename::FullSource
FullSource
Enum to record the source of a structure full stall.
Definition: rename.hh:465
gem5::o3::Rename::fromIEW
TimeBuffer< TimeStruct >::wire fromIEW
Wire to get IEW's output from backwards time buffer.
Definition: rename.hh:330
gem5::o3::Rename::readStallSignals
void readStallSignals(ThreadID tid)
Reads signals telling rename to block/unblock.
Definition: rename.cc:1196
gem5::o3::Rename::regProbePoints
void regProbePoints()
Registers probes.
Definition: rename.cc:182
gem5::o3::Rename::serializeInst
DynInstPtr serializeInst[MaxThreads]
The serialize instruction that rename has stalled on.
Definition: rename.hh:421
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::VecRegClass
@ VecRegClass
Vector Register.
Definition: reg_class.hh:63
gem5::RegId::index
constexpr RegIndex index() const
Index accessors.
Definition: reg_class.hh:150
gem5::o3::IEW::ldstQueue
LSQ ldstQueue
Load / store queue.
Definition: iew.hh:358
gem5::ThreadContext::getIsaPtr
virtual BaseISA * getIsaPtr() const =0
cpu.hh
std::list< ThreadID >
gem5::o3::Rename::renameInsts
void renameInsts(ThreadID tid)
Renames instructions for the given thread.
Definition: rename.cc:510
gem5::o3::Rename::RenameStats::squashedInsts
statistics::Scalar squashedInsts
Stat for total number of squashed instructions that rename discards.
Definition: rename.hh:500
gem5::o3::Rename::RenameStats::squashCycles
statistics::Scalar squashCycles
Stat for total number of cycles spent squashing.
Definition: rename.hh:484
gem5::o3::Rename::toDecode
TimeBuffer< TimeStruct >::wire toDecode
Wire to write infromation heading to previous stages.
Definition: rename.hh:336
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::RegId::classValue
constexpr RegClassType classValue() const
Definition: reg_class.hh:274
gem5::statistics::total
const FlagsType total
Print the total.
Definition: info.hh:59
limits.hh
gem5::o3::Rename::takeOverFrom
void takeOverFrom()
Takes over from another CPU's thread.
Definition: rename.cc:322
gem5::o3::Rename::activeThreads
std::list< ThreadID > * activeThreads
Pointer to the list of active threads.
Definition: rename.hh:363
gem5::o3::Rename::RenameStats::LQFullEvents
statistics::Scalar LQFullEvents
Stat for total number of times that the LQ starts a stall in rename.
Definition: rename.hh:509
gem5::o3::Rename::FreeEntries::lqEntries
unsigned lqEntries
Definition: rename.hh:395
gem5::o3::Rename::RenameStats::intLookups
statistics::Scalar intLookups
Definition: rename.hh:520
gem5::PhysRegId::className
constexpr const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:275
gem5::o3::UnifiedRenameMap::rename
RenameInfo rename(const RegId &arch_reg)
Tell rename map to get a new free physical register to remap the specified architectural register.
Definition: rename_map.hh:204
gem5::o3::Rename::toIEW
TimeBuffer< RenameStruct >::wire toIEW
Wire to write any information heading to IEW.
Definition: rename.hh:342
gem5::o3::Rename::renameStatus
ThreadStatus renameStatus[MaxThreads]
Per-thread status.
Definition: rename.hh:114
gem5::o3::Rename::resumeUnblocking
bool resumeUnblocking
Whether or not rename needs to resume clearing out the skidbuffer after squashing.
Definition: rename.hh:454
gem5::o3::Rename::readFreeEntries
void readFreeEntries(ThreadID tid)
Gets the number of free entries for a specific thread.
Definition: rename.cc:1240
gem5::o3::UnifiedFreeList::addReg
void addReg(PhysRegIdPtr freed_reg)
Adds a register back to the free list.
Definition: free_list.hh:174
gem5::ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
gem5::o3::Rename::commit_ptr
Commit * commit_ptr
Pointer to commit stage.
Definition: rename.hh:160
gem5::RegId
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:92
gem5::o3::Rename::skidBuffer
InstQueue skidBuffer[MaxThreads]
Skid buffer between rename and decode.
Definition: rename.hh:354
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::Rename::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets pointer to list of active threads.
Definition: rename.cc:282
gem5::o3::UnifiedRenameMap
Unified register rename map for all classes of registers.
Definition: rename_map.hh:168

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