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