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

Generated on Fri Jun 9 2017 13:03:44 for gem5 by doxygen 1.8.6