Merge zizzer.eecs.umich.edu:/z/m5/Bitkeeper/m5
[gem5.git] / cpu / o3 / rename_impl.hh
1 /*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <list>
30
31 #include "config/full_system.hh"
32 #include "cpu/o3/rename.hh"
33
34 template <class Impl>
35 SimpleRename<Impl>::SimpleRename(Params &params)
36 : iewToRenameDelay(params.iewToRenameDelay),
37 decodeToRenameDelay(params.decodeToRenameDelay),
38 commitToRenameDelay(params.commitToRenameDelay),
39 renameWidth(params.renameWidth),
40 commitWidth(params.commitWidth),
41 numInst(0)
42 {
43 _status = Idle;
44 }
45
46 template <class Impl>
47 void
48 SimpleRename<Impl>::regStats()
49 {
50 renameSquashCycles
51 .name(name() + ".renameSquashCycles")
52 .desc("Number of cycles rename is squashing")
53 .prereq(renameSquashCycles);
54 renameIdleCycles
55 .name(name() + ".renameIdleCycles")
56 .desc("Number of cycles rename is idle")
57 .prereq(renameIdleCycles);
58 renameBlockCycles
59 .name(name() + ".renameBlockCycles")
60 .desc("Number of cycles rename is blocking")
61 .prereq(renameBlockCycles);
62 renameUnblockCycles
63 .name(name() + ".renameUnblockCycles")
64 .desc("Number of cycles rename is unblocking")
65 .prereq(renameUnblockCycles);
66 renameRenamedInsts
67 .name(name() + ".renameRenamedInsts")
68 .desc("Number of instructions processed by rename")
69 .prereq(renameRenamedInsts);
70 renameSquashedInsts
71 .name(name() + ".renameSquashedInsts")
72 .desc("Number of squashed instructions processed by rename")
73 .prereq(renameSquashedInsts);
74 renameROBFullEvents
75 .name(name() + ".renameROBFullEvents")
76 .desc("Number of times rename has considered the ROB 'full'")
77 .prereq(renameROBFullEvents);
78 renameIQFullEvents
79 .name(name() + ".renameIQFullEvents")
80 .desc("Number of times rename has considered the IQ 'full'")
81 .prereq(renameIQFullEvents);
82 renameFullRegistersEvents
83 .name(name() + ".renameFullRegisterEvents")
84 .desc("Number of times there has been no free registers")
85 .prereq(renameFullRegistersEvents);
86 renameRenamedOperands
87 .name(name() + ".renameRenamedOperands")
88 .desc("Number of destination operands rename has renamed")
89 .prereq(renameRenamedOperands);
90 renameRenameLookups
91 .name(name() + ".renameRenameLookups")
92 .desc("Number of register rename lookups that rename has made")
93 .prereq(renameRenameLookups);
94 renameHBPlaceHolders
95 .name(name() + ".renameHBPlaceHolders")
96 .desc("Number of place holders added to the history buffer")
97 .prereq(renameHBPlaceHolders);
98 renameCommittedMaps
99 .name(name() + ".renameCommittedMaps")
100 .desc("Number of HB maps that are committed")
101 .prereq(renameCommittedMaps);
102 renameUndoneMaps
103 .name(name() + ".renameUndoneMaps")
104 .desc("Number of HB maps that are undone due to squashing")
105 .prereq(renameUndoneMaps);
106 renameValidUndoneMaps
107 .name(name() + ".renameValidUndoneMaps")
108 .desc("Number of HB maps that are undone, and are not place holders")
109 .prereq(renameValidUndoneMaps);
110 }
111
112 template <class Impl>
113 void
114 SimpleRename<Impl>::setCPU(FullCPU *cpu_ptr)
115 {
116 DPRINTF(Rename, "Rename: Setting CPU pointer.\n");
117 cpu = cpu_ptr;
118 }
119
120 template <class Impl>
121 void
122 SimpleRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
123 {
124 DPRINTF(Rename, "Rename: Setting time buffer pointer.\n");
125 timeBuffer = tb_ptr;
126
127 // Setup wire to read information from time buffer, from IEW stage.
128 fromIEW = timeBuffer->getWire(-iewToRenameDelay);
129
130 // Setup wire to read infromation from time buffer, from commit stage.
131 fromCommit = timeBuffer->getWire(-commitToRenameDelay);
132
133 // Setup wire to write information to previous stages.
134 toDecode = timeBuffer->getWire(0);
135 }
136
137 template <class Impl>
138 void
139 SimpleRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
140 {
141 DPRINTF(Rename, "Rename: Setting rename queue pointer.\n");
142 renameQueue = rq_ptr;
143
144 // Setup wire to write information to future stages.
145 toIEW = renameQueue->getWire(0);
146 }
147
148 template <class Impl>
149 void
150 SimpleRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
151 {
152 DPRINTF(Rename, "Rename: Setting decode queue pointer.\n");
153 decodeQueue = dq_ptr;
154
155 // Setup wire to get information from decode.
156 fromDecode = decodeQueue->getWire(-decodeToRenameDelay);
157 }
158
159 template <class Impl>
160 void
161 SimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr)
162 {
163 DPRINTF(Rename, "Rename: Setting rename map pointer.\n");
164 renameMap = rm_ptr;
165 }
166
167 template <class Impl>
168 void
169 SimpleRename<Impl>::setFreeList(FreeList *fl_ptr)
170 {
171 DPRINTF(Rename, "Rename: Setting free list pointer.\n");
172 freeList = fl_ptr;
173 }
174
175 template <class Impl>
176 void
177 SimpleRename<Impl>::dumpHistory()
178 {
179 typename list<RenameHistory>::iterator buf_it = historyBuffer.begin();
180
181 while (buf_it != historyBuffer.end())
182 {
183 cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
184 "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
185 (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
186
187 buf_it++;
188 }
189 }
190
191 template <class Impl>
192 void
193 SimpleRename<Impl>::block()
194 {
195 DPRINTF(Rename, "Rename: Blocking.\n");
196 // Set status to Blocked.
197 _status = Blocked;
198
199 // Add the current inputs onto the skid buffer, so they can be
200 // reprocessed when this stage unblocks.
201 skidBuffer.push(*fromDecode);
202
203 // Note that this stage only signals previous stages to stall when
204 // it is the cause of the stall originates at this stage. Otherwise
205 // the previous stages are expected to check all possible stall signals.
206 }
207
208 template <class Impl>
209 inline void
210 SimpleRename<Impl>::unblock()
211 {
212 DPRINTF(Rename, "Rename: Read instructions out of skid buffer this "
213 "cycle.\n");
214 // Remove the now processed instructions from the skid buffer.
215 skidBuffer.pop();
216
217 // If there's still information in the skid buffer, then
218 // continue to tell previous stages to stall. They will be
219 // able to restart once the skid buffer is empty.
220 if (!skidBuffer.empty()) {
221 toDecode->renameInfo.stall = true;
222 } else {
223 DPRINTF(Rename, "Rename: Done unblocking.\n");
224 _status = Running;
225 }
226 }
227
228 template <class Impl>
229 void
230 SimpleRename<Impl>::doSquash()
231 {
232 typename list<RenameHistory>::iterator hb_it = historyBuffer.begin();
233
234 InstSeqNum squashed_seq_num = fromCommit->commitInfo.doneSeqNum;
235
236 #if FULL_SYSTEM
237 assert(!historyBuffer.empty());
238 #else
239 // After a syscall squashes everything, the history buffer may be empty
240 // but the ROB may still be squashing instructions.
241 if (historyBuffer.empty()) {
242 return;
243 }
244 #endif // FULL_SYSTEM
245
246 // Go through the most recent instructions, undoing the mappings
247 // they did and freeing up the registers.
248 while ((*hb_it).instSeqNum > squashed_seq_num)
249 {
250 assert(hb_it != historyBuffer.end());
251
252 DPRINTF(Rename, "Rename: Removing history entry with sequence "
253 "number %i.\n", (*hb_it).instSeqNum);
254
255 // If it's not simply a place holder, then add the registers.
256 if (!(*hb_it).placeHolder) {
257 // Tell the rename map to set the architected register to the
258 // previous physical register that it was renamed to.
259 renameMap->setEntry(hb_it->archReg, hb_it->prevPhysReg);
260
261 // Put the renamed physical register back on the free list.
262 freeList->addReg(hb_it->newPhysReg);
263
264 ++renameValidUndoneMaps;
265 }
266
267 historyBuffer.erase(hb_it++);
268
269 ++renameUndoneMaps;
270 }
271 }
272
273 template <class Impl>
274 void
275 SimpleRename<Impl>::squash()
276 {
277 DPRINTF(Rename, "Rename: Squashing instructions.\n");
278 // Set the status to Squashing.
279 _status = Squashing;
280
281 numInst = 0;
282
283 // Clear the skid buffer in case it has any data in it.
284 while (!skidBuffer.empty())
285 {
286 skidBuffer.pop();
287 }
288
289 doSquash();
290 }
291
292 template<class Impl>
293 void
294 SimpleRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num)
295 {
296 DPRINTF(Rename, "Rename: Removing a committed instruction from the "
297 "history buffer, until sequence number %lli.\n", inst_seq_num);
298 typename list<RenameHistory>::iterator hb_it = historyBuffer.end();
299
300 --hb_it;
301
302 if (hb_it->instSeqNum > inst_seq_num) {
303 DPRINTF(Rename, "Rename: Old sequence number encountered. Ensure "
304 "that a syscall happened recently.\n");
305 return;
306 }
307
308 while ((*hb_it).instSeqNum != inst_seq_num)
309 {
310 // Make sure we haven't gone off the end of the list.
311 assert(hb_it != historyBuffer.end());
312
313 // In theory instructions at the end of the history buffer
314 // should be older than the instruction being removed, which
315 // means they will have a lower sequence number. Also the
316 // instruction being removed from the history really should
317 // be the last instruction in the list, as it is the instruction
318 // that was just committed that is being removed.
319 assert(hb_it->instSeqNum < inst_seq_num);
320 DPRINTF(Rename, "Rename: Freeing up older rename of reg %i, sequence"
321 " number %i.\n",
322 (*hb_it).prevPhysReg, (*hb_it).instSeqNum);
323
324 if (!(*hb_it).placeHolder) {
325 freeList->addReg((*hb_it).prevPhysReg);
326 ++renameCommittedMaps;
327 }
328
329 historyBuffer.erase(hb_it--);
330 }
331
332 // Finally free up the previous register of the finished instruction
333 // itself.
334 if (!(*hb_it).placeHolder) {
335 freeList->addReg(hb_it->prevPhysReg);
336 ++renameCommittedMaps;
337 }
338
339 historyBuffer.erase(hb_it);
340 }
341
342 template <class Impl>
343 inline void
344 SimpleRename<Impl>::renameSrcRegs(DynInstPtr &inst)
345 {
346 unsigned num_src_regs = inst->numSrcRegs();
347
348 // Get the architectual register numbers from the source and
349 // destination operands, and redirect them to the right register.
350 // Will need to mark dependencies though.
351 for (int src_idx = 0; src_idx < num_src_regs; src_idx++)
352 {
353 RegIndex src_reg = inst->srcRegIdx(src_idx);
354
355 // Look up the source registers to get the phys. register they've
356 // been renamed to, and set the sources to those registers.
357 PhysRegIndex renamed_reg = renameMap->lookup(src_reg);
358
359 DPRINTF(Rename, "Rename: Looking up arch reg %i, got "
360 "physical reg %i.\n", (int)src_reg, (int)renamed_reg);
361
362 inst->renameSrcReg(src_idx, renamed_reg);
363
364 // Either incorporate it into the info passed back,
365 // or make another function call to see if that register is
366 // ready or not.
367 if (renameMap->isReady(renamed_reg)) {
368 DPRINTF(Rename, "Rename: Register is ready.\n");
369
370 inst->markSrcRegReady(src_idx);
371 }
372
373 ++renameRenameLookups;
374 }
375 }
376
377 template <class Impl>
378 inline void
379 SimpleRename<Impl>::renameDestRegs(DynInstPtr &inst)
380 {
381 typename SimpleRenameMap::RenameInfo rename_result;
382
383 unsigned num_dest_regs = inst->numDestRegs();
384
385 // If it's an instruction with no destination registers, then put
386 // a placeholder within the history buffer. It might be better
387 // to not put it in the history buffer at all (other than branches,
388 // which always need at least a place holder), and differentiate
389 // between instructions with and without destination registers
390 // when getting from commit the instructions that committed.
391 if (num_dest_regs == 0) {
392 RenameHistory hb_entry(inst->seqNum);
393
394 historyBuffer.push_front(hb_entry);
395
396 DPRINTF(Rename, "Rename: Adding placeholder instruction to "
397 "history buffer, sequence number %lli.\n",
398 inst->seqNum);
399
400 ++renameHBPlaceHolders;
401 } else {
402
403 // Rename the destination registers.
404 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++)
405 {
406 RegIndex dest_reg = inst->destRegIdx(dest_idx);
407
408 // Get the physical register that the destination will be
409 // renamed to.
410 rename_result = renameMap->rename(dest_reg);
411
412 DPRINTF(Rename, "Rename: Renaming arch reg %i to physical "
413 "reg %i.\n", (int)dest_reg,
414 (int)rename_result.first);
415
416 // Record the rename information so that a history can be kept.
417 RenameHistory hb_entry(inst->seqNum, dest_reg,
418 rename_result.first,
419 rename_result.second);
420
421 historyBuffer.push_front(hb_entry);
422
423 DPRINTF(Rename, "Rename: Adding instruction to history buffer, "
424 "sequence number %lli.\n",
425 (*historyBuffer.begin()).instSeqNum);
426
427 // Tell the instruction to rename the appropriate destination
428 // register (dest_idx) to the new physical register
429 // (rename_result.first), and record the previous physical
430 // register that the same logical register was renamed to
431 // (rename_result.second).
432 inst->renameDestReg(dest_idx,
433 rename_result.first,
434 rename_result.second);
435
436 ++renameRenamedOperands;
437 }
438 }
439 }
440
441 template <class Impl>
442 inline int
443 SimpleRename<Impl>::calcFreeROBEntries()
444 {
445 return fromCommit->commitInfo.freeROBEntries -
446 renameWidth * iewToRenameDelay;
447 }
448
449 template <class Impl>
450 inline int
451 SimpleRename<Impl>::calcFreeIQEntries()
452 {
453 return fromIEW->iewInfo.freeIQEntries - renameWidth * iewToRenameDelay;
454 }
455
456 template<class Impl>
457 void
458 SimpleRename<Impl>::tick()
459 {
460 // Rename will need to try to rename as many instructions as it
461 // has bandwidth, unless it is blocked.
462
463 // Check if _status is BarrierStall. If so, then check if the number
464 // of free ROB entries is equal to the number of total ROB entries.
465 // Once equal then wake this stage up. Set status to unblocking maybe.
466
467 if (_status != Blocked && _status != Squashing) {
468 DPRINTF(Rename, "Rename: Status is not blocked, will attempt to "
469 "run stage.\n");
470 // Make sure that the skid buffer has something in it if the
471 // status is unblocking.
472 assert(_status == Unblocking ? !skidBuffer.empty() : 1);
473
474 rename();
475
476 // If the status was unblocking, then instructions from the skid
477 // buffer were used. Remove those instructions and handle
478 // the rest of unblocking.
479 if (_status == Unblocking) {
480 ++renameUnblockCycles;
481
482 if (fromDecode->size > 0) {
483 // Add the current inputs onto the skid buffer, so they can be
484 // reprocessed when this stage unblocks.
485 skidBuffer.push(*fromDecode);
486 }
487
488 unblock();
489 }
490 } else if (_status == Blocked) {
491 ++renameBlockCycles;
492
493 // If stage is blocked and still receiving valid instructions,
494 // make sure to store them in the skid buffer.
495 if (fromDecode->size > 0) {
496
497 block();
498
499 // Continue to tell previous stage to stall.
500 toDecode->renameInfo.stall = true;
501 }
502
503 if (!fromIEW->iewInfo.stall &&
504 !fromCommit->commitInfo.stall &&
505 calcFreeROBEntries() > 0 &&
506 calcFreeIQEntries() > 0 &&
507 renameMap->numFreeEntries() > 0) {
508
509 // Need to be sure to check all blocking conditions above.
510 // If they have cleared, then start unblocking.
511 DPRINTF(Rename, "Rename: Stall signals cleared, going to "
512 "unblock.\n");
513 _status = Unblocking;
514
515 // Continue to tell previous stage to block until this stage
516 // is done unblocking.
517 toDecode->renameInfo.stall = true;
518 } else {
519 // Otherwise no conditions have changed. Tell previous
520 // stage to continue blocking.
521 toDecode->renameInfo.stall = true;
522 }
523
524 if (fromCommit->commitInfo.squash ||
525 fromCommit->commitInfo.robSquashing) {
526 squash();
527 return;
528 }
529 } else if (_status == Squashing) {
530 ++renameSquashCycles;
531
532 if (fromCommit->commitInfo.squash) {
533 squash();
534 } else if (!fromCommit->commitInfo.squash &&
535 !fromCommit->commitInfo.robSquashing) {
536
537 DPRINTF(Rename, "Rename: Done squashing, going to running.\n");
538 _status = Running;
539 rename();
540 } else {
541 doSquash();
542 }
543 }
544
545 // Ugly code, revamp all of the tick() functions eventually.
546 if (fromCommit->commitInfo.doneSeqNum != 0 && _status != Squashing) {
547 #if !FULL_SYSTEM
548 if (!fromCommit->commitInfo.squash) {
549 removeFromHistory(fromCommit->commitInfo.doneSeqNum);
550 }
551 #else
552 removeFromHistory(fromCommit->commitInfo.doneSeqNum);
553 #endif
554 }
555
556 }
557
558 template<class Impl>
559 void
560 SimpleRename<Impl>::rename()
561 {
562 // Check if any of the stages ahead of rename are telling rename
563 // to squash. The squash() function will also take care of fixing up
564 // the rename map and the free list.
565 if (fromCommit->commitInfo.squash ||
566 fromCommit->commitInfo.robSquashing) {
567 DPRINTF(Rename, "Rename: Receiving signal from Commit to squash.\n");
568 squash();
569 return;
570 }
571
572 // Check if time buffer is telling this stage to stall.
573 if (fromIEW->iewInfo.stall ||
574 fromCommit->commitInfo.stall) {
575 DPRINTF(Rename, "Rename: Receiving signal from IEW/Commit to "
576 "stall.\n");
577 block();
578 return;
579 }
580
581 // Check if the current status is squashing. If so, set its status
582 // to running and resume execution the next cycle.
583 if (_status == Squashing) {
584 DPRINTF(Rename, "Rename: Done squashing.\n");
585 _status = Running;
586 return;
587 }
588
589 // Check the decode queue to see if instructions are available.
590 // If there are no available instructions to rename, then do nothing.
591 // Or, if the stage is currently unblocking, then go ahead and run it.
592 if (fromDecode->size == 0 && _status != Unblocking) {
593 DPRINTF(Rename, "Rename: Nothing to do, breaking out early.\n");
594 // Should I change status to idle?
595 return;
596 }
597
598 ////////////////////////////////////
599 // Actual rename part.
600 ////////////////////////////////////
601
602 DynInstPtr inst;
603
604 // If we're unblocking, then we may be in the middle of an instruction
605 // group. Subtract off numInst to get the proper number of instructions
606 // left.
607 int insts_available = _status == Unblocking ?
608 skidBuffer.front().size - numInst :
609 fromDecode->size;
610
611 bool block_this_cycle = false;
612
613 // Will have to do a different calculation for the number of free
614 // entries. Number of free entries recorded on this cycle -
615 // renameWidth * renameToDecodeDelay
616 int free_rob_entries = calcFreeROBEntries();
617 int free_iq_entries = calcFreeIQEntries();
618 int min_iq_rob = min(free_rob_entries, free_iq_entries);
619
620 unsigned to_iew_index = 0;
621
622 // Check if there's any space left.
623 if (min_iq_rob <= 0) {
624 DPRINTF(Rename, "Rename: Blocking due to no free ROB or IQ "
625 "entries.\n"
626 "Rename: ROB has %d free entries.\n"
627 "Rename: IQ has %d free entries.\n",
628 free_rob_entries,
629 free_iq_entries);
630 block();
631 // Tell previous stage to stall.
632 toDecode->renameInfo.stall = true;
633
634 if (free_rob_entries <= 0) {
635 ++renameROBFullEvents;
636 } else {
637 ++renameIQFullEvents;
638 }
639
640 return;
641 } else if (min_iq_rob < insts_available) {
642 DPRINTF(Rename, "Rename: Will have to block this cycle. Only "
643 "%i insts can be renamed due to IQ/ROB limits.\n",
644 min_iq_rob);
645
646 insts_available = min_iq_rob;
647
648 block_this_cycle = true;
649
650 if (free_rob_entries < free_iq_entries) {
651 ++renameROBFullEvents;
652 } else {
653 ++renameIQFullEvents;
654 }
655 }
656
657 while (insts_available > 0) {
658 DPRINTF(Rename, "Rename: Sending instructions to iew.\n");
659
660 // Get the next instruction either from the skid buffer or the
661 // decode queue.
662 inst = _status == Unblocking ? skidBuffer.front().insts[numInst] :
663 fromDecode->insts[numInst];
664
665 if (inst->isSquashed()) {
666 DPRINTF(Rename, "Rename: instruction %i with PC %#x is "
667 "squashed, skipping.\n",
668 inst->seqNum, inst->readPC());
669
670 // Go to the next instruction.
671 ++numInst;
672
673 ++renameSquashedInsts;
674
675 // Decrement how many instructions are available.
676 --insts_available;
677
678 continue;
679 }
680
681 DPRINTF(Rename, "Rename: Processing instruction %i with PC %#x.\n",
682 inst->seqNum, inst->readPC());
683
684 // If it's a trap instruction, then it needs to wait here within
685 // rename until the ROB is empty. Needs a way to detect that the
686 // ROB is empty. Maybe an event?
687 // Would be nice if it could be avoided putting this into a
688 // specific stage and instead just put it into the AlphaFullCPU.
689 // Might not really be feasible though...
690 // (EXCB, TRAPB)
691 if (inst->isSerializing()) {
692 panic("Rename: Serializing instruction encountered.\n");
693 DPRINTF(Rename, "Rename: Serializing instruction "
694 "encountered.\n");
695
696 // Change status over to BarrierStall so that other stages know
697 // what this is blocked on.
698 _status = BarrierStall;
699
700 block_this_cycle = true;
701
702 break;
703 }
704
705 // Check here to make sure there are enough destination registers
706 // to rename to. Otherwise block.
707 if (renameMap->numFreeEntries() < inst->numDestRegs())
708 {
709 DPRINTF(Rename, "Rename: Blocking due to lack of free "
710 "physical registers to rename to.\n");
711 // Need some sort of event based on a register being freed.
712
713 block_this_cycle = true;
714
715 ++renameFullRegistersEvents;
716
717 break;
718 }
719
720 renameSrcRegs(inst);
721
722 renameDestRegs(inst);
723
724 // Put instruction in rename queue.
725 toIEW->insts[to_iew_index] = inst;
726 ++(toIEW->size);
727
728 // Decrease the number of free ROB and IQ entries.
729 --free_rob_entries;
730 --free_iq_entries;
731
732 // Increment which instruction we're on.
733 ++to_iew_index;
734 ++numInst;
735
736 ++renameRenamedInsts;
737
738 // Decrement how many instructions are available.
739 --insts_available;
740 }
741
742 // Check if there's any instructions left that haven't yet been renamed.
743 // If so then block.
744 if (block_this_cycle) {
745 block();
746
747 toDecode->renameInfo.stall = true;
748 } else {
749 // If we had a successful rename and didn't have to exit early, then
750 // reset numInst so it will refer to the correct instruction on next
751 // run.
752 numInst = 0;
753 }
754 }