rename_impl.hh revision 2632:1bb2f91485ea
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
34template <class Impl>
35SimpleRename<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
46template <class Impl>
47void
48SimpleRename<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
112template <class Impl>
113void
114SimpleRename<Impl>::setCPU(FullCPU *cpu_ptr)
115{
116    DPRINTF(Rename, "Rename: Setting CPU pointer.\n");
117    cpu = cpu_ptr;
118}
119
120template <class Impl>
121void
122SimpleRename<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
137template <class Impl>
138void
139SimpleRename<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
148template <class Impl>
149void
150SimpleRename<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
159template <class Impl>
160void
161SimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr)
162{
163    DPRINTF(Rename, "Rename: Setting rename map pointer.\n");
164    renameMap = rm_ptr;
165}
166
167template <class Impl>
168void
169SimpleRename<Impl>::setFreeList(FreeList *fl_ptr)
170{
171    DPRINTF(Rename, "Rename: Setting free list pointer.\n");
172    freeList = fl_ptr;
173}
174
175template <class Impl>
176void
177SimpleRename<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
191template <class Impl>
192void
193SimpleRename<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
208template <class Impl>
209inline void
210SimpleRename<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
228template <class Impl>
229void
230SimpleRename<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
273template <class Impl>
274void
275SimpleRename<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
292template<class Impl>
293void
294SimpleRename<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
342template <class Impl>
343inline void
344SimpleRename<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
377template <class Impl>
378inline void
379SimpleRename<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
441template <class Impl>
442inline int
443SimpleRename<Impl>::calcFreeROBEntries()
444{
445    return fromCommit->commitInfo.freeROBEntries -
446        renameWidth * iewToRenameDelay;
447}
448
449template <class Impl>
450inline int
451SimpleRename<Impl>::calcFreeIQEntries()
452{
453    return fromIEW->iewInfo.freeIQEntries - renameWidth * iewToRenameDelay;
454}
455
456template<class Impl>
457void
458SimpleRename<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
558template<class Impl>
559void
560SimpleRename<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}
755