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