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