rename_impl.hh revision 3093
1955SN/A/*
2955SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan
37816Ssteve.reinhardt@amd.com * All rights reserved.
45871Snate@binkert.org *
51762SN/A * Redistribution and use in source and binary forms, with or without
6955SN/A * modification, are permitted provided that the following conditions are
7955SN/A * met: redistributions of source code must retain the above copyright
8955SN/A * notice, this list of conditions and the following disclaimer;
9955SN/A * redistributions in binary form must reproduce the above copyright
10955SN/A * notice, this list of conditions and the following disclaimer in the
11955SN/A * documentation and/or other materials provided with the distribution;
12955SN/A * neither the name of the copyright holders nor the names of its
13955SN/A * contributors may be used to endorse or promote products derived from
14955SN/A * this software without specific prior written permission.
15955SN/A *
16955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27955SN/A *
28955SN/A * Authors: Kevin Lim
29955SN/A *          Korey Sewell
302665Ssaidi@eecs.umich.edu */
312665Ssaidi@eecs.umich.edu
325863Snate@binkert.org#include <list>
33955SN/A
34955SN/A#include "config/full_system.hh"
35955SN/A#include "cpu/o3/rename.hh"
36955SN/A
37955SN/Atemplate <class Impl>
388878Ssteve.reinhardt@amd.comDefaultRename<Impl>::DefaultRename(Params *params)
392632Sstever@eecs.umich.edu    : iewToRenameDelay(params->iewToRenameDelay),
408878Ssteve.reinhardt@amd.com      decodeToRenameDelay(params->decodeToRenameDelay),
412632Sstever@eecs.umich.edu      commitToRenameDelay(params->commitToRenameDelay),
42955SN/A      renameWidth(params->renameWidth),
438878Ssteve.reinhardt@amd.com      commitWidth(params->commitWidth),
442632Sstever@eecs.umich.edu      numThreads(params->numberOfThreads)
452761Sstever@eecs.umich.edu{
462632Sstever@eecs.umich.edu    _status = Inactive;
472632Sstever@eecs.umich.edu
482632Sstever@eecs.umich.edu    for (int i=0; i< numThreads; i++) {
492761Sstever@eecs.umich.edu        renameStatus[i] = Idle;
502761Sstever@eecs.umich.edu
512761Sstever@eecs.umich.edu        freeEntries[i].iqEntries = 0;
528878Ssteve.reinhardt@amd.com        freeEntries[i].lsqEntries = 0;
538878Ssteve.reinhardt@amd.com        freeEntries[i].robEntries = 0;
542761Sstever@eecs.umich.edu
552761Sstever@eecs.umich.edu        stalls[i].iew = false;
562761Sstever@eecs.umich.edu        stalls[i].commit = false;
572761Sstever@eecs.umich.edu        serializeInst[i] = NULL;
582761Sstever@eecs.umich.edu
598878Ssteve.reinhardt@amd.com        instsInProgress[i] = 0;
608878Ssteve.reinhardt@amd.com
612632Sstever@eecs.umich.edu        emptyROB[i] = true;
622632Sstever@eecs.umich.edu
638878Ssteve.reinhardt@amd.com        serializeOnNextInst[i] = false;
648878Ssteve.reinhardt@amd.com    }
652632Sstever@eecs.umich.edu
66955SN/A    // @todo: Make into a parameter.
67955SN/A    skidBufferMax = (2 * (iewToRenameDelay * params->decodeWidth)) + renameWidth;
68955SN/A}
695863Snate@binkert.org
705863Snate@binkert.orgtemplate <class Impl>
715863Snate@binkert.orgstd::string
725863Snate@binkert.orgDefaultRename<Impl>::name() const
735863Snate@binkert.org{
745863Snate@binkert.org    return cpu->name() + ".rename";
755863Snate@binkert.org}
765863Snate@binkert.org
775863Snate@binkert.orgtemplate <class Impl>
785863Snate@binkert.orgvoid
795863Snate@binkert.orgDefaultRename<Impl>::regStats()
808878Ssteve.reinhardt@amd.com{
815863Snate@binkert.org    renameSquashCycles
825863Snate@binkert.org        .name(name() + ".RENAME:SquashCycles")
835863Snate@binkert.org        .desc("Number of cycles rename is squashing")
845863Snate@binkert.org        .prereq(renameSquashCycles);
855863Snate@binkert.org    renameIdleCycles
865863Snate@binkert.org        .name(name() + ".RENAME:IdleCycles")
875863Snate@binkert.org        .desc("Number of cycles rename is idle")
885863Snate@binkert.org        .prereq(renameIdleCycles);
895863Snate@binkert.org    renameBlockCycles
905863Snate@binkert.org        .name(name() + ".RENAME:BlockCycles")
915863Snate@binkert.org        .desc("Number of cycles rename is blocking")
925863Snate@binkert.org        .prereq(renameBlockCycles);
935863Snate@binkert.org    renameSerializeStallCycles
945863Snate@binkert.org        .name(name() + ".RENAME:serializeStallCycles")
955863Snate@binkert.org        .desc("count of cycles rename stalled for serializing inst")
968878Ssteve.reinhardt@amd.com        .flags(Stats::total);
975863Snate@binkert.org    renameRunCycles
985863Snate@binkert.org        .name(name() + ".RENAME:RunCycles")
995863Snate@binkert.org        .desc("Number of cycles rename is running")
1006654Snate@binkert.org        .prereq(renameIdleCycles);
101955SN/A    renameUnblockCycles
1025396Ssaidi@eecs.umich.edu        .name(name() + ".RENAME:UnblockCycles")
1035863Snate@binkert.org        .desc("Number of cycles rename is unblocking")
1045863Snate@binkert.org        .prereq(renameUnblockCycles);
1054202Sbinkertn@umich.edu    renameRenamedInsts
1065863Snate@binkert.org        .name(name() + ".RENAME:RenamedInsts")
1075863Snate@binkert.org        .desc("Number of instructions processed by rename")
1085863Snate@binkert.org        .prereq(renameRenamedInsts);
1095863Snate@binkert.org    renameSquashedInsts
110955SN/A        .name(name() + ".RENAME:SquashedInsts")
1116654Snate@binkert.org        .desc("Number of squashed instructions processed by rename")
1125273Sstever@gmail.com        .prereq(renameSquashedInsts);
1135871Snate@binkert.org    renameROBFullEvents
1145273Sstever@gmail.com        .name(name() + ".RENAME:ROBFullEvents")
1156655Snate@binkert.org        .desc("Number of times rename has blocked due to ROB full")
1168878Ssteve.reinhardt@amd.com        .prereq(renameROBFullEvents);
1176655Snate@binkert.org    renameIQFullEvents
1186655Snate@binkert.org        .name(name() + ".RENAME:IQFullEvents")
1199219Spower.jg@gmail.com        .desc("Number of times rename has blocked due to IQ full")
1206655Snate@binkert.org        .prereq(renameIQFullEvents);
1215871Snate@binkert.org    renameLSQFullEvents
1226654Snate@binkert.org        .name(name() + ".RENAME:LSQFullEvents")
1238947Sandreas.hansson@arm.com        .desc("Number of times rename has blocked due to LSQ full")
1245396Ssaidi@eecs.umich.edu        .prereq(renameLSQFullEvents);
1258120Sgblack@eecs.umich.edu    renameFullRegistersEvents
1268120Sgblack@eecs.umich.edu        .name(name() + ".RENAME:FullRegisterEvents")
1278120Sgblack@eecs.umich.edu        .desc("Number of times there has been no free registers")
1288120Sgblack@eecs.umich.edu        .prereq(renameFullRegistersEvents);
1298120Sgblack@eecs.umich.edu    renameRenamedOperands
1308120Sgblack@eecs.umich.edu        .name(name() + ".RENAME:RenamedOperands")
1318120Sgblack@eecs.umich.edu        .desc("Number of destination operands rename has renamed")
1328120Sgblack@eecs.umich.edu        .prereq(renameRenamedOperands);
1338879Ssteve.reinhardt@amd.com    renameRenameLookups
1348879Ssteve.reinhardt@amd.com        .name(name() + ".RENAME:RenameLookups")
1358879Ssteve.reinhardt@amd.com        .desc("Number of register rename lookups that rename has made")
1368879Ssteve.reinhardt@amd.com        .prereq(renameRenameLookups);
1378879Ssteve.reinhardt@amd.com    renameCommittedMaps
1388879Ssteve.reinhardt@amd.com        .name(name() + ".RENAME:CommittedMaps")
1398879Ssteve.reinhardt@amd.com        .desc("Number of HB maps that are committed")
1408879Ssteve.reinhardt@amd.com        .prereq(renameCommittedMaps);
1418879Ssteve.reinhardt@amd.com    renameUndoneMaps
1428879Ssteve.reinhardt@amd.com        .name(name() + ".RENAME:UndoneMaps")
1438879Ssteve.reinhardt@amd.com        .desc("Number of HB maps that are undone due to squashing")
1448879Ssteve.reinhardt@amd.com        .prereq(renameUndoneMaps);
1458879Ssteve.reinhardt@amd.com    renamedSerializing
1468120Sgblack@eecs.umich.edu        .name(name() + ".RENAME:serializingInsts")
1478120Sgblack@eecs.umich.edu        .desc("count of serializing insts renamed")
1488120Sgblack@eecs.umich.edu        .flags(Stats::total)
1498120Sgblack@eecs.umich.edu        ;
1508120Sgblack@eecs.umich.edu    renamedTempSerializing
1518120Sgblack@eecs.umich.edu        .name(name() + ".RENAME:tempSerializingInsts")
1528120Sgblack@eecs.umich.edu        .desc("count of temporary serializing insts renamed")
1538120Sgblack@eecs.umich.edu        .flags(Stats::total)
1548120Sgblack@eecs.umich.edu        ;
1558120Sgblack@eecs.umich.edu    renameSkidInsts
1568120Sgblack@eecs.umich.edu        .name(name() + ".RENAME:skidInsts")
1578120Sgblack@eecs.umich.edu        .desc("count of insts added to the skid buffer")
1588120Sgblack@eecs.umich.edu        .flags(Stats::total)
1598120Sgblack@eecs.umich.edu        ;
1608879Ssteve.reinhardt@amd.com}
1618879Ssteve.reinhardt@amd.com
1628879Ssteve.reinhardt@amd.comtemplate <class Impl>
1638879Ssteve.reinhardt@amd.comvoid
1648879Ssteve.reinhardt@amd.comDefaultRename<Impl>::setCPU(O3CPU *cpu_ptr)
1658879Ssteve.reinhardt@amd.com{
1668879Ssteve.reinhardt@amd.com    DPRINTF(Rename, "Setting CPU pointer.\n");
1678879Ssteve.reinhardt@amd.com    cpu = cpu_ptr;
1689227Sandreas.hansson@arm.com}
1699227Sandreas.hansson@arm.com
1708879Ssteve.reinhardt@amd.comtemplate <class Impl>
1718879Ssteve.reinhardt@amd.comvoid
1728879Ssteve.reinhardt@amd.comDefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
1738879Ssteve.reinhardt@amd.com{
1748120Sgblack@eecs.umich.edu    DPRINTF(Rename, "Setting time buffer pointer.\n");
1758947Sandreas.hansson@arm.com    timeBuffer = tb_ptr;
1767816Ssteve.reinhardt@amd.com
1775871Snate@binkert.org    // Setup wire to read information from time buffer, from IEW stage.
1785871Snate@binkert.org    fromIEW = timeBuffer->getWire(-iewToRenameDelay);
1796121Snate@binkert.org
1805871Snate@binkert.org    // Setup wire to read infromation from time buffer, from commit stage.
1815871Snate@binkert.org    fromCommit = timeBuffer->getWire(-commitToRenameDelay);
1829119Sandreas.hansson@arm.com
1839396Sandreas.hansson@arm.com    // Setup wire to write information to previous stages.
1849396Sandreas.hansson@arm.com    toDecode = timeBuffer->getWire(0);
185955SN/A}
1869416SAndreas.Sandberg@ARM.com
1879416SAndreas.Sandberg@ARM.comtemplate <class Impl>
1889416SAndreas.Sandberg@ARM.comvoid
1899416SAndreas.Sandberg@ARM.comDefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
1909416SAndreas.Sandberg@ARM.com{
1919416SAndreas.Sandberg@ARM.com    DPRINTF(Rename, "Setting rename queue pointer.\n");
1929416SAndreas.Sandberg@ARM.com    renameQueue = rq_ptr;
1935871Snate@binkert.org
1945871Snate@binkert.org    // Setup wire to write information to future stages.
1959416SAndreas.Sandberg@ARM.com    toIEW = renameQueue->getWire(0);
1969416SAndreas.Sandberg@ARM.com}
1975871Snate@binkert.org
198955SN/Atemplate <class Impl>
1996121Snate@binkert.orgvoid
2008881Smarc.orr@gmail.comDefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
2016121Snate@binkert.org{
2026121Snate@binkert.org    DPRINTF(Rename, "Setting decode queue pointer.\n");
2031533SN/A    decodeQueue = dq_ptr;
2049239Sandreas.hansson@arm.com
2059239Sandreas.hansson@arm.com    // Setup wire to get information from decode.
2069239Sandreas.hansson@arm.com    fromDecode = decodeQueue->getWire(-decodeToRenameDelay);
2079239Sandreas.hansson@arm.com}
2089239Sandreas.hansson@arm.com
2099239Sandreas.hansson@arm.comtemplate <class Impl>
2109239Sandreas.hansson@arm.comvoid
2119239Sandreas.hansson@arm.comDefaultRename<Impl>::initStage()
2129239Sandreas.hansson@arm.com{
2139239Sandreas.hansson@arm.com    // Grab the number of free entries directly from the stages.
2149239Sandreas.hansson@arm.com    for (int tid=0; tid < numThreads; tid++) {
2159239Sandreas.hansson@arm.com        freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);
2166655Snate@binkert.org        freeEntries[tid].lsqEntries = iew_ptr->ldstQueue.numFreeEntries(tid);
2176655Snate@binkert.org        freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);
2186655Snate@binkert.org        emptyROB[tid] = true;
2196655Snate@binkert.org    }
2205871Snate@binkert.org}
2215871Snate@binkert.org
2225863Snate@binkert.orgtemplate<class Impl>
2235871Snate@binkert.orgvoid
2248878Ssteve.reinhardt@amd.comDefaultRename<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
2255871Snate@binkert.org{
2265871Snate@binkert.org    DPRINTF(Rename, "Setting active threads list pointer.\n");
2275871Snate@binkert.org    activeThreads = at_ptr;
2285863Snate@binkert.org}
2296121Snate@binkert.org
2305863Snate@binkert.org
2315871Snate@binkert.orgtemplate <class Impl>
2328336Ssteve.reinhardt@amd.comvoid
2338336Ssteve.reinhardt@amd.comDefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[])
2348336Ssteve.reinhardt@amd.com{
2358336Ssteve.reinhardt@amd.com    DPRINTF(Rename, "Setting rename map pointers.\n");
2364678Snate@binkert.org
2378336Ssteve.reinhardt@amd.com    for (int i=0; i<numThreads; i++) {
2388336Ssteve.reinhardt@amd.com        renameMap[i] = &rm_ptr[i];
2398336Ssteve.reinhardt@amd.com    }
2404678Snate@binkert.org}
2414678Snate@binkert.org
2424678Snate@binkert.orgtemplate <class Impl>
2434678Snate@binkert.orgvoid
2447827Snate@binkert.orgDefaultRename<Impl>::setFreeList(FreeList *fl_ptr)
2457827Snate@binkert.org{
2468336Ssteve.reinhardt@amd.com    DPRINTF(Rename, "Setting free list pointer.\n");
2474678Snate@binkert.org    freeList = fl_ptr;
2488336Ssteve.reinhardt@amd.com}
2498336Ssteve.reinhardt@amd.com
2508336Ssteve.reinhardt@amd.comtemplate<class Impl>
2518336Ssteve.reinhardt@amd.comvoid
2528336Ssteve.reinhardt@amd.comDefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
2538336Ssteve.reinhardt@amd.com{
2545871Snate@binkert.org    DPRINTF(Rename, "Setting scoreboard pointer.\n");
2555871Snate@binkert.org    scoreboard = _scoreboard;
2568336Ssteve.reinhardt@amd.com}
2578336Ssteve.reinhardt@amd.com
2588336Ssteve.reinhardt@amd.comtemplate <class Impl>
2598336Ssteve.reinhardt@amd.combool
2608336Ssteve.reinhardt@amd.comDefaultRename<Impl>::drain()
2615871Snate@binkert.org{
2628336Ssteve.reinhardt@amd.com    // Rename is ready to switch out at any time.
2638336Ssteve.reinhardt@amd.com    cpu->signalDrained();
2648336Ssteve.reinhardt@amd.com    return true;
2658336Ssteve.reinhardt@amd.com}
2668336Ssteve.reinhardt@amd.com
2674678Snate@binkert.orgtemplate <class Impl>
2685871Snate@binkert.orgvoid
2694678Snate@binkert.orgDefaultRename<Impl>::switchOut()
2708336Ssteve.reinhardt@amd.com{
2718336Ssteve.reinhardt@amd.com    // Clear any state, fix up the rename map.
2728336Ssteve.reinhardt@amd.com    for (int i = 0; i < numThreads; i++) {
2738336Ssteve.reinhardt@amd.com        typename std::list<RenameHistory>::iterator hb_it =
2748336Ssteve.reinhardt@amd.com            historyBuffer[i].begin();
2758336Ssteve.reinhardt@amd.com
2768336Ssteve.reinhardt@amd.com        while (!historyBuffer[i].empty()) {
2778336Ssteve.reinhardt@amd.com            assert(hb_it != historyBuffer[i].end());
2788336Ssteve.reinhardt@amd.com
2798336Ssteve.reinhardt@amd.com            DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
2808336Ssteve.reinhardt@amd.com                    "number %i.\n", i, (*hb_it).instSeqNum);
2818336Ssteve.reinhardt@amd.com
2828336Ssteve.reinhardt@amd.com            // Tell the rename map to set the architected register to the
2838336Ssteve.reinhardt@amd.com            // previous physical register that it was renamed to.
2848336Ssteve.reinhardt@amd.com            renameMap[i]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
2858336Ssteve.reinhardt@amd.com
2868336Ssteve.reinhardt@amd.com            // Put the renamed physical register back on the free list.
2875871Snate@binkert.org            freeList->addReg(hb_it->newPhysReg);
2886121Snate@binkert.org
289955SN/A            historyBuffer[i].erase(hb_it++);
290955SN/A        }
2912632Sstever@eecs.umich.edu        insts[i].clear();
2922632Sstever@eecs.umich.edu        skidBuffer[i].clear();
293955SN/A    }
294955SN/A}
295955SN/A
296955SN/Atemplate <class Impl>
2978878Ssteve.reinhardt@amd.comvoid
298955SN/ADefaultRename<Impl>::takeOverFrom()
2992632Sstever@eecs.umich.edu{
3002632Sstever@eecs.umich.edu    _status = Inactive;
3012632Sstever@eecs.umich.edu    initStage();
3022632Sstever@eecs.umich.edu
3032632Sstever@eecs.umich.edu    // Reset all state prior to taking over from the other CPU.
3042632Sstever@eecs.umich.edu    for (int i=0; i< numThreads; i++) {
3052632Sstever@eecs.umich.edu        renameStatus[i] = Idle;
3068268Ssteve.reinhardt@amd.com
3078268Ssteve.reinhardt@amd.com        stalls[i].iew = false;
3088268Ssteve.reinhardt@amd.com        stalls[i].commit = false;
3098268Ssteve.reinhardt@amd.com        serializeInst[i] = NULL;
3108268Ssteve.reinhardt@amd.com
3118268Ssteve.reinhardt@amd.com        instsInProgress[i] = 0;
3128268Ssteve.reinhardt@amd.com
3132632Sstever@eecs.umich.edu        emptyROB[i] = true;
3142632Sstever@eecs.umich.edu
3152632Sstever@eecs.umich.edu        serializeOnNextInst[i] = false;
3162632Sstever@eecs.umich.edu    }
3178268Ssteve.reinhardt@amd.com}
3182632Sstever@eecs.umich.edu
3198268Ssteve.reinhardt@amd.comtemplate <class Impl>
3208268Ssteve.reinhardt@amd.comvoid
3218268Ssteve.reinhardt@amd.comDefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, unsigned tid)
3228268Ssteve.reinhardt@amd.com{
3233718Sstever@eecs.umich.edu    DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid);
3242634Sstever@eecs.umich.edu
3252634Sstever@eecs.umich.edu    // Clear the stall signal if rename was blocked or unblocking before.
3265863Snate@binkert.org    // If it still needs to block, the blocking should happen the next
3272638Sstever@eecs.umich.edu    // cycle and there should be space to hold everything due to the squash.
3288268Ssteve.reinhardt@amd.com    if (renameStatus[tid] == Blocked ||
3292632Sstever@eecs.umich.edu        renameStatus[tid] == Unblocking ||
3302632Sstever@eecs.umich.edu        renameStatus[tid] == SerializeStall) {
3312632Sstever@eecs.umich.edu
3322632Sstever@eecs.umich.edu        toDecode->renameUnblock[tid] = 1;
3332632Sstever@eecs.umich.edu
3341858SN/A        serializeInst[tid] = NULL;
3353716Sstever@eecs.umich.edu    }
3362638Sstever@eecs.umich.edu
3372638Sstever@eecs.umich.edu    // Set the status to Squashing.
3382638Sstever@eecs.umich.edu    renameStatus[tid] = Squashing;
3392638Sstever@eecs.umich.edu
3402638Sstever@eecs.umich.edu    // Squash any instructions from decode.
3412638Sstever@eecs.umich.edu    unsigned squashCount = 0;
3422638Sstever@eecs.umich.edu
3435863Snate@binkert.org    for (int i=0; i<fromDecode->size; i++) {
3445863Snate@binkert.org        if (fromDecode->insts[i]->threadNumber == tid &&
3455863Snate@binkert.org            fromDecode->insts[i]->seqNum > squash_seq_num) {
346955SN/A            fromDecode->insts[i]->setSquashed();
3475341Sstever@gmail.com            wroteToTimeBuffer = true;
3485341Sstever@gmail.com            squashCount++;
3495863Snate@binkert.org        }
3507756SAli.Saidi@ARM.com
3515341Sstever@gmail.com    }
3526121Snate@binkert.org
3534494Ssaidi@eecs.umich.edu    // Clear the instruction list and skid buffer in case they have any
3546121Snate@binkert.org    // insts in them. Since we support multiple ISAs, we cant just:
3551105SN/A    // "insts[tid].clear();" or "skidBuffer[tid].clear()" since there is
3562667Sstever@eecs.umich.edu    // a possible delay slot inst for different architectures
3572667Sstever@eecs.umich.edu    // insts[tid].clear();
3582667Sstever@eecs.umich.edu#if ISA_HAS_DELAY_SLOT
3592667Sstever@eecs.umich.edu    DPRINTF(Rename, "[tid:%i] Squashing incoming decode instructions until "
3606121Snate@binkert.org            "[sn:%i].\n",tid, squash_seq_num);
3612667Sstever@eecs.umich.edu    ListIt ilist_it = insts[tid].begin();
3625341Sstever@gmail.com    while (ilist_it != insts[tid].end()) {
3635863Snate@binkert.org        if ((*ilist_it)->seqNum > squash_seq_num) {
3645341Sstever@gmail.com            (*ilist_it)->setSquashed();
3655341Sstever@gmail.com            DPRINTF(Rename, "Squashing incoming decode instruction, "
3665341Sstever@gmail.com                    "[tid:%i] [sn:%i] PC %08p.\n", tid, (*ilist_it)->seqNum, (*ilist_it)->PC);
3678120Sgblack@eecs.umich.edu        }
3685341Sstever@gmail.com        ilist_it++;
3698120Sgblack@eecs.umich.edu    }
3705341Sstever@gmail.com#else
3718120Sgblack@eecs.umich.edu    insts[tid].clear();
3726121Snate@binkert.org#endif
3736121Snate@binkert.org
3748980Ssteve.reinhardt@amd.com    // Clear the skid buffer in case it has any data in it.
3759396Sandreas.hansson@arm.com    // See comments above.
3765397Ssaidi@eecs.umich.edu    //     skidBuffer[tid].clear();
3775397Ssaidi@eecs.umich.edu#if ISA_HAS_DELAY_SLOT
3787727SAli.Saidi@ARM.com    DPRINTF(Rename, "[tid:%i] Squashing incoming skidbuffer instructions "
3798268Ssteve.reinhardt@amd.com            "until [sn:%i].\n", tid, squash_seq_num);
3806168Snate@binkert.org    ListIt slist_it = skidBuffer[tid].begin();
3815341Sstever@gmail.com    while (slist_it != skidBuffer[tid].end()) {
3828120Sgblack@eecs.umich.edu        if ((*slist_it)->seqNum > squash_seq_num) {
3838120Sgblack@eecs.umich.edu            (*slist_it)->setSquashed();
3848120Sgblack@eecs.umich.edu            DPRINTF(Rename, "Squashing skidbuffer instruction, [tid:%i] [sn:%i]"
3856814Sgblack@eecs.umich.edu                    "PC %08p.\n", tid, (*slist_it)->seqNum, (*slist_it)->PC);
3865863Snate@binkert.org        }
3878120Sgblack@eecs.umich.edu        slist_it++;
3885341Sstever@gmail.com    }
3895863Snate@binkert.org#else
3908268Ssteve.reinhardt@amd.com    skidBuffer[tid].clear();
3916121Snate@binkert.org#endif
3926121Snate@binkert.org    doSquash(squash_seq_num, tid);
3938268Ssteve.reinhardt@amd.com}
3945742Snate@binkert.org
3955742Snate@binkert.orgtemplate <class Impl>
3965341Sstever@gmail.comvoid
3975742Snate@binkert.orgDefaultRename<Impl>::tick()
3985742Snate@binkert.org{
3995341Sstever@gmail.com    wroteToTimeBuffer = false;
4006017Snate@binkert.org
4016121Snate@binkert.org    blockThisCycle = false;
4026017Snate@binkert.org
4037816Ssteve.reinhardt@amd.com    bool status_change = false;
4047756SAli.Saidi@ARM.com
4057756SAli.Saidi@ARM.com    toIEWIndex = 0;
4067756SAli.Saidi@ARM.com
4077756SAli.Saidi@ARM.com    sortInsts();
4087756SAli.Saidi@ARM.com
4097756SAli.Saidi@ARM.com    std::list<unsigned>::iterator threads = (*activeThreads).begin();
4107756SAli.Saidi@ARM.com
4117756SAli.Saidi@ARM.com    // Check stall and squash signals.
4127816Ssteve.reinhardt@amd.com    while (threads != (*activeThreads).end()) {
4137816Ssteve.reinhardt@amd.com        unsigned tid = *threads++;
4147816Ssteve.reinhardt@amd.com
4157816Ssteve.reinhardt@amd.com        DPRINTF(Rename, "Processing [tid:%i]\n", tid);
4167816Ssteve.reinhardt@amd.com
4177816Ssteve.reinhardt@amd.com        status_change = checkSignalsAndUpdate(tid) || status_change;
4187816Ssteve.reinhardt@amd.com
4197816Ssteve.reinhardt@amd.com        rename(status_change, tid);
4207816Ssteve.reinhardt@amd.com    }
4217816Ssteve.reinhardt@amd.com
4227756SAli.Saidi@ARM.com    if (status_change) {
4237816Ssteve.reinhardt@amd.com        updateStatus();
4247816Ssteve.reinhardt@amd.com    }
4257816Ssteve.reinhardt@amd.com
4267816Ssteve.reinhardt@amd.com    if (wroteToTimeBuffer) {
4277816Ssteve.reinhardt@amd.com        DPRINTF(Activity, "Activity this cycle.\n");
4287816Ssteve.reinhardt@amd.com        cpu->activityThisCycle();
4297816Ssteve.reinhardt@amd.com    }
4307816Ssteve.reinhardt@amd.com
4317816Ssteve.reinhardt@amd.com    threads = (*activeThreads).begin();
4327816Ssteve.reinhardt@amd.com
4337816Ssteve.reinhardt@amd.com    while (threads != (*activeThreads).end()) {
4347816Ssteve.reinhardt@amd.com        unsigned tid = *threads++;
4357816Ssteve.reinhardt@amd.com
4367816Ssteve.reinhardt@amd.com        // If we committed this cycle then doneSeqNum will be > 0
4377816Ssteve.reinhardt@amd.com        if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
4387816Ssteve.reinhardt@amd.com            !fromCommit->commitInfo[tid].squash &&
4397816Ssteve.reinhardt@amd.com            renameStatus[tid] != Squashing) {
4407816Ssteve.reinhardt@amd.com
4417816Ssteve.reinhardt@amd.com            removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum,
4427816Ssteve.reinhardt@amd.com                                  tid);
4437816Ssteve.reinhardt@amd.com        }
4447816Ssteve.reinhardt@amd.com    }
4457816Ssteve.reinhardt@amd.com
4467816Ssteve.reinhardt@amd.com    // @todo: make into updateProgress function
4477816Ssteve.reinhardt@amd.com    for (int tid=0; tid < numThreads; tid++) {
4487816Ssteve.reinhardt@amd.com        instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
4497816Ssteve.reinhardt@amd.com
4507816Ssteve.reinhardt@amd.com        assert(instsInProgress[tid] >=0);
4517816Ssteve.reinhardt@amd.com    }
4527816Ssteve.reinhardt@amd.com
4537816Ssteve.reinhardt@amd.com}
4547816Ssteve.reinhardt@amd.com
4557816Ssteve.reinhardt@amd.comtemplate<class Impl>
4567816Ssteve.reinhardt@amd.comvoid
4577816Ssteve.reinhardt@amd.comDefaultRename<Impl>::rename(bool &status_change, unsigned tid)
4587816Ssteve.reinhardt@amd.com{
4597816Ssteve.reinhardt@amd.com    // If status is Running or idle,
4607816Ssteve.reinhardt@amd.com    //     call renameInsts()
4617816Ssteve.reinhardt@amd.com    // If status is Unblocking,
4627816Ssteve.reinhardt@amd.com    //     buffer any instructions coming from decode
4637816Ssteve.reinhardt@amd.com    //     continue trying to empty skid buffer
4647816Ssteve.reinhardt@amd.com    //     check if stall conditions have passed
4657816Ssteve.reinhardt@amd.com
4667816Ssteve.reinhardt@amd.com    if (renameStatus[tid] == Blocked) {
4677816Ssteve.reinhardt@amd.com        ++renameBlockCycles;
4687816Ssteve.reinhardt@amd.com    } else if (renameStatus[tid] == Squashing) {
4697816Ssteve.reinhardt@amd.com        ++renameSquashCycles;
4707816Ssteve.reinhardt@amd.com    } else if (renameStatus[tid] == SerializeStall) {
4717816Ssteve.reinhardt@amd.com        ++renameSerializeStallCycles;
4727816Ssteve.reinhardt@amd.com    }
4737816Ssteve.reinhardt@amd.com
4747816Ssteve.reinhardt@amd.com    if (renameStatus[tid] == Running ||
4757816Ssteve.reinhardt@amd.com        renameStatus[tid] == Idle) {
4767816Ssteve.reinhardt@amd.com        DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run "
4777816Ssteve.reinhardt@amd.com                "stage.\n", tid);
4787816Ssteve.reinhardt@amd.com
4797816Ssteve.reinhardt@amd.com        renameInsts(tid);
4807816Ssteve.reinhardt@amd.com    } else if (renameStatus[tid] == Unblocking) {
4817816Ssteve.reinhardt@amd.com        renameInsts(tid);
4827816Ssteve.reinhardt@amd.com
4837816Ssteve.reinhardt@amd.com        if (validInsts()) {
4848947Sandreas.hansson@arm.com            // Add the current inputs to the skid buffer so they can be
4858947Sandreas.hansson@arm.com            // reprocessed when this stage unblocks.
4867756SAli.Saidi@ARM.com            skidInsert(tid);
4878120Sgblack@eecs.umich.edu        }
4887756SAli.Saidi@ARM.com
4897756SAli.Saidi@ARM.com        // If we switched over to blocking, then there's a potential for
4907756SAli.Saidi@ARM.com        // an overall status change.
4917756SAli.Saidi@ARM.com        status_change = unblock(tid) || status_change || blockThisCycle;
4927816Ssteve.reinhardt@amd.com    }
4937816Ssteve.reinhardt@amd.com}
4947816Ssteve.reinhardt@amd.com
4957816Ssteve.reinhardt@amd.comtemplate <class Impl>
4967816Ssteve.reinhardt@amd.comvoid
4977816Ssteve.reinhardt@amd.comDefaultRename<Impl>::renameInsts(unsigned tid)
4987816Ssteve.reinhardt@amd.com{
4997816Ssteve.reinhardt@amd.com    // Instructions can be either in the skid buffer or the queue of
5007816Ssteve.reinhardt@amd.com    // instructions coming from decode, depending on the status.
5017816Ssteve.reinhardt@amd.com    int insts_available = renameStatus[tid] == Unblocking ?
5027756SAli.Saidi@ARM.com        skidBuffer[tid].size() : insts[tid].size();
5037756SAli.Saidi@ARM.com
5049227Sandreas.hansson@arm.com    // Check the decode queue to see if instructions are available.
5059227Sandreas.hansson@arm.com    // If there are no available instructions to rename, then do nothing.
5069227Sandreas.hansson@arm.com    if (insts_available == 0) {
5079227Sandreas.hansson@arm.com        DPRINTF(Rename, "[tid:%u]: Nothing to do, breaking out early.\n",
5086654Snate@binkert.org                tid);
5096654Snate@binkert.org        // Should I change status to idle?
5105871Snate@binkert.org        ++renameIdleCycles;
5116121Snate@binkert.org        return;
5128946Sandreas.hansson@arm.com    } else if (renameStatus[tid] == Unblocking) {
5139419Sandreas.hansson@arm.com        ++renameUnblockCycles;
5143940Ssaidi@eecs.umich.edu    } else if (renameStatus[tid] == Running) {
5153918Ssaidi@eecs.umich.edu        ++renameRunCycles;
5163918Ssaidi@eecs.umich.edu    }
5171858SN/A
5186121Snate@binkert.org    DynInstPtr inst;
5197739Sgblack@eecs.umich.edu
5207739Sgblack@eecs.umich.edu    // Will have to do a different calculation for the number of free
5216143Snate@binkert.org    // entries.
5227618SAli.Saidi@arm.com    int free_rob_entries = calcFreeROBEntries(tid);
5237618SAli.Saidi@arm.com    int free_iq_entries  = calcFreeIQEntries(tid);
5247618SAli.Saidi@arm.com    int free_lsq_entries = calcFreeLSQEntries(tid);
5257618SAli.Saidi@arm.com    int min_free_entries = free_rob_entries;
5268614Sgblack@eecs.umich.edu
5277618SAli.Saidi@arm.com    FullSource source = ROB;
5287618SAli.Saidi@arm.com
5297618SAli.Saidi@arm.com    if (free_iq_entries < min_free_entries) {
5307739Sgblack@eecs.umich.edu        min_free_entries = free_iq_entries;
5319224Sandreas.hansson@arm.com        source = IQ;
5329224Sandreas.hansson@arm.com    }
5339224Sandreas.hansson@arm.com
5348946Sandreas.hansson@arm.com    if (free_lsq_entries < min_free_entries) {
5359227Sandreas.hansson@arm.com        min_free_entries = free_lsq_entries;
5369227Sandreas.hansson@arm.com        source = LSQ;
5379227Sandreas.hansson@arm.com    }
5389227Sandreas.hansson@arm.com
5399227Sandreas.hansson@arm.com    // Check if there's any space left.
5409227Sandreas.hansson@arm.com    if (min_free_entries <= 0) {
5419227Sandreas.hansson@arm.com        DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/LSQ "
5429227Sandreas.hansson@arm.com                "entries.\n"
5439227Sandreas.hansson@arm.com                "ROB has %i free entries.\n"
5449227Sandreas.hansson@arm.com                "IQ has %i free entries.\n"
5459227Sandreas.hansson@arm.com                "LSQ has %i free entries.\n",
5469227Sandreas.hansson@arm.com                tid,
5479227Sandreas.hansson@arm.com                free_rob_entries,
5489227Sandreas.hansson@arm.com                free_iq_entries,
5499227Sandreas.hansson@arm.com                free_lsq_entries);
5509227Sandreas.hansson@arm.com
5519227Sandreas.hansson@arm.com        blockThisCycle = true;
5529227Sandreas.hansson@arm.com
5538737Skoansin.tan@gmail.com        block(tid);
5548737Skoansin.tan@gmail.com
5558737Skoansin.tan@gmail.com        incrFullStat(source);
5568737Skoansin.tan@gmail.com
5578737Skoansin.tan@gmail.com        return;
5588737Skoansin.tan@gmail.com    } else if (min_free_entries < insts_available) {
5598737Skoansin.tan@gmail.com        DPRINTF(Rename, "[tid:%u]: Will have to block this cycle."
5608737Skoansin.tan@gmail.com                "%i insts available, but only %i insts can be "
5618737Skoansin.tan@gmail.com                "renamed due to ROB/IQ/LSQ limits.\n",
5628737Skoansin.tan@gmail.com                tid, insts_available, min_free_entries);
5638737Skoansin.tan@gmail.com
5648737Skoansin.tan@gmail.com        insts_available = min_free_entries;
5658737Skoansin.tan@gmail.com
5668737Skoansin.tan@gmail.com        blockThisCycle = true;
5678737Skoansin.tan@gmail.com
5688737Skoansin.tan@gmail.com        incrFullStat(source);
5698737Skoansin.tan@gmail.com    }
5708737Skoansin.tan@gmail.com
5718946Sandreas.hansson@arm.com    InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ?
5728946Sandreas.hansson@arm.com        skidBuffer[tid] : insts[tid];
5738946Sandreas.hansson@arm.com
5748946Sandreas.hansson@arm.com    DPRINTF(Rename, "[tid:%u]: %i available instructions to "
5759224Sandreas.hansson@arm.com            "send iew.\n", tid, insts_available);
5769224Sandreas.hansson@arm.com
5778946Sandreas.hansson@arm.com    DPRINTF(Rename, "[tid:%u]: %i insts pipelining from Rename | %i insts "
5788946Sandreas.hansson@arm.com            "dispatched to IQ last cycle.\n",
5793918Ssaidi@eecs.umich.edu            tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched);
5809068SAli.Saidi@ARM.com
5819068SAli.Saidi@ARM.com    // Handle serializing the next instruction if necessary.
5829068SAli.Saidi@ARM.com    if (serializeOnNextInst[tid]) {
5839068SAli.Saidi@ARM.com        if (emptyROB[tid] && instsInProgress[tid] == 0) {
5849068SAli.Saidi@ARM.com            // ROB already empty; no need to serialize.
5859068SAli.Saidi@ARM.com            serializeOnNextInst[tid] = false;
5869068SAli.Saidi@ARM.com        } else if (!insts_to_rename.empty()) {
5879068SAli.Saidi@ARM.com            insts_to_rename.front()->setSerializeBefore();
5889068SAli.Saidi@ARM.com        }
5899419Sandreas.hansson@arm.com    }
5909068SAli.Saidi@ARM.com
5919068SAli.Saidi@ARM.com    int renamed_insts = 0;
5929068SAli.Saidi@ARM.com
5939068SAli.Saidi@ARM.com    while (insts_available > 0 &&  toIEWIndex < renameWidth) {
5949068SAli.Saidi@ARM.com        DPRINTF(Rename, "[tid:%u]: Sending instructions to IEW.\n", tid);
5959068SAli.Saidi@ARM.com
5963918Ssaidi@eecs.umich.edu        assert(!insts_to_rename.empty());
5973918Ssaidi@eecs.umich.edu
5986157Snate@binkert.org        inst = insts_to_rename.front();
5996157Snate@binkert.org
6006157Snate@binkert.org        insts_to_rename.pop_front();
6016157Snate@binkert.org
6025397Ssaidi@eecs.umich.edu        if (renameStatus[tid] == Unblocking) {
6035397Ssaidi@eecs.umich.edu            DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%#x from rename "
6046121Snate@binkert.org                    "skidBuffer\n",
6056121Snate@binkert.org                    tid, inst->seqNum, inst->readPC());
6066121Snate@binkert.org        }
6076121Snate@binkert.org
6086121Snate@binkert.org        if (inst->isSquashed()) {
6096121Snate@binkert.org            DPRINTF(Rename, "[tid:%u]: instruction %i with PC %#x is "
6105397Ssaidi@eecs.umich.edu                    "squashed, skipping.\n",
6111851SN/A                    tid, inst->seqNum, inst->readPC());
6121851SN/A
6137739Sgblack@eecs.umich.edu            ++renameSquashedInsts;
614955SN/A
6159396Sandreas.hansson@arm.com            // Decrement how many instructions are available.
6169396Sandreas.hansson@arm.com            --insts_available;
6179396Sandreas.hansson@arm.com
6189396Sandreas.hansson@arm.com            continue;
6199396Sandreas.hansson@arm.com        }
6209396Sandreas.hansson@arm.com
6219396Sandreas.hansson@arm.com        DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with "
6229396Sandreas.hansson@arm.com                "PC %#x.\n",
6239396Sandreas.hansson@arm.com                tid, inst->seqNum, inst->readPC());
6249396Sandreas.hansson@arm.com
6259396Sandreas.hansson@arm.com        // Handle serializeAfter/serializeBefore instructions.
6269396Sandreas.hansson@arm.com        // serializeAfter marks the next instruction as serializeBefore.
6279396Sandreas.hansson@arm.com        // serializeBefore makes the instruction wait in rename until the ROB
6289396Sandreas.hansson@arm.com        // is empty.
6299396Sandreas.hansson@arm.com
6309396Sandreas.hansson@arm.com        // In this model, IPR accesses are serialize before
6319396Sandreas.hansson@arm.com        // instructions, and store conditionals are serialize after
6329396Sandreas.hansson@arm.com        // instructions.  This is mainly due to lack of support for
6339396Sandreas.hansson@arm.com        // out-of-order operations of either of those classes of
6349396Sandreas.hansson@arm.com        // instructions.
6359396Sandreas.hansson@arm.com        if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
6369396Sandreas.hansson@arm.com            !inst->isSerializeHandled()) {
6379396Sandreas.hansson@arm.com            DPRINTF(Rename, "Serialize before instruction encountered.\n");
6389396Sandreas.hansson@arm.com
6399396Sandreas.hansson@arm.com            if (!inst->isTempSerializeBefore()) {
6409396Sandreas.hansson@arm.com                renamedSerializing++;
6419396Sandreas.hansson@arm.com                inst->setSerializeHandled();
6429396Sandreas.hansson@arm.com            } else {
6433053Sstever@eecs.umich.edu                renamedTempSerializing++;
6446121Snate@binkert.org            }
6453053Sstever@eecs.umich.edu
6463053Sstever@eecs.umich.edu            // Change status over to SerializeStall so that other stages know
6473053Sstever@eecs.umich.edu            // what this is blocked on.
6483053Sstever@eecs.umich.edu            renameStatus[tid] = SerializeStall;
6493053Sstever@eecs.umich.edu
6509072Sandreas.hansson@arm.com            serializeInst[tid] = inst;
6513053Sstever@eecs.umich.edu
6524742Sstever@eecs.umich.edu            blockThisCycle = true;
6534742Sstever@eecs.umich.edu
6543053Sstever@eecs.umich.edu            break;
6553053Sstever@eecs.umich.edu        } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
6563053Sstever@eecs.umich.edu                   !inst->isSerializeHandled()) {
6578960Ssteve.reinhardt@amd.com            DPRINTF(Rename, "Serialize after instruction encountered.\n");
6586654Snate@binkert.org
6593053Sstever@eecs.umich.edu            renamedSerializing++;
6603053Sstever@eecs.umich.edu
6613053Sstever@eecs.umich.edu            inst->setSerializeHandled();
6623053Sstever@eecs.umich.edu
6632667Sstever@eecs.umich.edu            serializeAfter(insts_to_rename, tid);
6644554Sbinkertn@umich.edu        }
6656121Snate@binkert.org
6662667Sstever@eecs.umich.edu        // Check here to make sure there are enough destination registers
6674554Sbinkertn@umich.edu        // to rename to.  Otherwise block.
6684554Sbinkertn@umich.edu        if (renameMap[tid]->numFreeEntries() < inst->numDestRegs()) {
6694554Sbinkertn@umich.edu            DPRINTF(Rename, "Blocking due to lack of free "
6706121Snate@binkert.org                    "physical registers to rename to.\n");
6714554Sbinkertn@umich.edu            blockThisCycle = true;
6724554Sbinkertn@umich.edu
6734554Sbinkertn@umich.edu            ++renameFullRegistersEvents;
6744781Snate@binkert.org
6754554Sbinkertn@umich.edu            break;
6764554Sbinkertn@umich.edu        }
6772667Sstever@eecs.umich.edu
6784554Sbinkertn@umich.edu        renameSrcRegs(inst, inst->threadNumber);
6794554Sbinkertn@umich.edu
6804554Sbinkertn@umich.edu        renameDestRegs(inst, inst->threadNumber);
6814554Sbinkertn@umich.edu
6822667Sstever@eecs.umich.edu        ++renamed_insts;
6834554Sbinkertn@umich.edu
6842667Sstever@eecs.umich.edu        // Put instruction in rename queue.
6854554Sbinkertn@umich.edu        toIEW->insts[toIEWIndex] = inst;
6866121Snate@binkert.org        ++(toIEW->size);
6872667Sstever@eecs.umich.edu
6885522Snate@binkert.org        // Increment which instruction we're on.
6895522Snate@binkert.org        ++toIEWIndex;
6905522Snate@binkert.org
6915522Snate@binkert.org        // Decrement how many instructions are available.
6925522Snate@binkert.org        --insts_available;
6935522Snate@binkert.org    }
6945522Snate@binkert.org
6955522Snate@binkert.org    instsInProgress[tid] += renamed_insts;
6965522Snate@binkert.org    renameRenamedInsts += renamed_insts;
6975522Snate@binkert.org
6985522Snate@binkert.org    // If we wrote to the time buffer, record this.
6995522Snate@binkert.org    if (toIEWIndex) {
7005522Snate@binkert.org        wroteToTimeBuffer = true;
7015522Snate@binkert.org    }
7025522Snate@binkert.org
7035522Snate@binkert.org    // Check if there's any instructions left that haven't yet been renamed.
7045522Snate@binkert.org    // If so then block.
7055522Snate@binkert.org    if (insts_available) {
7065522Snate@binkert.org        blockThisCycle = true;
7075522Snate@binkert.org    }
7085522Snate@binkert.org
7095522Snate@binkert.org    if (blockThisCycle) {
7105522Snate@binkert.org        block(tid);
7115522Snate@binkert.org        toDecode->renameUnblock[tid] = false;
7125522Snate@binkert.org    }
7135522Snate@binkert.org}
7149255SAndreas.Sandberg@arm.com
7159255SAndreas.Sandberg@arm.comtemplate<class Impl>
7169255SAndreas.Sandberg@arm.comvoid
7179255SAndreas.Sandberg@arm.comDefaultRename<Impl>::skidInsert(unsigned tid)
7189255SAndreas.Sandberg@arm.com{
7199255SAndreas.Sandberg@arm.com    DynInstPtr inst = NULL;
7209255SAndreas.Sandberg@arm.com
7219255SAndreas.Sandberg@arm.com    while (!insts[tid].empty()) {
7229255SAndreas.Sandberg@arm.com        inst = insts[tid].front();
7239255SAndreas.Sandberg@arm.com
7249255SAndreas.Sandberg@arm.com        insts[tid].pop_front();
7259255SAndreas.Sandberg@arm.com
7262638Sstever@eecs.umich.edu        assert(tid == inst->threadNumber);
7272638Sstever@eecs.umich.edu
7286121Snate@binkert.org        DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC:%#x into Rename "
7293716Sstever@eecs.umich.edu                "skidBuffer\n", tid, inst->seqNum, inst->readPC());
7305522Snate@binkert.org
7319255SAndreas.Sandberg@arm.com        ++renameSkidInsts;
7329255SAndreas.Sandberg@arm.com
7339255SAndreas.Sandberg@arm.com        skidBuffer[tid].push_back(inst);
7345522Snate@binkert.org    }
7355522Snate@binkert.org
7365522Snate@binkert.org    if (skidBuffer[tid].size() > skidBufferMax)
7375522Snate@binkert.org        panic("Skidbuffer Exceeded Max Size");
7381858SN/A}
7399255SAndreas.Sandberg@arm.com
7409255SAndreas.Sandberg@arm.comtemplate <class Impl>
7419255SAndreas.Sandberg@arm.comvoid
7425227Ssaidi@eecs.umich.eduDefaultRename<Impl>::sortInsts()
7435227Ssaidi@eecs.umich.edu{
7445227Ssaidi@eecs.umich.edu    int insts_from_decode = fromDecode->size;
7455227Ssaidi@eecs.umich.edu#ifdef DEBUG
7466654Snate@binkert.org#if !ISA_HAS_DELAY_SLOT
7476654Snate@binkert.org    for (int i=0; i < numThreads; i++)
7487769SAli.Saidi@ARM.com        assert(insts[i].empty());
7497769SAli.Saidi@ARM.com#endif
7507769SAli.Saidi@ARM.com#endif
7517769SAli.Saidi@ARM.com    for (int i = 0; i < insts_from_decode; ++i) {
7525227Ssaidi@eecs.umich.edu        DynInstPtr inst = fromDecode->insts[i];
7535227Ssaidi@eecs.umich.edu        insts[inst->threadNumber].push_back(inst);
7545227Ssaidi@eecs.umich.edu    }
7555204Sstever@gmail.com}
7565204Sstever@gmail.com
7575204Sstever@gmail.comtemplate<class Impl>
7585204Sstever@gmail.combool
7595204Sstever@gmail.comDefaultRename<Impl>::skidsEmpty()
7605204Sstever@gmail.com{
7615204Sstever@gmail.com    std::list<unsigned>::iterator threads = (*activeThreads).begin();
7625204Sstever@gmail.com
7635204Sstever@gmail.com    while (threads != (*activeThreads).end()) {
7645204Sstever@gmail.com        if (!skidBuffer[*threads++].empty())
7655204Sstever@gmail.com            return false;
7665204Sstever@gmail.com    }
7675204Sstever@gmail.com
7685204Sstever@gmail.com    return true;
7695204Sstever@gmail.com}
7705204Sstever@gmail.com
7715204Sstever@gmail.comtemplate<class Impl>
7726121Snate@binkert.orgvoid
7735204Sstever@gmail.comDefaultRename<Impl>::updateStatus()
7743118Sstever@eecs.umich.edu{
7753118Sstever@eecs.umich.edu    bool any_unblocking = false;
7763118Sstever@eecs.umich.edu
7773118Sstever@eecs.umich.edu    std::list<unsigned>::iterator threads = (*activeThreads).begin();
7783118Sstever@eecs.umich.edu
7795863Snate@binkert.org    threads = (*activeThreads).begin();
7803118Sstever@eecs.umich.edu
7815863Snate@binkert.org    while (threads != (*activeThreads).end()) {
7823118Sstever@eecs.umich.edu        unsigned tid = *threads++;
7837457Snate@binkert.org
7847457Snate@binkert.org        if (renameStatus[tid] == Unblocking) {
7855863Snate@binkert.org            any_unblocking = true;
7865863Snate@binkert.org            break;
7875863Snate@binkert.org        }
7885863Snate@binkert.org    }
7895863Snate@binkert.org
7905863Snate@binkert.org    // Rename will have activity if it's unblocking.
7915863Snate@binkert.org    if (any_unblocking) {
7926003Snate@binkert.org        if (_status == Inactive) {
7935863Snate@binkert.org            _status = Active;
7945863Snate@binkert.org
7955863Snate@binkert.org            DPRINTF(Activity, "Activating stage.\n");
7966120Snate@binkert.org
7975863Snate@binkert.org            cpu->activateStage(O3CPU::RenameIdx);
7985863Snate@binkert.org        }
7995863Snate@binkert.org    } else {
8008655Sandreas.hansson@arm.com        // If it's not unblocking, then rename will not have any internal
8018655Sandreas.hansson@arm.com        // activity.  Switch it to inactive.
8028655Sandreas.hansson@arm.com        if (_status == Active) {
8038655Sandreas.hansson@arm.com            _status = Inactive;
8048655Sandreas.hansson@arm.com            DPRINTF(Activity, "Deactivating stage.\n");
8058655Sandreas.hansson@arm.com
8068655Sandreas.hansson@arm.com            cpu->deactivateStage(O3CPU::RenameIdx);
8078655Sandreas.hansson@arm.com        }
8086120Snate@binkert.org    }
8095863Snate@binkert.org}
8106121Snate@binkert.org
8116121Snate@binkert.orgtemplate <class Impl>
8125863Snate@binkert.orgbool
8137727SAli.Saidi@ARM.comDefaultRename<Impl>::block(unsigned tid)
8147727SAli.Saidi@ARM.com{
8157727SAli.Saidi@ARM.com    DPRINTF(Rename, "[tid:%u]: Blocking.\n", tid);
8167727SAli.Saidi@ARM.com
8177727SAli.Saidi@ARM.com    // Add the current inputs onto the skid buffer, so they can be
8187727SAli.Saidi@ARM.com    // reprocessed when this stage unblocks.
8195863Snate@binkert.org    skidInsert(tid);
8203118Sstever@eecs.umich.edu
8215863Snate@binkert.org    // Only signal backwards to block if the previous stages do not think
8229239Sandreas.hansson@arm.com    // rename is already blocked.
8233118Sstever@eecs.umich.edu    if (renameStatus[tid] != Blocked) {
8243118Sstever@eecs.umich.edu        if (renameStatus[tid] != Unblocking) {
8255863Snate@binkert.org            toDecode->renameBlock[tid] = true;
8265863Snate@binkert.org            toDecode->renameUnblock[tid] = false;
8275863Snate@binkert.org            wroteToTimeBuffer = true;
8285863Snate@binkert.org        }
8293118Sstever@eecs.umich.edu
8303483Ssaidi@eecs.umich.edu        // Rename can not go from SerializeStall to Blocked, otherwise
8313494Ssaidi@eecs.umich.edu        // it would not know to complete the serialize stall.
8323494Ssaidi@eecs.umich.edu        if (renameStatus[tid] != SerializeStall) {
8333483Ssaidi@eecs.umich.edu            // Set status to Blocked.
8343483Ssaidi@eecs.umich.edu            renameStatus[tid] = Blocked;
8353483Ssaidi@eecs.umich.edu            return true;
8363053Sstever@eecs.umich.edu        }
8373053Sstever@eecs.umich.edu    }
8383918Ssaidi@eecs.umich.edu
8393053Sstever@eecs.umich.edu    return false;
8403053Sstever@eecs.umich.edu}
8413053Sstever@eecs.umich.edu
8423053Sstever@eecs.umich.edutemplate <class Impl>
8433053Sstever@eecs.umich.edubool
8449396Sandreas.hansson@arm.comDefaultRename<Impl>::unblock(unsigned tid)
8459396Sandreas.hansson@arm.com{
8469396Sandreas.hansson@arm.com    DPRINTF(Rename, "[tid:%u]: Trying to unblock.\n", tid);
8479396Sandreas.hansson@arm.com
8489396Sandreas.hansson@arm.com    // Rename is done unblocking if the skid buffer is empty.
8499396Sandreas.hansson@arm.com    if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) {
8509396Sandreas.hansson@arm.com
8519396Sandreas.hansson@arm.com        DPRINTF(Rename, "[tid:%u]: Done unblocking.\n", tid);
8529396Sandreas.hansson@arm.com
8539396Sandreas.hansson@arm.com        toDecode->renameUnblock[tid] = true;
8549396Sandreas.hansson@arm.com        wroteToTimeBuffer = true;
8559396Sandreas.hansson@arm.com
8569396Sandreas.hansson@arm.com        renameStatus[tid] = Running;
8579396Sandreas.hansson@arm.com        return true;
8589396Sandreas.hansson@arm.com    }
8597840Snate@binkert.org
8607865Sgblack@eecs.umich.edu    return false;
8617865Sgblack@eecs.umich.edu}
8627865Sgblack@eecs.umich.edu
8637865Sgblack@eecs.umich.edutemplate <class Impl>
8647865Sgblack@eecs.umich.eduvoid
8657840Snate@binkert.orgDefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, unsigned tid)
8669045SAli.Saidi@ARM.com{
8679045SAli.Saidi@ARM.com    typename std::list<RenameHistory>::iterator hb_it =
8689045SAli.Saidi@ARM.com        historyBuffer[tid].begin();
8699045SAli.Saidi@ARM.com
8709045SAli.Saidi@ARM.com    // After a syscall squashes everything, the history buffer may be empty
8719045SAli.Saidi@ARM.com    // but the ROB may still be squashing instructions.
8729071Sandreas.hansson@arm.com    if (historyBuffer[tid].empty()) {
8739071Sandreas.hansson@arm.com        return;
8749045SAli.Saidi@ARM.com    }
8757840Snate@binkert.org
8767840Snate@binkert.org    // Go through the most recent instructions, undoing the mappings
8777840Snate@binkert.org    // they did and freeing up the registers.
8781858SN/A    while (!historyBuffer[tid].empty() &&
8791858SN/A           (*hb_it).instSeqNum > squashed_seq_num) {
8801858SN/A        assert(hb_it != historyBuffer[tid].end());
8811858SN/A
8821858SN/A        DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
8831858SN/A                "number %i.\n", tid, (*hb_it).instSeqNum);
8845863Snate@binkert.org
8855863Snate@binkert.org        // Tell the rename map to set the architected register to the
8865863Snate@binkert.org        // previous physical register that it was renamed to.
8875863Snate@binkert.org        renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
8886121Snate@binkert.org
8891858SN/A        // Put the renamed physical register back on the free list.
8905863Snate@binkert.org        freeList->addReg(hb_it->newPhysReg);
8915863Snate@binkert.org
8925863Snate@binkert.org        historyBuffer[tid].erase(hb_it++);
8935863Snate@binkert.org
8945863Snate@binkert.org        ++renameUndoneMaps;
8952139SN/A    }
8964202Sbinkertn@umich.edu}
8974202Sbinkertn@umich.edu
8982139SN/Atemplate<class Impl>
8996994Snate@binkert.orgvoid
9006994Snate@binkert.orgDefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, unsigned tid)
9016994Snate@binkert.org{
9026994Snate@binkert.org    DPRINTF(Rename, "[tid:%u]: Removing a committed instruction from the "
9036994Snate@binkert.org            "history buffer %u (size=%i), until [sn:%lli].\n",
9046994Snate@binkert.org            tid, tid, historyBuffer[tid].size(), inst_seq_num);
9056994Snate@binkert.org
9066994Snate@binkert.org    typename std::list<RenameHistory>::iterator hb_it =
9076994Snate@binkert.org        historyBuffer[tid].end();
9086994Snate@binkert.org
9096994Snate@binkert.org    --hb_it;
9106994Snate@binkert.org
9116994Snate@binkert.org    if (historyBuffer[tid].empty()) {
9126994Snate@binkert.org        DPRINTF(Rename, "[tid:%u]: History buffer is empty.\n", tid);
9136994Snate@binkert.org        return;
9146994Snate@binkert.org    } else if (hb_it->instSeqNum > inst_seq_num) {
9156994Snate@binkert.org        DPRINTF(Rename, "[tid:%u]: Old sequence number encountered.  Ensure "
9166994Snate@binkert.org                "that a syscall happened recently.\n", tid);
9176994Snate@binkert.org        return;
9186994Snate@binkert.org    }
9196994Snate@binkert.org
9206994Snate@binkert.org    // Commit all the renames up until (and including) the committed sequence
9216994Snate@binkert.org    // number. Some or even all of the committed instructions may not have
9226994Snate@binkert.org    // rename histories if they did not have destination registers that were
9236994Snate@binkert.org    // renamed.
9246994Snate@binkert.org    while (!historyBuffer[tid].empty() &&
9256994Snate@binkert.org           hb_it != historyBuffer[tid].end() &&
9266994Snate@binkert.org           (*hb_it).instSeqNum <= inst_seq_num) {
9272155SN/A
9285863Snate@binkert.org        DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, "
9291869SN/A                "[sn:%lli].\n",
9301869SN/A                tid, (*hb_it).prevPhysReg, (*hb_it).instSeqNum);
9315863Snate@binkert.org
9325863Snate@binkert.org        freeList->addReg((*hb_it).prevPhysReg);
9334202Sbinkertn@umich.edu        ++renameCommittedMaps;
9346108Snate@binkert.org
9356108Snate@binkert.org        historyBuffer[tid].erase(hb_it--);
9366108Snate@binkert.org    }
9376108Snate@binkert.org}
9389219Spower.jg@gmail.com
9399219Spower.jg@gmail.comtemplate <class Impl>
9409219Spower.jg@gmail.cominline void
9419219Spower.jg@gmail.comDefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst,unsigned tid)
9429219Spower.jg@gmail.com{
9439219Spower.jg@gmail.com    assert(renameMap[tid] != 0);
9449219Spower.jg@gmail.com
9459219Spower.jg@gmail.com    unsigned num_src_regs = inst->numSrcRegs();
9464202Sbinkertn@umich.edu
9475863Snate@binkert.org    // Get the architectual register numbers from the source and
9488474Sgblack@eecs.umich.edu    // destination operands, and redirect them to the right register.
9498474Sgblack@eecs.umich.edu    // Will need to mark dependencies though.
9505742Snate@binkert.org    for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
9518268Ssteve.reinhardt@amd.com        RegIndex src_reg = inst->srcRegIdx(src_idx);
9528268Ssteve.reinhardt@amd.com
9538268Ssteve.reinhardt@amd.com        // Look up the source registers to get the phys. register they've
9545742Snate@binkert.org        // been renamed to, and set the sources to those registers.
9555341Sstever@gmail.com        PhysRegIndex renamed_reg = renameMap[tid]->lookup(src_reg);
9568474Sgblack@eecs.umich.edu
9578474Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got "
9585342Sstever@gmail.com                "physical reg %i.\n", tid, (int)src_reg,
9594202Sbinkertn@umich.edu                (int)renamed_reg);
9604202Sbinkertn@umich.edu
9614202Sbinkertn@umich.edu        inst->renameSrcReg(src_idx, renamed_reg);
9625863Snate@binkert.org
9635863Snate@binkert.org        // See if the register is ready or not.
9646994Snate@binkert.org        if (scoreboard->getReg(renamed_reg) == true) {
9656994Snate@binkert.org            DPRINTF(Rename, "[tid:%u]: Register is ready.\n", tid);
9666994Snate@binkert.org
9675863Snate@binkert.org            inst->markSrcRegReady(src_idx);
9685863Snate@binkert.org        }
9695863Snate@binkert.org
9705863Snate@binkert.org        ++renameRenameLookups;
9715863Snate@binkert.org    }
9725863Snate@binkert.org}
9735863Snate@binkert.org
9745863Snate@binkert.orgtemplate <class Impl>
9757840Snate@binkert.orginline void
9765863Snate@binkert.orgDefaultRename<Impl>::renameDestRegs(DynInstPtr &inst,unsigned tid)
9775952Ssaidi@eecs.umich.edu{
9789219Spower.jg@gmail.com    typename RenameMap::RenameInfo rename_result;
9799219Spower.jg@gmail.com
9801869SN/A    unsigned num_dest_regs = inst->numDestRegs();
9811858SN/A
9825863Snate@binkert.org    // Rename the destination registers.
9839044SAli.Saidi@ARM.com    for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
9849219Spower.jg@gmail.com        RegIndex dest_reg = inst->destRegIdx(dest_idx);
9859396Sandreas.hansson@arm.com
9861858SN/A        // Get the physical register that the destination will be
987955SN/A        // renamed to.
988955SN/A        rename_result = renameMap[tid]->rename(dest_reg);
9891869SN/A
9901869SN/A        //Mark Scoreboard entry as not ready
9911869SN/A        scoreboard->unsetReg(rename_result.first);
9921869SN/A
9931869SN/A        DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
9945863Snate@binkert.org                "reg %i.\n", tid, (int)dest_reg,
9955863Snate@binkert.org                (int)rename_result.first);
9965863Snate@binkert.org
9971869SN/A        // Record the rename information so that a history can be kept.
9985863Snate@binkert.org        RenameHistory hb_entry(inst->seqNum, dest_reg,
9991869SN/A                               rename_result.first,
10005863Snate@binkert.org                               rename_result.second);
10011869SN/A
10021869SN/A        historyBuffer[tid].push_front(hb_entry);
10031869SN/A
10041869SN/A        DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer "
10058483Sgblack@eecs.umich.edu                "(size=%i), [sn:%lli].\n",tid,
10061869SN/A                historyBuffer[tid].size(),
10071869SN/A                (*historyBuffer[tid].begin()).instSeqNum);
10081869SN/A
10091869SN/A        // Tell the instruction to rename the appropriate destination
10105863Snate@binkert.org        // register (dest_idx) to the new physical register
10115863Snate@binkert.org        // (rename_result.first), and record the previous physical
10121869SN/A        // register that the same logical register was renamed to
10135863Snate@binkert.org        // (rename_result.second).
10145863Snate@binkert.org        inst->renameDestReg(dest_idx,
10153356Sbinkertn@umich.edu                            rename_result.first,
10163356Sbinkertn@umich.edu                            rename_result.second);
10173356Sbinkertn@umich.edu
10183356Sbinkertn@umich.edu        ++renameRenamedOperands;
10193356Sbinkertn@umich.edu    }
10204781Snate@binkert.org}
10215863Snate@binkert.org
10225863Snate@binkert.orgtemplate <class Impl>
10231869SN/Ainline int
10241869SN/ADefaultRename<Impl>::calcFreeROBEntries(unsigned tid)
10251869SN/A{
10266121Snate@binkert.org    int num_free = freeEntries[tid].robEntries -
10271869SN/A                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
10282638Sstever@eecs.umich.edu
10296121Snate@binkert.org    //DPRINTF(Rename,"[tid:%i]: %i rob free\n",tid,num_free);
10306121Snate@binkert.org
10312638Sstever@eecs.umich.edu    return num_free;
10325749Scws3k@cs.virginia.edu}
10336121Snate@binkert.org
10346121Snate@binkert.orgtemplate <class Impl>
10355749Scws3k@cs.virginia.eduinline int
10361869SN/ADefaultRename<Impl>::calcFreeIQEntries(unsigned tid)
10371869SN/A{
10383546Sgblack@eecs.umich.edu    int num_free = freeEntries[tid].iqEntries -
10393546Sgblack@eecs.umich.edu                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
10403546Sgblack@eecs.umich.edu
10413546Sgblack@eecs.umich.edu    //DPRINTF(Rename,"[tid:%i]: %i iq free\n",tid,num_free);
10426121Snate@binkert.org
10435863Snate@binkert.org    return num_free;
10443546Sgblack@eecs.umich.edu}
10453546Sgblack@eecs.umich.edu
10463546Sgblack@eecs.umich.edutemplate <class Impl>
10473546Sgblack@eecs.umich.eduinline int
10484781Snate@binkert.orgDefaultRename<Impl>::calcFreeLSQEntries(unsigned tid)
10494781Snate@binkert.org{
10506658Snate@binkert.org    int num_free = freeEntries[tid].lsqEntries -
10516658Snate@binkert.org                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLSQ);
10524781Snate@binkert.org
10533546Sgblack@eecs.umich.edu    //DPRINTF(Rename,"[tid:%i]: %i lsq free\n",tid,num_free);
10543546Sgblack@eecs.umich.edu
10553546Sgblack@eecs.umich.edu    return num_free;
10563546Sgblack@eecs.umich.edu}
10577756SAli.Saidi@ARM.com
10587816Ssteve.reinhardt@amd.comtemplate <class Impl>
10593546Sgblack@eecs.umich.eduunsigned
10603546Sgblack@eecs.umich.eduDefaultRename<Impl>::validInsts()
10613546Sgblack@eecs.umich.edu{
10623546Sgblack@eecs.umich.edu    unsigned inst_count = 0;
10634202Sbinkertn@umich.edu
10643546Sgblack@eecs.umich.edu    for (int i=0; i<fromDecode->size; i++) {
10653546Sgblack@eecs.umich.edu        if (!fromDecode->insts[i]->isSquashed())
10663546Sgblack@eecs.umich.edu            inst_count++;
1067955SN/A    }
1068955SN/A
1069955SN/A    return inst_count;
1070955SN/A}
10715863Snate@binkert.org
10725863Snate@binkert.orgtemplate <class Impl>
10735343Sstever@gmail.comvoid
10745343Sstever@gmail.comDefaultRename<Impl>::readStallSignals(unsigned tid)
10756121Snate@binkert.org{
10765863Snate@binkert.org    if (fromIEW->iewBlock[tid]) {
10774773Snate@binkert.org        stalls[tid].iew = true;
10785863Snate@binkert.org    }
10792632Sstever@eecs.umich.edu
10805863Snate@binkert.org    if (fromIEW->iewUnblock[tid]) {
10812023SN/A        assert(stalls[tid].iew);
10825863Snate@binkert.org        stalls[tid].iew = false;
10835863Snate@binkert.org    }
10845863Snate@binkert.org
10855863Snate@binkert.org    if (fromCommit->commitBlock[tid]) {
10865863Snate@binkert.org        stalls[tid].commit = true;
10875863Snate@binkert.org    }
10885863Snate@binkert.org
10895863Snate@binkert.org    if (fromCommit->commitUnblock[tid]) {
10905863Snate@binkert.org        assert(stalls[tid].commit);
10912632Sstever@eecs.umich.edu        stalls[tid].commit = false;
10925863Snate@binkert.org    }
10932023SN/A}
10942632Sstever@eecs.umich.edu
10955863Snate@binkert.orgtemplate <class Impl>
10965342Sstever@gmail.combool
10975863Snate@binkert.orgDefaultRename<Impl>::checkStall(unsigned tid)
10982632Sstever@eecs.umich.edu{
10995863Snate@binkert.org    bool ret_val = false;
11005863Snate@binkert.org
11018267Ssteve.reinhardt@amd.com    if (stalls[tid].iew) {
11028120Sgblack@eecs.umich.edu        DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid);
11038267Ssteve.reinhardt@amd.com        ret_val = true;
11048267Ssteve.reinhardt@amd.com    } else if (stalls[tid].commit) {
11058267Ssteve.reinhardt@amd.com        DPRINTF(Rename,"[tid:%i]: Stall from Commit stage detected.\n", tid);
11068267Ssteve.reinhardt@amd.com        ret_val = true;
11078267Ssteve.reinhardt@amd.com    } else if (calcFreeROBEntries(tid) <= 0) {
11088267Ssteve.reinhardt@amd.com        DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid);
11098267Ssteve.reinhardt@amd.com        ret_val = true;
11108267Ssteve.reinhardt@amd.com    } else if (calcFreeIQEntries(tid) <= 0) {
11118267Ssteve.reinhardt@amd.com        DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid);
11125863Snate@binkert.org        ret_val = true;
11135863Snate@binkert.org    } else if (calcFreeLSQEntries(tid) <= 0) {
11145863Snate@binkert.org        DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid);
11152632Sstever@eecs.umich.edu        ret_val = true;
11168267Ssteve.reinhardt@amd.com    } else if (renameMap[tid]->numFreeEntries() <= 0) {
11178267Ssteve.reinhardt@amd.com        DPRINTF(Rename,"[tid:%i]: Stall: RenameMap has 0 free entries.\n", tid);
11188267Ssteve.reinhardt@amd.com        ret_val = true;
11192632Sstever@eecs.umich.edu    } else if (renameStatus[tid] == SerializeStall &&
11201888SN/A               (!emptyROB[tid] || instsInProgress[tid])) {
11215863Snate@binkert.org        DPRINTF(Rename,"[tid:%i]: Stall: Serialize stall and ROB is not "
11225863Snate@binkert.org                "empty.\n",
11231858SN/A                tid);
11248120Sgblack@eecs.umich.edu        ret_val = true;
11258120Sgblack@eecs.umich.edu    }
11267756SAli.Saidi@ARM.com
11272598SN/A    return ret_val;
11285863Snate@binkert.org}
11291858SN/A
11301858SN/Atemplate <class Impl>
11311858SN/Avoid
11325863Snate@binkert.orgDefaultRename<Impl>::readFreeEntries(unsigned tid)
11331858SN/A{
11341858SN/A    bool updated = false;
11351858SN/A    if (fromIEW->iewInfo[tid].usedIQ) {
11365863Snate@binkert.org        freeEntries[tid].iqEntries =
11371871SN/A            fromIEW->iewInfo[tid].freeIQEntries;
11381858SN/A        updated = true;
11391858SN/A    }
11401858SN/A
11411858SN/A    if (fromIEW->iewInfo[tid].usedLSQ) {
11425863Snate@binkert.org        freeEntries[tid].lsqEntries =
11435863Snate@binkert.org            fromIEW->iewInfo[tid].freeLSQEntries;
11441869SN/A        updated = true;
11451965SN/A    }
11467739Sgblack@eecs.umich.edu
11471965SN/A    if (fromCommit->commitInfo[tid].usedROB) {
11489045SAli.Saidi@ARM.com        freeEntries[tid].robEntries =
11499045SAli.Saidi@ARM.com            fromCommit->commitInfo[tid].freeROBEntries;
11509045SAli.Saidi@ARM.com        emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
11512761Sstever@eecs.umich.edu        updated = true;
11525863Snate@binkert.org    }
11531869SN/A
11545863Snate@binkert.org    DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, Free LSQ: %i\n",
11552667Sstever@eecs.umich.edu            tid,
11561869SN/A            freeEntries[tid].iqEntries,
11571869SN/A            freeEntries[tid].robEntries,
11582929Sktlim@umich.edu            freeEntries[tid].lsqEntries);
11592929Sktlim@umich.edu
11605863Snate@binkert.org    DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n",
11612929Sktlim@umich.edu            tid, instsInProgress[tid]);
1162955SN/A}
11638120Sgblack@eecs.umich.edu
11648120Sgblack@eecs.umich.edutemplate <class Impl>
11658120Sgblack@eecs.umich.edubool
11668120Sgblack@eecs.umich.eduDefaultRename<Impl>::checkSignalsAndUpdate(unsigned tid)
11678120Sgblack@eecs.umich.edu{
11688120Sgblack@eecs.umich.edu    // Check if there's a squash signal, squash if there is
11698120Sgblack@eecs.umich.edu    // Check stall signals, block if necessary.
11708120Sgblack@eecs.umich.edu    // If status was blocked
11718120Sgblack@eecs.umich.edu    //     check if stall conditions have passed
11728120Sgblack@eecs.umich.edu    //         if so then go to unblocking
11738120Sgblack@eecs.umich.edu    // If status was Squashing
11748120Sgblack@eecs.umich.edu    //     check if squashing is not high.  Switch to running this cycle.
1175    // If status was serialize stall
1176    //     check if ROB is empty and no insts are in flight to the ROB
1177
1178    readFreeEntries(tid);
1179    readStallSignals(tid);
1180
1181    if (fromCommit->commitInfo[tid].squash) {
1182        DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from "
1183                "commit.\n", tid);
1184
1185#if ISA_HAS_DELAY_SLOT
1186        InstSeqNum squashed_seq_num = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
1187#else
1188        InstSeqNum squashed_seq_num = fromCommit->commitInfo[tid].doneSeqNum;
1189#endif
1190
1191        squash(squashed_seq_num, tid);
1192
1193        return true;
1194    }
1195
1196    if (fromCommit->commitInfo[tid].robSquashing) {
1197        DPRINTF(Rename, "[tid:%u]: ROB is still squashing.\n", tid);
1198
1199        renameStatus[tid] = Squashing;
1200
1201        return true;
1202    }
1203
1204    if (checkStall(tid)) {
1205        return block(tid);
1206    }
1207
1208    if (renameStatus[tid] == Blocked) {
1209        DPRINTF(Rename, "[tid:%u]: Done blocking, switching to unblocking.\n",
1210                tid);
1211
1212        renameStatus[tid] = Unblocking;
1213
1214        unblock(tid);
1215
1216        return true;
1217    }
1218
1219    if (renameStatus[tid] == Squashing) {
1220        // Switch status to running if rename isn't being told to block or
1221        // squash this cycle.
1222        DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n",
1223                tid);
1224
1225        renameStatus[tid] = Running;
1226
1227        return false;
1228    }
1229
1230    if (renameStatus[tid] == SerializeStall) {
1231        // Stall ends once the ROB is free.
1232        DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to "
1233                "unblocking.\n", tid);
1234
1235        DynInstPtr serial_inst = serializeInst[tid];
1236
1237        renameStatus[tid] = Unblocking;
1238
1239        unblock(tid);
1240
1241        DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with "
1242                "PC %#x.\n",
1243                tid, serial_inst->seqNum, serial_inst->readPC());
1244
1245        // Put instruction into queue here.
1246        serial_inst->clearSerializeBefore();
1247
1248        if (!skidBuffer[tid].empty()) {
1249            skidBuffer[tid].push_front(serial_inst);
1250        } else {
1251            insts[tid].push_front(serial_inst);
1252        }
1253
1254        DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename."
1255                " Adding to front of list.\n", tid);
1256
1257        serializeInst[tid] = NULL;
1258
1259        return true;
1260    }
1261
1262    // If we've reached this point, we have not gotten any signals that
1263    // cause rename to change its status.  Rename remains the same as before.
1264    return false;
1265}
1266
1267template<class Impl>
1268void
1269DefaultRename<Impl>::serializeAfter(InstQueue &inst_list,
1270                                   unsigned tid)
1271{
1272    if (inst_list.empty()) {
1273        // Mark a bit to say that I must serialize on the next instruction.
1274        serializeOnNextInst[tid] = true;
1275        return;
1276    }
1277
1278    // Set the next instruction as serializing.
1279    inst_list.front()->setSerializeBefore();
1280}
1281
1282template <class Impl>
1283inline void
1284DefaultRename<Impl>::incrFullStat(const FullSource &source)
1285{
1286    switch (source) {
1287      case ROB:
1288        ++renameROBFullEvents;
1289        break;
1290      case IQ:
1291        ++renameIQFullEvents;
1292        break;
1293      case LSQ:
1294        ++renameLSQFullEvents;
1295        break;
1296      default:
1297        panic("Rename full stall stat should be incremented for a reason!");
1298        break;
1299    }
1300}
1301
1302template <class Impl>
1303void
1304DefaultRename<Impl>::dumpHistory()
1305{
1306    typename std::list<RenameHistory>::iterator buf_it;
1307
1308    for (int i = 0; i < numThreads; i++) {
1309
1310        buf_it = historyBuffer[i].begin();
1311
1312        while (buf_it != historyBuffer[i].end()) {
1313            cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
1314                    "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
1315                    (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
1316
1317            buf_it++;
1318        }
1319    }
1320}
1321