rename_impl.hh revision 11650:fe601d7bd955
17396Sgblack@eecs.umich.edu/*
210037SARM gem5 Developers * Copyright (c) 2010-2012, 2014-2015 ARM Limited
37396Sgblack@eecs.umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc.
47396Sgblack@eecs.umich.edu * All rights reserved.
57396Sgblack@eecs.umich.edu *
67396Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
77396Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
87396Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
97396Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
107396Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
117396Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
127396Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
137396Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
147396Sgblack@eecs.umich.edu *
157396Sgblack@eecs.umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan
167396Sgblack@eecs.umich.edu * All rights reserved.
177396Sgblack@eecs.umich.edu *
187396Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
197396Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
207396Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
217396Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
227396Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
237396Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
247396Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
257396Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
267396Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
277396Sgblack@eecs.umich.edu * this software without specific prior written permission.
287396Sgblack@eecs.umich.edu *
297396Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
307396Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
317396Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
327396Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
337396Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
347396Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
357396Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
367396Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
377396Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
387396Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
397396Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
407396Sgblack@eecs.umich.edu *
417396Sgblack@eecs.umich.edu * Authors: Kevin Lim
427434Sgblack@eecs.umich.edu *          Korey Sewell
437434Sgblack@eecs.umich.edu */
447434Sgblack@eecs.umich.edu
457434Sgblack@eecs.umich.edu#ifndef __CPU_O3_RENAME_IMPL_HH__
467434Sgblack@eecs.umich.edu#define __CPU_O3_RENAME_IMPL_HH__
477434Sgblack@eecs.umich.edu
487396Sgblack@eecs.umich.edu#include <list>
4910037SARM gem5 Developers
5010037SARM gem5 Developers#include "arch/isa_traits.hh"
5110037SARM gem5 Developers#include "arch/registers.hh"
5210037SARM gem5 Developers#include "config/the_isa.hh"
5310037SARM gem5 Developers#include "cpu/o3/rename.hh"
5410037SARM gem5 Developers#include "cpu/reg_class.hh"
5510037SARM gem5 Developers#include "debug/Activity.hh"
5610037SARM gem5 Developers#include "debug/Rename.hh"
5710037SARM gem5 Developers#include "debug/O3PipeView.hh"
5810037SARM gem5 Developers#include "params/DerivO3CPU.hh"
5910037SARM gem5 Developers
6010037SARM gem5 Developersusing namespace std;
6110037SARM gem5 Developers
6210037SARM gem5 Developerstemplate <class Impl>
6310037SARM gem5 DevelopersDefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params)
6410037SARM gem5 Developers    : cpu(_cpu),
6510037SARM gem5 Developers      iewToRenameDelay(params->iewToRenameDelay),
6610037SARM gem5 Developers      decodeToRenameDelay(params->decodeToRenameDelay),
6710037SARM gem5 Developers      commitToRenameDelay(params->commitToRenameDelay),
6810037SARM gem5 Developers      renameWidth(params->renameWidth),
6910037SARM gem5 Developers      commitWidth(params->commitWidth),
7010037SARM gem5 Developers      numThreads(params->numThreads),
7110037SARM gem5 Developers      maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs
7210037SARM gem5 Developers                      + params->numPhysCCRegs)
7310037SARM gem5 Developers{
7410037SARM gem5 Developers    if (renameWidth > Impl::MaxWidth)
7510037SARM gem5 Developers        fatal("renameWidth (%d) is larger than compiled limit (%d),\n"
7610037SARM gem5 Developers             "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
7710037SARM gem5 Developers             renameWidth, static_cast<int>(Impl::MaxWidth));
7810037SARM gem5 Developers
7910037SARM gem5 Developers    // @todo: Make into a parameter.
807396Sgblack@eecs.umich.edu    skidBufferMax = (decodeToRenameDelay + 1) * params->decodeWidth;
817396Sgblack@eecs.umich.edu}
827396Sgblack@eecs.umich.edu
837396Sgblack@eecs.umich.edutemplate <class Impl>
849918Ssteve.reinhardt@amd.comstd::string
857396Sgblack@eecs.umich.eduDefaultRename<Impl>::name() const
869918Ssteve.reinhardt@amd.com{
877396Sgblack@eecs.umich.edu    return cpu->name() + ".rename";
887396Sgblack@eecs.umich.edu}
897396Sgblack@eecs.umich.edu
907396Sgblack@eecs.umich.edutemplate <class Impl>
917396Sgblack@eecs.umich.eduvoid
927396Sgblack@eecs.umich.eduDefaultRename<Impl>::regStats()
937396Sgblack@eecs.umich.edu{
947396Sgblack@eecs.umich.edu    renameSquashCycles
959918Ssteve.reinhardt@amd.com        .name(name() + ".SquashCycles")
967396Sgblack@eecs.umich.edu        .desc("Number of cycles rename is squashing")
977396Sgblack@eecs.umich.edu        .prereq(renameSquashCycles);
987396Sgblack@eecs.umich.edu    renameIdleCycles
997396Sgblack@eecs.umich.edu        .name(name() + ".IdleCycles")
1007396Sgblack@eecs.umich.edu        .desc("Number of cycles rename is idle")
1017396Sgblack@eecs.umich.edu        .prereq(renameIdleCycles);
1027396Sgblack@eecs.umich.edu    renameBlockCycles
1037396Sgblack@eecs.umich.edu        .name(name() + ".BlockCycles")
1047396Sgblack@eecs.umich.edu        .desc("Number of cycles rename is blocking")
1059918Ssteve.reinhardt@amd.com        .prereq(renameBlockCycles);
1067396Sgblack@eecs.umich.edu    renameSerializeStallCycles
1079918Ssteve.reinhardt@amd.com        .name(name() + ".serializeStallCycles")
1087396Sgblack@eecs.umich.edu        .desc("count of cycles rename stalled for serializing inst")
1097396Sgblack@eecs.umich.edu        .flags(Stats::total);
1107396Sgblack@eecs.umich.edu    renameRunCycles
1117396Sgblack@eecs.umich.edu        .name(name() + ".RunCycles")
1127396Sgblack@eecs.umich.edu        .desc("Number of cycles rename is running")
1137396Sgblack@eecs.umich.edu        .prereq(renameIdleCycles);
1147396Sgblack@eecs.umich.edu    renameUnblockCycles
1157396Sgblack@eecs.umich.edu        .name(name() + ".UnblockCycles")
1167396Sgblack@eecs.umich.edu        .desc("Number of cycles rename is unblocking")
1179918Ssteve.reinhardt@amd.com        .prereq(renameUnblockCycles);
1187396Sgblack@eecs.umich.edu    renameRenamedInsts
1199918Ssteve.reinhardt@amd.com        .name(name() + ".RenamedInsts")
1207396Sgblack@eecs.umich.edu        .desc("Number of instructions processed by rename")
1219918Ssteve.reinhardt@amd.com        .prereq(renameRenamedInsts);
1227396Sgblack@eecs.umich.edu    renameSquashedInsts
1237396Sgblack@eecs.umich.edu        .name(name() + ".SquashedInsts")
1247430Sgblack@eecs.umich.edu        .desc("Number of squashed instructions processed by rename")
1257639Sgblack@eecs.umich.edu        .prereq(renameSquashedInsts);
12610037SARM gem5 Developers    renameROBFullEvents
12710037SARM gem5 Developers        .name(name() + ".ROBFullEvents")
12810037SARM gem5 Developers        .desc("Number of times rename has blocked due to ROB full")
12910037SARM gem5 Developers        .prereq(renameROBFullEvents);
13010037SARM gem5 Developers    renameIQFullEvents
13110037SARM gem5 Developers        .name(name() + ".IQFullEvents")
13210037SARM gem5 Developers        .desc("Number of times rename has blocked due to IQ full")
13310037SARM gem5 Developers        .prereq(renameIQFullEvents);
13410037SARM gem5 Developers    renameLQFullEvents
13510037SARM gem5 Developers        .name(name() + ".LQFullEvents")
13610037SARM gem5 Developers        .desc("Number of times rename has blocked due to LQ full")
13710037SARM gem5 Developers        .prereq(renameLQFullEvents);
13810037SARM gem5 Developers    renameSQFullEvents
13910037SARM gem5 Developers        .name(name() + ".SQFullEvents")
14010037SARM gem5 Developers        .desc("Number of times rename has blocked due to SQ full")
1417639Sgblack@eecs.umich.edu        .prereq(renameSQFullEvents);
1427639Sgblack@eecs.umich.edu    renameFullRegistersEvents
1437639Sgblack@eecs.umich.edu        .name(name() + ".FullRegisterEvents")
1447639Sgblack@eecs.umich.edu        .desc("Number of times there has been no free registers")
1459918Ssteve.reinhardt@amd.com        .prereq(renameFullRegistersEvents);
1467639Sgblack@eecs.umich.edu    renameRenamedOperands
1479918Ssteve.reinhardt@amd.com        .name(name() + ".RenamedOperands")
1487639Sgblack@eecs.umich.edu        .desc("Number of destination operands rename has renamed")
1499918Ssteve.reinhardt@amd.com        .prereq(renameRenamedOperands);
1507639Sgblack@eecs.umich.edu    renameRenameLookups
1517639Sgblack@eecs.umich.edu        .name(name() + ".RenameLookups")
1527639Sgblack@eecs.umich.edu        .desc("Number of register rename lookups that rename has made")
1537639Sgblack@eecs.umich.edu        .prereq(renameRenameLookups);
1547430Sgblack@eecs.umich.edu    renameCommittedMaps
1557430Sgblack@eecs.umich.edu        .name(name() + ".CommittedMaps")
1567430Sgblack@eecs.umich.edu        .desc("Number of HB maps that are committed")
1577430Sgblack@eecs.umich.edu        .prereq(renameCommittedMaps);
1587430Sgblack@eecs.umich.edu    renameUndoneMaps
1597430Sgblack@eecs.umich.edu        .name(name() + ".UndoneMaps")
1607430Sgblack@eecs.umich.edu        .desc("Number of HB maps that are undone due to squashing")
1617430Sgblack@eecs.umich.edu        .prereq(renameUndoneMaps);
1627430Sgblack@eecs.umich.edu    renamedSerializing
1637430Sgblack@eecs.umich.edu        .name(name() + ".serializingInsts")
1647430Sgblack@eecs.umich.edu        .desc("count of serializing insts renamed")
1657430Sgblack@eecs.umich.edu        .flags(Stats::total)
1667430Sgblack@eecs.umich.edu        ;
1677430Sgblack@eecs.umich.edu    renamedTempSerializing
1687430Sgblack@eecs.umich.edu        .name(name() + ".tempSerializingInsts")
1697430Sgblack@eecs.umich.edu        .desc("count of temporary serializing insts renamed")
1707430Sgblack@eecs.umich.edu        .flags(Stats::total)
1717430Sgblack@eecs.umich.edu        ;
1727430Sgblack@eecs.umich.edu    renameSkidInsts
1737430Sgblack@eecs.umich.edu        .name(name() + ".skidInsts")
1747430Sgblack@eecs.umich.edu        .desc("count of insts added to the skid buffer")
1757430Sgblack@eecs.umich.edu        .flags(Stats::total)
1767430Sgblack@eecs.umich.edu        ;
1777430Sgblack@eecs.umich.edu    intRenameLookups
1787430Sgblack@eecs.umich.edu        .name(name() + ".int_rename_lookups")
1797430Sgblack@eecs.umich.edu        .desc("Number of integer rename lookups")
18010037SARM gem5 Developers        .prereq(intRenameLookups);
1817430Sgblack@eecs.umich.edu    fpRenameLookups
1827430Sgblack@eecs.umich.edu        .name(name() + ".fp_rename_lookups")
1837430Sgblack@eecs.umich.edu        .desc("Number of floating rename lookups")
18410037SARM gem5 Developers        .prereq(fpRenameLookups);
1857430Sgblack@eecs.umich.edu}
1867430Sgblack@eecs.umich.edu
18710037SARM gem5 Developerstemplate <class Impl>
1887430Sgblack@eecs.umich.eduvoid
1897430Sgblack@eecs.umich.eduDefaultRename<Impl>::regProbePoints()
19010037SARM gem5 Developers{
1917430Sgblack@eecs.umich.edu    ppRename = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Rename");
1927430Sgblack@eecs.umich.edu    ppSquashInRename = new ProbePointArg<SeqNumRegPair>(cpu->getProbeManager(),
1937430Sgblack@eecs.umich.edu                                                        "SquashInRename");
1947430Sgblack@eecs.umich.edu}
19510037SARM gem5 Developers
19610037SARM gem5 Developerstemplate <class Impl>
1977430Sgblack@eecs.umich.eduvoid
19810037SARM gem5 DevelopersDefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
1997430Sgblack@eecs.umich.edu{
2007430Sgblack@eecs.umich.edu    timeBuffer = tb_ptr;
2017430Sgblack@eecs.umich.edu
2027430Sgblack@eecs.umich.edu    // Setup wire to read information from time buffer, from IEW stage.
2037430Sgblack@eecs.umich.edu    fromIEW = timeBuffer->getWire(-iewToRenameDelay);
2047430Sgblack@eecs.umich.edu
2057430Sgblack@eecs.umich.edu    // Setup wire to read infromation from time buffer, from commit stage.
2067639Sgblack@eecs.umich.edu    fromCommit = timeBuffer->getWire(-commitToRenameDelay);
2077430Sgblack@eecs.umich.edu
2087430Sgblack@eecs.umich.edu    // Setup wire to write information to previous stages.
2097430Sgblack@eecs.umich.edu    toDecode = timeBuffer->getWire(0);
2107430Sgblack@eecs.umich.edu}
2117430Sgblack@eecs.umich.edu
2127430Sgblack@eecs.umich.edutemplate <class Impl>
2137430Sgblack@eecs.umich.eduvoid
2147639Sgblack@eecs.umich.eduDefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
2157430Sgblack@eecs.umich.edu{
2167430Sgblack@eecs.umich.edu    renameQueue = rq_ptr;
2177430Sgblack@eecs.umich.edu
2187430Sgblack@eecs.umich.edu    // Setup wire to write information to future stages.
2197639Sgblack@eecs.umich.edu    toIEW = renameQueue->getWire(0);
2207430Sgblack@eecs.umich.edu}
2217430Sgblack@eecs.umich.edu
2227430Sgblack@eecs.umich.edutemplate <class Impl>
2237430Sgblack@eecs.umich.eduvoid
2247430Sgblack@eecs.umich.eduDefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
2257430Sgblack@eecs.umich.edu{
2267430Sgblack@eecs.umich.edu    decodeQueue = dq_ptr;
2277430Sgblack@eecs.umich.edu
2287430Sgblack@eecs.umich.edu    // Setup wire to get information from decode.
2297430Sgblack@eecs.umich.edu    fromDecode = decodeQueue->getWire(-decodeToRenameDelay);
2307639Sgblack@eecs.umich.edu}
2317430Sgblack@eecs.umich.edu
2327639Sgblack@eecs.umich.edutemplate <class Impl>
2337430Sgblack@eecs.umich.eduvoid
2347430Sgblack@eecs.umich.eduDefaultRename<Impl>::startupStage()
2357430Sgblack@eecs.umich.edu{
2367639Sgblack@eecs.umich.edu    resetStage();
2377430Sgblack@eecs.umich.edu}
2387430Sgblack@eecs.umich.edu
2397430Sgblack@eecs.umich.edutemplate <class Impl>
2407430Sgblack@eecs.umich.eduvoid
2417430Sgblack@eecs.umich.eduDefaultRename<Impl>::resetStage()
2427430Sgblack@eecs.umich.edu{
2437430Sgblack@eecs.umich.edu    _status = Inactive;
2447430Sgblack@eecs.umich.edu
2457430Sgblack@eecs.umich.edu    resumeSerialize = false;
2467430Sgblack@eecs.umich.edu    resumeUnblocking = false;
2477639Sgblack@eecs.umich.edu
2487430Sgblack@eecs.umich.edu    // Grab the number of free entries directly from the stages.
2497430Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
2507430Sgblack@eecs.umich.edu        renameStatus[tid] = Idle;
2517430Sgblack@eecs.umich.edu
2527430Sgblack@eecs.umich.edu        freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);
2537430Sgblack@eecs.umich.edu        freeEntries[tid].lqEntries = iew_ptr->ldstQueue.numFreeLoadEntries(tid);
2547430Sgblack@eecs.umich.edu        freeEntries[tid].sqEntries = iew_ptr->ldstQueue.numFreeStoreEntries(tid);
2557430Sgblack@eecs.umich.edu        freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);
2567430Sgblack@eecs.umich.edu        emptyROB[tid] = true;
2577430Sgblack@eecs.umich.edu
2587639Sgblack@eecs.umich.edu        stalls[tid].iew = false;
2597430Sgblack@eecs.umich.edu        serializeInst[tid] = NULL;
2607430Sgblack@eecs.umich.edu
2617430Sgblack@eecs.umich.edu        instsInProgress[tid] = 0;
2627430Sgblack@eecs.umich.edu        loadsInProgress[tid] = 0;
2637430Sgblack@eecs.umich.edu        storesInProgress[tid] = 0;
2647430Sgblack@eecs.umich.edu
2657430Sgblack@eecs.umich.edu        serializeOnNextInst[tid] = false;
2667430Sgblack@eecs.umich.edu    }
2677430Sgblack@eecs.umich.edu}
2687430Sgblack@eecs.umich.edu
2697639Sgblack@eecs.umich.edutemplate<class Impl>
2707639Sgblack@eecs.umich.eduvoid
2717430Sgblack@eecs.umich.eduDefaultRename<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
2727639Sgblack@eecs.umich.edu{
2737639Sgblack@eecs.umich.edu    activeThreads = at_ptr;
2747430Sgblack@eecs.umich.edu}
2757430Sgblack@eecs.umich.edu
2767430Sgblack@eecs.umich.edu
2777639Sgblack@eecs.umich.edutemplate <class Impl>
2787430Sgblack@eecs.umich.eduvoid
2797639Sgblack@eecs.umich.eduDefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[])
2807430Sgblack@eecs.umich.edu{
2817430Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++)
2827430Sgblack@eecs.umich.edu        renameMap[tid] = &rm_ptr[tid];
2837430Sgblack@eecs.umich.edu}
2847430Sgblack@eecs.umich.edu
2857430Sgblack@eecs.umich.edutemplate <class Impl>
2867430Sgblack@eecs.umich.eduvoid
2877430Sgblack@eecs.umich.eduDefaultRename<Impl>::setFreeList(FreeList *fl_ptr)
2887430Sgblack@eecs.umich.edu{
2897430Sgblack@eecs.umich.edu    freeList = fl_ptr;
2907430Sgblack@eecs.umich.edu}
2917430Sgblack@eecs.umich.edu
2927430Sgblack@eecs.umich.edutemplate<class Impl>
2937430Sgblack@eecs.umich.eduvoid
2947639Sgblack@eecs.umich.eduDefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
2957430Sgblack@eecs.umich.edu{
2967430Sgblack@eecs.umich.edu    scoreboard = _scoreboard;
2977430Sgblack@eecs.umich.edu}
2987430Sgblack@eecs.umich.edu
2997430Sgblack@eecs.umich.edutemplate <class Impl>
3007430Sgblack@eecs.umich.edubool
3017430Sgblack@eecs.umich.eduDefaultRename<Impl>::isDrained() const
3027430Sgblack@eecs.umich.edu{
3037430Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
3047430Sgblack@eecs.umich.edu        if (instsInProgress[tid] != 0 ||
3057639Sgblack@eecs.umich.edu            !historyBuffer[tid].empty() ||
3067639Sgblack@eecs.umich.edu            !skidBuffer[tid].empty() ||
3077430Sgblack@eecs.umich.edu            !insts[tid].empty() ||
3087639Sgblack@eecs.umich.edu            (renameStatus[tid] != Idle && renameStatus[tid] != Running))
3097639Sgblack@eecs.umich.edu            return false;
3107430Sgblack@eecs.umich.edu    }
3117430Sgblack@eecs.umich.edu    return true;
3127430Sgblack@eecs.umich.edu}
3137430Sgblack@eecs.umich.edu
3147430Sgblack@eecs.umich.edutemplate <class Impl>
3157430Sgblack@eecs.umich.eduvoid
3167430Sgblack@eecs.umich.eduDefaultRename<Impl>::takeOverFrom()
3177430Sgblack@eecs.umich.edu{
3187430Sgblack@eecs.umich.edu    resetStage();
3197430Sgblack@eecs.umich.edu}
3207430Sgblack@eecs.umich.edu
3217430Sgblack@eecs.umich.edutemplate <class Impl>
3227430Sgblack@eecs.umich.eduvoid
3237639Sgblack@eecs.umich.eduDefaultRename<Impl>::drainSanityCheck() const
3247430Sgblack@eecs.umich.edu{
3257430Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
3267430Sgblack@eecs.umich.edu        assert(historyBuffer[tid].empty());
3277430Sgblack@eecs.umich.edu        assert(insts[tid].empty());
3287430Sgblack@eecs.umich.edu        assert(skidBuffer[tid].empty());
3297430Sgblack@eecs.umich.edu        assert(instsInProgress[tid] == 0);
3307430Sgblack@eecs.umich.edu    }
3317430Sgblack@eecs.umich.edu}
3327430Sgblack@eecs.umich.edu
3337430Sgblack@eecs.umich.edutemplate <class Impl>
3347430Sgblack@eecs.umich.eduvoid
3357430Sgblack@eecs.umich.eduDefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, ThreadID tid)
3367430Sgblack@eecs.umich.edu{
3377430Sgblack@eecs.umich.edu    DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid);
3387430Sgblack@eecs.umich.edu
3397430Sgblack@eecs.umich.edu    // Clear the stall signal if rename was blocked or unblocking before.
3407430Sgblack@eecs.umich.edu    // If it still needs to block, the blocking should happen the next
3417430Sgblack@eecs.umich.edu    // cycle and there should be space to hold everything due to the squash.
3427430Sgblack@eecs.umich.edu    if (renameStatus[tid] == Blocked ||
3437430Sgblack@eecs.umich.edu        renameStatus[tid] == Unblocking) {
3447430Sgblack@eecs.umich.edu        toDecode->renameUnblock[tid] = 1;
3457430Sgblack@eecs.umich.edu
3467430Sgblack@eecs.umich.edu        resumeSerialize = false;
3477430Sgblack@eecs.umich.edu        serializeInst[tid] = NULL;
3487430Sgblack@eecs.umich.edu    } else if (renameStatus[tid] == SerializeStall) {
3497430Sgblack@eecs.umich.edu        if (serializeInst[tid]->seqNum <= squash_seq_num) {
3507430Sgblack@eecs.umich.edu            DPRINTF(Rename, "Rename will resume serializing after squash\n");
3517430Sgblack@eecs.umich.edu            resumeSerialize = true;
3527430Sgblack@eecs.umich.edu            assert(serializeInst[tid]);
3537430Sgblack@eecs.umich.edu        } else {
3547430Sgblack@eecs.umich.edu            resumeSerialize = false;
3557430Sgblack@eecs.umich.edu            toDecode->renameUnblock[tid] = 1;
3567430Sgblack@eecs.umich.edu
3577430Sgblack@eecs.umich.edu            serializeInst[tid] = NULL;
3587430Sgblack@eecs.umich.edu        }
3597639Sgblack@eecs.umich.edu    }
3607430Sgblack@eecs.umich.edu
3617430Sgblack@eecs.umich.edu    // Set the status to Squashing.
3627430Sgblack@eecs.umich.edu    renameStatus[tid] = Squashing;
3637430Sgblack@eecs.umich.edu
3647430Sgblack@eecs.umich.edu    // Squash any instructions from decode.
3657430Sgblack@eecs.umich.edu    for (int i=0; i<fromDecode->size; i++) {
3667430Sgblack@eecs.umich.edu        if (fromDecode->insts[i]->threadNumber == tid &&
3677430Sgblack@eecs.umich.edu            fromDecode->insts[i]->seqNum > squash_seq_num) {
3687430Sgblack@eecs.umich.edu            fromDecode->insts[i]->setSquashed();
3697430Sgblack@eecs.umich.edu            wroteToTimeBuffer = true;
3707430Sgblack@eecs.umich.edu        }
3717430Sgblack@eecs.umich.edu
3727430Sgblack@eecs.umich.edu    }
3737430Sgblack@eecs.umich.edu
3747430Sgblack@eecs.umich.edu    // Clear the instruction list and skid buffer in case they have any
3757430Sgblack@eecs.umich.edu    // insts in them.
3767430Sgblack@eecs.umich.edu    insts[tid].clear();
3777430Sgblack@eecs.umich.edu
3787430Sgblack@eecs.umich.edu    // Clear the skid buffer in case it has any data in it.
37910037SARM gem5 Developers    skidBuffer[tid].clear();
38010037SARM gem5 Developers
38110037SARM gem5 Developers    doSquash(squash_seq_num, tid);
3827430Sgblack@eecs.umich.edu}
38310037SARM gem5 Developers
38410037SARM gem5 Developerstemplate <class Impl>
38510037SARM gem5 Developersvoid
38610037SARM gem5 DevelopersDefaultRename<Impl>::tick()
38710037SARM gem5 Developers{
38810037SARM gem5 Developers    wroteToTimeBuffer = false;
38910037SARM gem5 Developers
39010037SARM gem5 Developers    blockThisCycle = false;
39110037SARM gem5 Developers
39210037SARM gem5 Developers    bool status_change = false;
39310037SARM gem5 Developers
39410037SARM gem5 Developers    toIEWIndex = 0;
39510037SARM gem5 Developers
39610037SARM gem5 Developers    sortInsts();
39710037SARM gem5 Developers
3987430Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
39910037SARM gem5 Developers    list<ThreadID>::iterator end = activeThreads->end();
40010037SARM gem5 Developers
40110037SARM gem5 Developers    // Check stall and squash signals.
40210037SARM gem5 Developers    while (threads != end) {
4037430Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
40410037SARM gem5 Developers
40510037SARM gem5 Developers        DPRINTF(Rename, "Processing [tid:%i]\n", tid);
4067430Sgblack@eecs.umich.edu
4077430Sgblack@eecs.umich.edu        status_change = checkSignalsAndUpdate(tid) || status_change;
4087430Sgblack@eecs.umich.edu
4097430Sgblack@eecs.umich.edu        rename(status_change, tid);
4107430Sgblack@eecs.umich.edu    }
4117430Sgblack@eecs.umich.edu
4127639Sgblack@eecs.umich.edu    if (status_change) {
4137430Sgblack@eecs.umich.edu        updateStatus();
4147430Sgblack@eecs.umich.edu    }
4157430Sgblack@eecs.umich.edu
4167639Sgblack@eecs.umich.edu    if (wroteToTimeBuffer) {
4177430Sgblack@eecs.umich.edu        DPRINTF(Activity, "Activity this cycle.\n");
4187430Sgblack@eecs.umich.edu        cpu->activityThisCycle();
4197430Sgblack@eecs.umich.edu    }
4207430Sgblack@eecs.umich.edu
4217430Sgblack@eecs.umich.edu    threads = activeThreads->begin();
4227430Sgblack@eecs.umich.edu
4237430Sgblack@eecs.umich.edu    while (threads != end) {
4247430Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4257430Sgblack@eecs.umich.edu
4267430Sgblack@eecs.umich.edu        // If we committed this cycle then doneSeqNum will be > 0
4277639Sgblack@eecs.umich.edu        if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
4287430Sgblack@eecs.umich.edu            !fromCommit->commitInfo[tid].squash &&
4297430Sgblack@eecs.umich.edu            renameStatus[tid] != Squashing) {
4307430Sgblack@eecs.umich.edu
4317430Sgblack@eecs.umich.edu            removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum,
4327430Sgblack@eecs.umich.edu                                  tid);
4337430Sgblack@eecs.umich.edu        }
4347430Sgblack@eecs.umich.edu    }
4357430Sgblack@eecs.umich.edu
4367430Sgblack@eecs.umich.edu    // @todo: make into updateProgress function
4377430Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
4387430Sgblack@eecs.umich.edu        instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
4397430Sgblack@eecs.umich.edu        loadsInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToLQ;
4407430Sgblack@eecs.umich.edu        storesInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToSQ;
4417430Sgblack@eecs.umich.edu        assert(loadsInProgress[tid] >= 0);
4427430Sgblack@eecs.umich.edu        assert(storesInProgress[tid] >= 0);
4437430Sgblack@eecs.umich.edu        assert(instsInProgress[tid] >=0);
4447639Sgblack@eecs.umich.edu    }
4457430Sgblack@eecs.umich.edu
4467430Sgblack@eecs.umich.edu}
4477430Sgblack@eecs.umich.edu
4487430Sgblack@eecs.umich.edutemplate<class Impl>
4497430Sgblack@eecs.umich.eduvoid
4507430Sgblack@eecs.umich.eduDefaultRename<Impl>::rename(bool &status_change, ThreadID tid)
4517639Sgblack@eecs.umich.edu{
4527430Sgblack@eecs.umich.edu    // If status is Running or idle,
4537430Sgblack@eecs.umich.edu    //     call renameInsts()
4547430Sgblack@eecs.umich.edu    // If status is Unblocking,
4557430Sgblack@eecs.umich.edu    //     buffer any instructions coming from decode
4567430Sgblack@eecs.umich.edu    //     continue trying to empty skid buffer
4577430Sgblack@eecs.umich.edu    //     check if stall conditions have passed
4587430Sgblack@eecs.umich.edu
4597430Sgblack@eecs.umich.edu    if (renameStatus[tid] == Blocked) {
4607430Sgblack@eecs.umich.edu        ++renameBlockCycles;
4617430Sgblack@eecs.umich.edu    } else if (renameStatus[tid] == Squashing) {
4627430Sgblack@eecs.umich.edu        ++renameSquashCycles;
4637430Sgblack@eecs.umich.edu    } else if (renameStatus[tid] == SerializeStall) {
4647430Sgblack@eecs.umich.edu        ++renameSerializeStallCycles;
4657430Sgblack@eecs.umich.edu        // If we are currently in SerializeStall and resumeSerialize
4667430Sgblack@eecs.umich.edu        // was set, then that means that we are resuming serializing
4677430Sgblack@eecs.umich.edu        // this cycle.  Tell the previous stages to block.
4687430Sgblack@eecs.umich.edu        if (resumeSerialize) {
4697430Sgblack@eecs.umich.edu            resumeSerialize = false;
47010037SARM gem5 Developers            block(tid);
47110037SARM gem5 Developers            toDecode->renameUnblock[tid] = false;
4727430Sgblack@eecs.umich.edu        }
47310037SARM gem5 Developers    } else if (renameStatus[tid] == Unblocking) {
4747430Sgblack@eecs.umich.edu        if (resumeUnblocking) {
4757430Sgblack@eecs.umich.edu            block(tid);
47610037SARM gem5 Developers            resumeUnblocking = false;
4777430Sgblack@eecs.umich.edu            toDecode->renameUnblock[tid] = false;
4787430Sgblack@eecs.umich.edu        }
4797430Sgblack@eecs.umich.edu    }
4807430Sgblack@eecs.umich.edu
4817430Sgblack@eecs.umich.edu    if (renameStatus[tid] == Running ||
4827430Sgblack@eecs.umich.edu        renameStatus[tid] == Idle) {
4837430Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run "
4847430Sgblack@eecs.umich.edu                "stage.\n", tid);
4857430Sgblack@eecs.umich.edu
4867430Sgblack@eecs.umich.edu        renameInsts(tid);
48710037SARM gem5 Developers    } else if (renameStatus[tid] == Unblocking) {
4887430Sgblack@eecs.umich.edu        renameInsts(tid);
4897430Sgblack@eecs.umich.edu
4907430Sgblack@eecs.umich.edu        if (validInsts()) {
4917430Sgblack@eecs.umich.edu            // Add the current inputs to the skid buffer so they can be
4927430Sgblack@eecs.umich.edu            // reprocessed when this stage unblocks.
4937430Sgblack@eecs.umich.edu            skidInsert(tid);
4947430Sgblack@eecs.umich.edu        }
4957430Sgblack@eecs.umich.edu
4967639Sgblack@eecs.umich.edu        // If we switched over to blocking, then there's a potential for
4977430Sgblack@eecs.umich.edu        // an overall status change.
4987430Sgblack@eecs.umich.edu        status_change = unblock(tid) || status_change || blockThisCycle;
4997430Sgblack@eecs.umich.edu    }
5007430Sgblack@eecs.umich.edu}
5017430Sgblack@eecs.umich.edu
5027430Sgblack@eecs.umich.edutemplate <class Impl>
5037430Sgblack@eecs.umich.eduvoid
5047430Sgblack@eecs.umich.eduDefaultRename<Impl>::renameInsts(ThreadID tid)
5057430Sgblack@eecs.umich.edu{
5067430Sgblack@eecs.umich.edu    // Instructions can be either in the skid buffer or the queue of
5077430Sgblack@eecs.umich.edu    // instructions coming from decode, depending on the status.
5087430Sgblack@eecs.umich.edu    int insts_available = renameStatus[tid] == Unblocking ?
5097430Sgblack@eecs.umich.edu        skidBuffer[tid].size() : insts[tid].size();
5107430Sgblack@eecs.umich.edu
5117430Sgblack@eecs.umich.edu    // Check the decode queue to see if instructions are available.
5127639Sgblack@eecs.umich.edu    // If there are no available instructions to rename, then do nothing.
5137430Sgblack@eecs.umich.edu    if (insts_available == 0) {
5147430Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Nothing to do, breaking out early.\n",
5157430Sgblack@eecs.umich.edu                tid);
5167430Sgblack@eecs.umich.edu        // Should I change status to idle?
5177430Sgblack@eecs.umich.edu        ++renameIdleCycles;
5187430Sgblack@eecs.umich.edu        return;
5197430Sgblack@eecs.umich.edu    } else if (renameStatus[tid] == Unblocking) {
5207430Sgblack@eecs.umich.edu        ++renameUnblockCycles;
5217430Sgblack@eecs.umich.edu    } else if (renameStatus[tid] == Running) {
5227430Sgblack@eecs.umich.edu        ++renameRunCycles;
5237430Sgblack@eecs.umich.edu    }
5247430Sgblack@eecs.umich.edu
5257430Sgblack@eecs.umich.edu    DynInstPtr inst;
5267430Sgblack@eecs.umich.edu
5277430Sgblack@eecs.umich.edu    // Will have to do a different calculation for the number of free
5287430Sgblack@eecs.umich.edu    // entries.
5297430Sgblack@eecs.umich.edu    int free_rob_entries = calcFreeROBEntries(tid);
5307430Sgblack@eecs.umich.edu    int free_iq_entries  = calcFreeIQEntries(tid);
5317430Sgblack@eecs.umich.edu    int min_free_entries = free_rob_entries;
5327430Sgblack@eecs.umich.edu
5337430Sgblack@eecs.umich.edu    FullSource source = ROB;
5347430Sgblack@eecs.umich.edu
5357430Sgblack@eecs.umich.edu    if (free_iq_entries < min_free_entries) {
5367430Sgblack@eecs.umich.edu        min_free_entries = free_iq_entries;
5377430Sgblack@eecs.umich.edu        source = IQ;
5387430Sgblack@eecs.umich.edu    }
5397430Sgblack@eecs.umich.edu
5407430Sgblack@eecs.umich.edu    // Check if there's any space left.
5417430Sgblack@eecs.umich.edu    if (min_free_entries <= 0) {
5427430Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/ "
5437430Sgblack@eecs.umich.edu                "entries.\n"
5447430Sgblack@eecs.umich.edu                "ROB has %i free entries.\n"
5457430Sgblack@eecs.umich.edu                "IQ has %i free entries.\n",
5467430Sgblack@eecs.umich.edu                tid,
5477430Sgblack@eecs.umich.edu                free_rob_entries,
5487639Sgblack@eecs.umich.edu                free_iq_entries);
5497430Sgblack@eecs.umich.edu
5507430Sgblack@eecs.umich.edu        blockThisCycle = true;
55110037SARM gem5 Developers
55210037SARM gem5 Developers        block(tid);
55310037SARM gem5 Developers
5547430Sgblack@eecs.umich.edu        incrFullStat(source);
55510037SARM gem5 Developers
55610037SARM gem5 Developers        return;
55710037SARM gem5 Developers    } else if (min_free_entries < insts_available) {
55810037SARM gem5 Developers        DPRINTF(Rename, "[tid:%u]: Will have to block this cycle."
55910037SARM gem5 Developers                "%i insts available, but only %i insts can be "
56010037SARM gem5 Developers                "renamed due to ROB/IQ/LSQ limits.\n",
56110037SARM gem5 Developers                tid, insts_available, min_free_entries);
56210037SARM gem5 Developers
56310037SARM gem5 Developers        insts_available = min_free_entries;
56410037SARM gem5 Developers
56510037SARM gem5 Developers        blockThisCycle = true;
56610037SARM gem5 Developers
56710037SARM gem5 Developers        incrFullStat(source);
56810037SARM gem5 Developers    }
56910037SARM gem5 Developers
57010037SARM gem5 Developers    InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ?
57110037SARM gem5 Developers        skidBuffer[tid] : insts[tid];
57210037SARM gem5 Developers
57310037SARM gem5 Developers    DPRINTF(Rename, "[tid:%u]: %i available instructions to "
57410037SARM gem5 Developers            "send iew.\n", tid, insts_available);
57510037SARM gem5 Developers
57610037SARM gem5 Developers    DPRINTF(Rename, "[tid:%u]: %i insts pipelining from Rename | %i insts "
57710037SARM gem5 Developers            "dispatched to IQ last cycle.\n",
57810037SARM gem5 Developers            tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched);
57910037SARM gem5 Developers
58010037SARM gem5 Developers    // Handle serializing the next instruction if necessary.
58110037SARM gem5 Developers    if (serializeOnNextInst[tid]) {
58210037SARM gem5 Developers        if (emptyROB[tid] && instsInProgress[tid] == 0) {
58310037SARM gem5 Developers            // ROB already empty; no need to serialize.
58410037SARM gem5 Developers            serializeOnNextInst[tid] = false;
5857430Sgblack@eecs.umich.edu        } else if (!insts_to_rename.empty()) {
5867639Sgblack@eecs.umich.edu            insts_to_rename.front()->setSerializeBefore();
5877639Sgblack@eecs.umich.edu        }
58810037SARM gem5 Developers    }
5897430Sgblack@eecs.umich.edu
5907430Sgblack@eecs.umich.edu    int renamed_insts = 0;
5917430Sgblack@eecs.umich.edu
5927430Sgblack@eecs.umich.edu    while (insts_available > 0 &&  toIEWIndex < renameWidth) {
59310037SARM gem5 Developers        DPRINTF(Rename, "[tid:%u]: Sending instructions to IEW.\n", tid);
5947430Sgblack@eecs.umich.edu
5957430Sgblack@eecs.umich.edu        assert(!insts_to_rename.empty());
5967430Sgblack@eecs.umich.edu
5977430Sgblack@eecs.umich.edu        inst = insts_to_rename.front();
5987430Sgblack@eecs.umich.edu
59910037SARM gem5 Developers        //For all kind of instructions, check ROB and IQ first
6007639Sgblack@eecs.umich.edu        //For load instruction, check LQ size and take into account the inflight loads
6017430Sgblack@eecs.umich.edu        //For store instruction, check SQ size and take into account the inflight stores
60210037SARM gem5 Developers
6037430Sgblack@eecs.umich.edu        if (inst->isLoad()) {
6047430Sgblack@eecs.umich.edu            if (calcFreeLQEntries(tid) <= 0) {
60510037SARM gem5 Developers                DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free LQ\n");
60610037SARM gem5 Developers                source = LQ;
6077430Sgblack@eecs.umich.edu                incrFullStat(source);
6087430Sgblack@eecs.umich.edu                break;
60910037SARM gem5 Developers            }
6107430Sgblack@eecs.umich.edu        }
6117639Sgblack@eecs.umich.edu
61210037SARM gem5 Developers        if (inst->isStore()) {
6137430Sgblack@eecs.umich.edu            if (calcFreeSQEntries(tid) <= 0) {
6147430Sgblack@eecs.umich.edu                DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free SQ\n");
6157430Sgblack@eecs.umich.edu                source = SQ;
6167430Sgblack@eecs.umich.edu                incrFullStat(source);
61710037SARM gem5 Developers                break;
61810037SARM gem5 Developers            }
6197430Sgblack@eecs.umich.edu        }
6207430Sgblack@eecs.umich.edu
62110037SARM gem5 Developers        insts_to_rename.pop_front();
62210037SARM gem5 Developers
62310037SARM gem5 Developers        if (renameStatus[tid] == Unblocking) {
62410037SARM gem5 Developers            DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%s from rename "
62510037SARM gem5 Developers                    "skidBuffer\n", tid, inst->seqNum, inst->pcState());
62610037SARM gem5 Developers        }
62710037SARM gem5 Developers
62810037SARM gem5 Developers        if (inst->isSquashed()) {
62910037SARM gem5 Developers            DPRINTF(Rename, "[tid:%u]: instruction %i with PC %s is "
63010037SARM gem5 Developers                    "squashed, skipping.\n", tid, inst->seqNum,
63110037SARM gem5 Developers                    inst->pcState());
63210037SARM gem5 Developers
63310037SARM gem5 Developers            ++renameSquashedInsts;
63410037SARM gem5 Developers
63510037SARM gem5 Developers            // Decrement how many instructions are available.
6367430Sgblack@eecs.umich.edu            --insts_available;
6377430Sgblack@eecs.umich.edu
6387430Sgblack@eecs.umich.edu            continue;
63910037SARM gem5 Developers        }
64010037SARM gem5 Developers
6417430Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with "
64210037SARM gem5 Developers                "PC %s.\n", tid, inst->seqNum, inst->pcState());
64310037SARM gem5 Developers
6447430Sgblack@eecs.umich.edu        // Check here to make sure there are enough destination registers
64510037SARM gem5 Developers        // to rename to.  Otherwise block.
64610037SARM gem5 Developers        if (!renameMap[tid]->canRename(inst->numIntDestRegs(),
6477430Sgblack@eecs.umich.edu                                       inst->numFPDestRegs(),
6487430Sgblack@eecs.umich.edu                                       inst->numCCDestRegs())) {
6497430Sgblack@eecs.umich.edu            DPRINTF(Rename, "Blocking due to lack of free "
6507639Sgblack@eecs.umich.edu                    "physical registers to rename to.\n");
65110037SARM gem5 Developers            blockThisCycle = true;
6527430Sgblack@eecs.umich.edu            insts_to_rename.push_front(inst);
6537430Sgblack@eecs.umich.edu            ++renameFullRegistersEvents;
65410037SARM gem5 Developers
6557430Sgblack@eecs.umich.edu            break;
65610037SARM gem5 Developers        }
65710037SARM gem5 Developers
65810037SARM gem5 Developers        // Handle serializeAfter/serializeBefore instructions.
65910037SARM gem5 Developers        // serializeAfter marks the next instruction as serializeBefore.
6607430Sgblack@eecs.umich.edu        // serializeBefore makes the instruction wait in rename until the ROB
6617430Sgblack@eecs.umich.edu        // is empty.
6627430Sgblack@eecs.umich.edu
6637430Sgblack@eecs.umich.edu        // In this model, IPR accesses are serialize before
6647639Sgblack@eecs.umich.edu        // instructions, and store conditionals are serialize after
6657430Sgblack@eecs.umich.edu        // instructions.  This is mainly due to lack of support for
6667430Sgblack@eecs.umich.edu        // out-of-order operations of either of those classes of
6677430Sgblack@eecs.umich.edu        // instructions.
6687639Sgblack@eecs.umich.edu        if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
66910037SARM gem5 Developers            !inst->isSerializeHandled()) {
6707430Sgblack@eecs.umich.edu            DPRINTF(Rename, "Serialize before instruction encountered.\n");
6717430Sgblack@eecs.umich.edu
67210037SARM gem5 Developers            if (!inst->isTempSerializeBefore()) {
6737430Sgblack@eecs.umich.edu                renamedSerializing++;
67410037SARM gem5 Developers                inst->setSerializeHandled();
67510037SARM gem5 Developers            } else {
67610037SARM gem5 Developers                renamedTempSerializing++;
67710037SARM gem5 Developers            }
67810037SARM gem5 Developers
6797430Sgblack@eecs.umich.edu            // Change status over to SerializeStall so that other stages know
6807430Sgblack@eecs.umich.edu            // what this is blocked on.
6817430Sgblack@eecs.umich.edu            renameStatus[tid] = SerializeStall;
6827430Sgblack@eecs.umich.edu
6837639Sgblack@eecs.umich.edu            serializeInst[tid] = inst;
6847430Sgblack@eecs.umich.edu
6857430Sgblack@eecs.umich.edu            blockThisCycle = true;
6867430Sgblack@eecs.umich.edu
6877430Sgblack@eecs.umich.edu            break;
6887639Sgblack@eecs.umich.edu        } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
68910037SARM gem5 Developers                   !inst->isSerializeHandled()) {
6907430Sgblack@eecs.umich.edu            DPRINTF(Rename, "Serialize after instruction encountered.\n");
6917430Sgblack@eecs.umich.edu
69210037SARM gem5 Developers            renamedSerializing++;
6937430Sgblack@eecs.umich.edu
69410037SARM gem5 Developers            inst->setSerializeHandled();
69510037SARM gem5 Developers
69610037SARM gem5 Developers            serializeAfter(insts_to_rename, tid);
69710037SARM gem5 Developers        }
69810037SARM gem5 Developers
6997430Sgblack@eecs.umich.edu        renameSrcRegs(inst, inst->threadNumber);
7007430Sgblack@eecs.umich.edu
7017430Sgblack@eecs.umich.edu        renameDestRegs(inst, inst->threadNumber);
7027430Sgblack@eecs.umich.edu
7037639Sgblack@eecs.umich.edu        if (inst->isLoad()) {
7047430Sgblack@eecs.umich.edu                loadsInProgress[tid]++;
7057430Sgblack@eecs.umich.edu        }
7067430Sgblack@eecs.umich.edu        if (inst->isStore()) {
7077639Sgblack@eecs.umich.edu                storesInProgress[tid]++;
70810037SARM gem5 Developers        }
7097430Sgblack@eecs.umich.edu        ++renamed_insts;
7107430Sgblack@eecs.umich.edu        // Notify potential listeners that source and destination registers for
71110037SARM gem5 Developers        // this instruction have been renamed.
7127430Sgblack@eecs.umich.edu        ppRename->notify(inst);
71310037SARM gem5 Developers
71410037SARM gem5 Developers        // Put instruction in rename queue.
71510037SARM gem5 Developers        toIEW->insts[toIEWIndex] = inst;
71610037SARM gem5 Developers        ++(toIEW->size);
71710037SARM gem5 Developers
7187430Sgblack@eecs.umich.edu        // Increment which instruction we're on.
7197430Sgblack@eecs.umich.edu        ++toIEWIndex;
7207430Sgblack@eecs.umich.edu
7217430Sgblack@eecs.umich.edu        // Decrement how many instructions are available.
7227639Sgblack@eecs.umich.edu        --insts_available;
7237430Sgblack@eecs.umich.edu    }
7247430Sgblack@eecs.umich.edu
7257639Sgblack@eecs.umich.edu    instsInProgress[tid] += renamed_insts;
7267639Sgblack@eecs.umich.edu    renameRenamedInsts += renamed_insts;
7277639Sgblack@eecs.umich.edu
7287639Sgblack@eecs.umich.edu    // If we wrote to the time buffer, record this.
7297639Sgblack@eecs.umich.edu    if (toIEWIndex) {
7307639Sgblack@eecs.umich.edu        wroteToTimeBuffer = true;
7317639Sgblack@eecs.umich.edu    }
7327639Sgblack@eecs.umich.edu
7337639Sgblack@eecs.umich.edu    // Check if there's any instructions left that haven't yet been renamed.
7347639Sgblack@eecs.umich.edu    // If so then block.
7357639Sgblack@eecs.umich.edu    if (insts_available) {
7367639Sgblack@eecs.umich.edu        blockThisCycle = true;
7377639Sgblack@eecs.umich.edu    }
7387639Sgblack@eecs.umich.edu
7397639Sgblack@eecs.umich.edu    if (blockThisCycle) {
7407639Sgblack@eecs.umich.edu        block(tid);
7417639Sgblack@eecs.umich.edu        toDecode->renameUnblock[tid] = false;
7427639Sgblack@eecs.umich.edu    }
7437639Sgblack@eecs.umich.edu}
7447639Sgblack@eecs.umich.edu
7457639Sgblack@eecs.umich.edutemplate<class Impl>
7467639Sgblack@eecs.umich.eduvoid
7477639Sgblack@eecs.umich.eduDefaultRename<Impl>::skidInsert(ThreadID tid)
7487639Sgblack@eecs.umich.edu{
7497639Sgblack@eecs.umich.edu    DynInstPtr inst = NULL;
7507639Sgblack@eecs.umich.edu
7517639Sgblack@eecs.umich.edu    while (!insts[tid].empty()) {
7527639Sgblack@eecs.umich.edu        inst = insts[tid].front();
7537639Sgblack@eecs.umich.edu
7547639Sgblack@eecs.umich.edu        insts[tid].pop_front();
7557639Sgblack@eecs.umich.edu
7567639Sgblack@eecs.umich.edu        assert(tid == inst->threadNumber);
7577639Sgblack@eecs.umich.edu
7587639Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC: %s into Rename "
7597639Sgblack@eecs.umich.edu                "skidBuffer\n", tid, inst->seqNum, inst->pcState());
7607639Sgblack@eecs.umich.edu
7617639Sgblack@eecs.umich.edu        ++renameSkidInsts;
7627639Sgblack@eecs.umich.edu
7637639Sgblack@eecs.umich.edu        skidBuffer[tid].push_back(inst);
7647639Sgblack@eecs.umich.edu    }
7657639Sgblack@eecs.umich.edu
7667639Sgblack@eecs.umich.edu    if (skidBuffer[tid].size() > skidBufferMax)
7677639Sgblack@eecs.umich.edu    {
7687639Sgblack@eecs.umich.edu        typename InstQueue::iterator it;
7697639Sgblack@eecs.umich.edu        warn("Skidbuffer contents:\n");
7707639Sgblack@eecs.umich.edu        for (it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++)
7717639Sgblack@eecs.umich.edu        {
7727639Sgblack@eecs.umich.edu            warn("[tid:%u]: %s [sn:%i].\n", tid,
7737639Sgblack@eecs.umich.edu                    (*it)->staticInst->disassemble(inst->instAddr()),
7747639Sgblack@eecs.umich.edu                    (*it)->seqNum);
7757639Sgblack@eecs.umich.edu        }
7767639Sgblack@eecs.umich.edu        panic("Skidbuffer Exceeded Max Size");
7777639Sgblack@eecs.umich.edu    }
7787639Sgblack@eecs.umich.edu}
7797639Sgblack@eecs.umich.edu
7807639Sgblack@eecs.umich.edutemplate <class Impl>
7817639Sgblack@eecs.umich.eduvoid
7827639Sgblack@eecs.umich.eduDefaultRename<Impl>::sortInsts()
7837639Sgblack@eecs.umich.edu{
7847639Sgblack@eecs.umich.edu    int insts_from_decode = fromDecode->size;
7857639Sgblack@eecs.umich.edu    for (int i = 0; i < insts_from_decode; ++i) {
7867639Sgblack@eecs.umich.edu        DynInstPtr inst = fromDecode->insts[i];
7877639Sgblack@eecs.umich.edu        insts[inst->threadNumber].push_back(inst);
7887639Sgblack@eecs.umich.edu#if TRACING_ON
7897639Sgblack@eecs.umich.edu        if (DTRACE(O3PipeView)) {
7907639Sgblack@eecs.umich.edu            inst->renameTick = curTick() - inst->fetchTick;
7917639Sgblack@eecs.umich.edu        }
7927639Sgblack@eecs.umich.edu#endif
7937639Sgblack@eecs.umich.edu    }
7947639Sgblack@eecs.umich.edu}
7957639Sgblack@eecs.umich.edu
7967639Sgblack@eecs.umich.edutemplate<class Impl>
7977639Sgblack@eecs.umich.edubool
7987639Sgblack@eecs.umich.eduDefaultRename<Impl>::skidsEmpty()
7997639Sgblack@eecs.umich.edu{
8007639Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
8017639Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
8027639Sgblack@eecs.umich.edu
8037639Sgblack@eecs.umich.edu    while (threads != end) {
8047639Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
8057639Sgblack@eecs.umich.edu
8067639Sgblack@eecs.umich.edu        if (!skidBuffer[tid].empty())
8077639Sgblack@eecs.umich.edu            return false;
8087639Sgblack@eecs.umich.edu    }
8097639Sgblack@eecs.umich.edu
8107639Sgblack@eecs.umich.edu    return true;
8117639Sgblack@eecs.umich.edu}
8127639Sgblack@eecs.umich.edu
8137639Sgblack@eecs.umich.edutemplate<class Impl>
8147639Sgblack@eecs.umich.eduvoid
8157639Sgblack@eecs.umich.eduDefaultRename<Impl>::updateStatus()
8167639Sgblack@eecs.umich.edu{
8177639Sgblack@eecs.umich.edu    bool any_unblocking = false;
8187639Sgblack@eecs.umich.edu
8197639Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
8207639Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
8217639Sgblack@eecs.umich.edu
8227639Sgblack@eecs.umich.edu    while (threads != end) {
8237639Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
8247639Sgblack@eecs.umich.edu
8257639Sgblack@eecs.umich.edu        if (renameStatus[tid] == Unblocking) {
8267639Sgblack@eecs.umich.edu            any_unblocking = true;
8277639Sgblack@eecs.umich.edu            break;
8287639Sgblack@eecs.umich.edu        }
8297639Sgblack@eecs.umich.edu    }
8307639Sgblack@eecs.umich.edu
8317639Sgblack@eecs.umich.edu    // Rename will have activity if it's unblocking.
8327639Sgblack@eecs.umich.edu    if (any_unblocking) {
8337639Sgblack@eecs.umich.edu        if (_status == Inactive) {
8347639Sgblack@eecs.umich.edu            _status = Active;
8357639Sgblack@eecs.umich.edu
8367639Sgblack@eecs.umich.edu            DPRINTF(Activity, "Activating stage.\n");
8377639Sgblack@eecs.umich.edu
8387639Sgblack@eecs.umich.edu            cpu->activateStage(O3CPU::RenameIdx);
8397639Sgblack@eecs.umich.edu        }
8407639Sgblack@eecs.umich.edu    } else {
8417639Sgblack@eecs.umich.edu        // If it's not unblocking, then rename will not have any internal
8427639Sgblack@eecs.umich.edu        // activity.  Switch it to inactive.
8437639Sgblack@eecs.umich.edu        if (_status == Active) {
8447639Sgblack@eecs.umich.edu            _status = Inactive;
8457639Sgblack@eecs.umich.edu            DPRINTF(Activity, "Deactivating stage.\n");
8467639Sgblack@eecs.umich.edu
8477639Sgblack@eecs.umich.edu            cpu->deactivateStage(O3CPU::RenameIdx);
8487639Sgblack@eecs.umich.edu        }
8497639Sgblack@eecs.umich.edu    }
8507639Sgblack@eecs.umich.edu}
8517639Sgblack@eecs.umich.edu
8527639Sgblack@eecs.umich.edutemplate <class Impl>
8537639Sgblack@eecs.umich.edubool
8547639Sgblack@eecs.umich.eduDefaultRename<Impl>::block(ThreadID tid)
8557639Sgblack@eecs.umich.edu{
8567639Sgblack@eecs.umich.edu    DPRINTF(Rename, "[tid:%u]: Blocking.\n", tid);
8577639Sgblack@eecs.umich.edu
8587639Sgblack@eecs.umich.edu    // Add the current inputs onto the skid buffer, so they can be
8597639Sgblack@eecs.umich.edu    // reprocessed when this stage unblocks.
8607639Sgblack@eecs.umich.edu    skidInsert(tid);
8617639Sgblack@eecs.umich.edu
8627639Sgblack@eecs.umich.edu    // Only signal backwards to block if the previous stages do not think
8637639Sgblack@eecs.umich.edu    // rename is already blocked.
8647639Sgblack@eecs.umich.edu    if (renameStatus[tid] != Blocked) {
8657639Sgblack@eecs.umich.edu        // If resumeUnblocking is set, we unblocked during the squash,
8667639Sgblack@eecs.umich.edu        // but now we're have unblocking status. We need to tell earlier
8677639Sgblack@eecs.umich.edu        // stages to block.
8687639Sgblack@eecs.umich.edu        if (resumeUnblocking || renameStatus[tid] != Unblocking) {
8697639Sgblack@eecs.umich.edu            toDecode->renameBlock[tid] = true;
8707639Sgblack@eecs.umich.edu            toDecode->renameUnblock[tid] = false;
8717639Sgblack@eecs.umich.edu            wroteToTimeBuffer = true;
8727639Sgblack@eecs.umich.edu        }
8737639Sgblack@eecs.umich.edu
8747639Sgblack@eecs.umich.edu        // Rename can not go from SerializeStall to Blocked, otherwise
8757639Sgblack@eecs.umich.edu        // it would not know to complete the serialize stall.
8767639Sgblack@eecs.umich.edu        if (renameStatus[tid] != SerializeStall) {
8777639Sgblack@eecs.umich.edu            // Set status to Blocked.
8787639Sgblack@eecs.umich.edu            renameStatus[tid] = Blocked;
8797639Sgblack@eecs.umich.edu            return true;
8807639Sgblack@eecs.umich.edu        }
8817639Sgblack@eecs.umich.edu    }
8827639Sgblack@eecs.umich.edu
8837639Sgblack@eecs.umich.edu    return false;
8847639Sgblack@eecs.umich.edu}
8857639Sgblack@eecs.umich.edu
8867639Sgblack@eecs.umich.edutemplate <class Impl>
8877639Sgblack@eecs.umich.edubool
8887639Sgblack@eecs.umich.eduDefaultRename<Impl>::unblock(ThreadID tid)
8897639Sgblack@eecs.umich.edu{
8907639Sgblack@eecs.umich.edu    DPRINTF(Rename, "[tid:%u]: Trying to unblock.\n", tid);
8917639Sgblack@eecs.umich.edu
8927639Sgblack@eecs.umich.edu    // Rename is done unblocking if the skid buffer is empty.
8937639Sgblack@eecs.umich.edu    if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) {
8947639Sgblack@eecs.umich.edu
8957639Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Done unblocking.\n", tid);
8967639Sgblack@eecs.umich.edu
8977639Sgblack@eecs.umich.edu        toDecode->renameUnblock[tid] = true;
8987639Sgblack@eecs.umich.edu        wroteToTimeBuffer = true;
8997639Sgblack@eecs.umich.edu
9007639Sgblack@eecs.umich.edu        renameStatus[tid] = Running;
9017639Sgblack@eecs.umich.edu        return true;
9027639Sgblack@eecs.umich.edu    }
9037639Sgblack@eecs.umich.edu
9047639Sgblack@eecs.umich.edu    return false;
9057639Sgblack@eecs.umich.edu}
9067639Sgblack@eecs.umich.edu
9077639Sgblack@eecs.umich.edutemplate <class Impl>
9087639Sgblack@eecs.umich.eduvoid
9097639Sgblack@eecs.umich.eduDefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
9107639Sgblack@eecs.umich.edu{
9117639Sgblack@eecs.umich.edu    typename std::list<RenameHistory>::iterator hb_it =
9127639Sgblack@eecs.umich.edu        historyBuffer[tid].begin();
9137639Sgblack@eecs.umich.edu
9147639Sgblack@eecs.umich.edu    // After a syscall squashes everything, the history buffer may be empty
9157639Sgblack@eecs.umich.edu    // but the ROB may still be squashing instructions.
9167639Sgblack@eecs.umich.edu    if (historyBuffer[tid].empty()) {
9177639Sgblack@eecs.umich.edu        return;
9187639Sgblack@eecs.umich.edu    }
9197639Sgblack@eecs.umich.edu
9207639Sgblack@eecs.umich.edu    // Go through the most recent instructions, undoing the mappings
9217639Sgblack@eecs.umich.edu    // they did and freeing up the registers.
92210037SARM gem5 Developers    while (!historyBuffer[tid].empty() &&
92310037SARM gem5 Developers           hb_it->instSeqNum > squashed_seq_num) {
92410037SARM gem5 Developers        assert(hb_it != historyBuffer[tid].end());
92510037SARM gem5 Developers
92610037SARM gem5 Developers        DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
92710037SARM gem5 Developers                "number %i.\n", tid, hb_it->instSeqNum);
92810037SARM gem5 Developers
92910037SARM gem5 Developers        // Undo the rename mapping only if it was really a change.
93010037SARM gem5 Developers        // Special regs that are not really renamed (like misc regs
93110037SARM gem5 Developers        // and the zero reg) can be recognized because the new mapping
93210037SARM gem5 Developers        // is the same as the old one.  While it would be merely a
93310037SARM gem5 Developers        // waste of time to update the rename table, we definitely
93410037SARM gem5 Developers        // don't want to put these on the free list.
93510037SARM gem5 Developers        if (hb_it->newPhysReg != hb_it->prevPhysReg) {
93610037SARM gem5 Developers            // Tell the rename map to set the architected register to the
93710037SARM gem5 Developers            // previous physical register that it was renamed to.
93810037SARM gem5 Developers            renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
93910037SARM gem5 Developers
94010037SARM gem5 Developers            // Put the renamed physical register back on the free list.
94110037SARM gem5 Developers            freeList->addReg(hb_it->newPhysReg);
94210037SARM gem5 Developers        }
94310037SARM gem5 Developers
94410037SARM gem5 Developers        // Notify potential listeners that the register mapping needs to be
94510037SARM gem5 Developers        // removed because the instruction it was mapped to got squashed. Note
94610037SARM gem5 Developers        // that this is done before hb_it is incremented.
94710037SARM gem5 Developers        ppSquashInRename->notify(std::make_pair(hb_it->instSeqNum,
94810037SARM gem5 Developers                                                hb_it->newPhysReg));
94910037SARM gem5 Developers
95010037SARM gem5 Developers        historyBuffer[tid].erase(hb_it++);
95110037SARM gem5 Developers
95210037SARM gem5 Developers        ++renameUndoneMaps;
95310037SARM gem5 Developers    }
95410037SARM gem5 Developers}
95510037SARM gem5 Developers
95610037SARM gem5 Developerstemplate<class Impl>
95710037SARM gem5 Developersvoid
95810037SARM gem5 DevelopersDefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
95910037SARM gem5 Developers{
96010037SARM gem5 Developers    DPRINTF(Rename, "[tid:%u]: Removing a committed instruction from the "
96110037SARM gem5 Developers            "history buffer %u (size=%i), until [sn:%lli].\n",
96210037SARM gem5 Developers            tid, tid, historyBuffer[tid].size(), inst_seq_num);
96310037SARM gem5 Developers
96410037SARM gem5 Developers    typename std::list<RenameHistory>::iterator hb_it =
96510037SARM gem5 Developers        historyBuffer[tid].end();
96610037SARM gem5 Developers
96710037SARM gem5 Developers    --hb_it;
96810037SARM gem5 Developers
96910037SARM gem5 Developers    if (historyBuffer[tid].empty()) {
97010037SARM gem5 Developers        DPRINTF(Rename, "[tid:%u]: History buffer is empty.\n", tid);
97110037SARM gem5 Developers        return;
97210037SARM gem5 Developers    } else if (hb_it->instSeqNum > inst_seq_num) {
97310037SARM gem5 Developers        DPRINTF(Rename, "[tid:%u]: Old sequence number encountered.  Ensure "
97410037SARM gem5 Developers                "that a syscall happened recently.\n", tid);
97510037SARM gem5 Developers        return;
97610037SARM gem5 Developers    }
97710037SARM gem5 Developers
97810037SARM gem5 Developers    // Commit all the renames up until (and including) the committed sequence
97910037SARM gem5 Developers    // number. Some or even all of the committed instructions may not have
98010037SARM gem5 Developers    // rename histories if they did not have destination registers that were
98110037SARM gem5 Developers    // renamed.
98210037SARM gem5 Developers    while (!historyBuffer[tid].empty() &&
98310037SARM gem5 Developers           hb_it != historyBuffer[tid].end() &&
98410037SARM gem5 Developers           hb_it->instSeqNum <= inst_seq_num) {
98510037SARM gem5 Developers
98610037SARM gem5 Developers        DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, "
98710037SARM gem5 Developers                "[sn:%lli].\n",
98810037SARM gem5 Developers                tid, hb_it->prevPhysReg, hb_it->instSeqNum);
98910037SARM gem5 Developers
99010037SARM gem5 Developers        // Don't free special phys regs like misc and zero regs, which
99110037SARM gem5 Developers        // can be recognized because the new mapping is the same as
99210037SARM gem5 Developers        // the old one.
99310037SARM gem5 Developers        if (hb_it->newPhysReg != hb_it->prevPhysReg) {
99410037SARM gem5 Developers            freeList->addReg(hb_it->prevPhysReg);
99510037SARM gem5 Developers        }
99610037SARM gem5 Developers
99710037SARM gem5 Developers        ++renameCommittedMaps;
99810037SARM gem5 Developers
99910037SARM gem5 Developers        historyBuffer[tid].erase(hb_it--);
100010037SARM gem5 Developers    }
10017430Sgblack@eecs.umich.edu}
10027430Sgblack@eecs.umich.edu
10037430Sgblack@eecs.umich.edutemplate <class Impl>
10047430Sgblack@eecs.umich.eduinline void
10057639Sgblack@eecs.umich.eduDefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
10067430Sgblack@eecs.umich.edu{
10077430Sgblack@eecs.umich.edu    ThreadContext *tc = inst->tcBase();
10087430Sgblack@eecs.umich.edu    RenameMap *map = renameMap[tid];
10097430Sgblack@eecs.umich.edu    unsigned num_src_regs = inst->numSrcRegs();
10107430Sgblack@eecs.umich.edu
10117430Sgblack@eecs.umich.edu    // Get the architectual register numbers from the source and
10127430Sgblack@eecs.umich.edu    // operands, and redirect them to the right physical register.
10137430Sgblack@eecs.umich.edu    for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
10147430Sgblack@eecs.umich.edu        RegIndex src_reg = inst->srcRegIdx(src_idx);
10157430Sgblack@eecs.umich.edu        RegIndex rel_src_reg;
10167430Sgblack@eecs.umich.edu        RegIndex flat_rel_src_reg;
10177430Sgblack@eecs.umich.edu        PhysRegIndex renamed_reg;
10187430Sgblack@eecs.umich.edu
10199515SAli.Saidi@ARM.com        switch (regIdxToClass(src_reg, &rel_src_reg)) {
10207430Sgblack@eecs.umich.edu          case IntRegClass:
10217430Sgblack@eecs.umich.edu            flat_rel_src_reg = tc->flattenIntIndex(rel_src_reg);
10227430Sgblack@eecs.umich.edu            renamed_reg = map->lookupInt(flat_rel_src_reg);
10237430Sgblack@eecs.umich.edu            intRenameLookups++;
10247430Sgblack@eecs.umich.edu            break;
10257430Sgblack@eecs.umich.edu
10267639Sgblack@eecs.umich.edu          case FloatRegClass:
10277430Sgblack@eecs.umich.edu            flat_rel_src_reg = tc->flattenFloatIndex(rel_src_reg);
10287430Sgblack@eecs.umich.edu            renamed_reg = map->lookupFloat(flat_rel_src_reg);
10297430Sgblack@eecs.umich.edu            fpRenameLookups++;
10307430Sgblack@eecs.umich.edu            break;
10317430Sgblack@eecs.umich.edu
10327430Sgblack@eecs.umich.edu          case CCRegClass:
10337430Sgblack@eecs.umich.edu            flat_rel_src_reg = tc->flattenCCIndex(rel_src_reg);
10347430Sgblack@eecs.umich.edu            renamed_reg = map->lookupCC(flat_rel_src_reg);
10357430Sgblack@eecs.umich.edu            break;
10367430Sgblack@eecs.umich.edu
10377430Sgblack@eecs.umich.edu          case MiscRegClass:
10387430Sgblack@eecs.umich.edu            // misc regs don't get flattened
10397430Sgblack@eecs.umich.edu            flat_rel_src_reg = rel_src_reg;
10407430Sgblack@eecs.umich.edu            renamed_reg = map->lookupMisc(flat_rel_src_reg);
10417430Sgblack@eecs.umich.edu            break;
10427430Sgblack@eecs.umich.edu
10437430Sgblack@eecs.umich.edu          default:
10447430Sgblack@eecs.umich.edu            panic("Reg index is out of bound: %d.", src_reg);
10457430Sgblack@eecs.umich.edu        }
10467430Sgblack@eecs.umich.edu
10477430Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i (flattened %i), "
10487430Sgblack@eecs.umich.edu                "got phys reg %i\n", tid, RegClassStrings[regIdxToClass(src_reg)],
10497430Sgblack@eecs.umich.edu                (int)src_reg, (int)flat_rel_src_reg, (int)renamed_reg);
10507430Sgblack@eecs.umich.edu
10517430Sgblack@eecs.umich.edu        inst->renameSrcReg(src_idx, renamed_reg);
10527430Sgblack@eecs.umich.edu
10537430Sgblack@eecs.umich.edu        // See if the register is ready or not.
10547430Sgblack@eecs.umich.edu        if (scoreboard->getReg(renamed_reg)) {
10557430Sgblack@eecs.umich.edu            DPRINTF(Rename, "[tid:%u]: Register %d is ready.\n",
10567430Sgblack@eecs.umich.edu                    tid, renamed_reg);
10577430Sgblack@eecs.umich.edu
10587430Sgblack@eecs.umich.edu            inst->markSrcRegReady(src_idx);
10597639Sgblack@eecs.umich.edu        } else {
10607430Sgblack@eecs.umich.edu            DPRINTF(Rename, "[tid:%u]: Register %d is not ready.\n",
10617430Sgblack@eecs.umich.edu                    tid, renamed_reg);
10627430Sgblack@eecs.umich.edu        }
10637430Sgblack@eecs.umich.edu
10647430Sgblack@eecs.umich.edu        ++renameRenameLookups;
10657430Sgblack@eecs.umich.edu    }
10667639Sgblack@eecs.umich.edu}
10677430Sgblack@eecs.umich.edu
10687430Sgblack@eecs.umich.edutemplate <class Impl>
10697430Sgblack@eecs.umich.eduinline void
10707639Sgblack@eecs.umich.eduDefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
10717430Sgblack@eecs.umich.edu{
10727430Sgblack@eecs.umich.edu    ThreadContext *tc = inst->tcBase();
10737430Sgblack@eecs.umich.edu    RenameMap *map = renameMap[tid];
10747430Sgblack@eecs.umich.edu    unsigned num_dest_regs = inst->numDestRegs();
10757430Sgblack@eecs.umich.edu
10767430Sgblack@eecs.umich.edu    // Rename the destination registers.
10777430Sgblack@eecs.umich.edu    for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
10787430Sgblack@eecs.umich.edu        RegIndex dest_reg = inst->destRegIdx(dest_idx);
10797430Sgblack@eecs.umich.edu        RegIndex rel_dest_reg;
10807430Sgblack@eecs.umich.edu        RegIndex flat_rel_dest_reg;
10817430Sgblack@eecs.umich.edu        RegIndex flat_uni_dest_reg;
10827430Sgblack@eecs.umich.edu        typename RenameMap::RenameInfo rename_result;
10837430Sgblack@eecs.umich.edu
10847430Sgblack@eecs.umich.edu        switch (regIdxToClass(dest_reg, &rel_dest_reg)) {
10857430Sgblack@eecs.umich.edu          case IntRegClass:
10867430Sgblack@eecs.umich.edu            flat_rel_dest_reg = tc->flattenIntIndex(rel_dest_reg);
10877430Sgblack@eecs.umich.edu            rename_result = map->renameInt(flat_rel_dest_reg);
10887430Sgblack@eecs.umich.edu            flat_uni_dest_reg = flat_rel_dest_reg;  // 1:1 mapping
10899515SAli.Saidi@ARM.com            break;
10907430Sgblack@eecs.umich.edu
10917430Sgblack@eecs.umich.edu          case FloatRegClass:
10927430Sgblack@eecs.umich.edu            flat_rel_dest_reg = tc->flattenFloatIndex(rel_dest_reg);
10937430Sgblack@eecs.umich.edu            rename_result = map->renameFloat(flat_rel_dest_reg);
10947430Sgblack@eecs.umich.edu            flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base;
10957430Sgblack@eecs.umich.edu            break;
10967430Sgblack@eecs.umich.edu
10977430Sgblack@eecs.umich.edu          case CCRegClass:
10987430Sgblack@eecs.umich.edu            flat_rel_dest_reg = tc->flattenCCIndex(rel_dest_reg);
10997430Sgblack@eecs.umich.edu            rename_result = map->renameCC(flat_rel_dest_reg);
11007430Sgblack@eecs.umich.edu            flat_uni_dest_reg = flat_rel_dest_reg + TheISA::CC_Reg_Base;
11017430Sgblack@eecs.umich.edu            break;
11027430Sgblack@eecs.umich.edu
11037430Sgblack@eecs.umich.edu          case MiscRegClass:
11047430Sgblack@eecs.umich.edu            // misc regs don't get flattened
11057430Sgblack@eecs.umich.edu            flat_rel_dest_reg = rel_dest_reg;
11067430Sgblack@eecs.umich.edu            rename_result = map->renameMisc(flat_rel_dest_reg);
11077430Sgblack@eecs.umich.edu            flat_uni_dest_reg = flat_rel_dest_reg + TheISA::Misc_Reg_Base;
11087430Sgblack@eecs.umich.edu            break;
11097430Sgblack@eecs.umich.edu
11107430Sgblack@eecs.umich.edu          default:
11117430Sgblack@eecs.umich.edu            panic("Reg index is out of bound: %d.", dest_reg);
11127430Sgblack@eecs.umich.edu        }
11137430Sgblack@eecs.umich.edu
11147430Sgblack@eecs.umich.edu        inst->flattenDestReg(dest_idx, flat_uni_dest_reg);
11157430Sgblack@eecs.umich.edu
11167430Sgblack@eecs.umich.edu        // Mark Scoreboard entry as not ready
11177430Sgblack@eecs.umich.edu        scoreboard->unsetReg(rename_result.first);
11187430Sgblack@eecs.umich.edu
11197639Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
11207430Sgblack@eecs.umich.edu                "reg %i.\n", tid, (int)flat_rel_dest_reg,
11217430Sgblack@eecs.umich.edu                (int)rename_result.first);
11227430Sgblack@eecs.umich.edu
11237430Sgblack@eecs.umich.edu        // Record the rename information so that a history can be kept.
11247430Sgblack@eecs.umich.edu        RenameHistory hb_entry(inst->seqNum, flat_uni_dest_reg,
11257430Sgblack@eecs.umich.edu                               rename_result.first,
11267430Sgblack@eecs.umich.edu                               rename_result.second);
11277430Sgblack@eecs.umich.edu
11287430Sgblack@eecs.umich.edu        historyBuffer[tid].push_front(hb_entry);
11297430Sgblack@eecs.umich.edu
11307430Sgblack@eecs.umich.edu        DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer "
11317430Sgblack@eecs.umich.edu                "(size=%i), [sn:%lli].\n",tid,
11327430Sgblack@eecs.umich.edu                historyBuffer[tid].size(),
11337430Sgblack@eecs.umich.edu                (*historyBuffer[tid].begin()).instSeqNum);
11347430Sgblack@eecs.umich.edu
11357430Sgblack@eecs.umich.edu        // Tell the instruction to rename the appropriate destination
11367430Sgblack@eecs.umich.edu        // register (dest_idx) to the new physical register
11377430Sgblack@eecs.umich.edu        // (rename_result.first), and record the previous physical
11387430Sgblack@eecs.umich.edu        // register that the same logical register was renamed to
11397430Sgblack@eecs.umich.edu        // (rename_result.second).
11407430Sgblack@eecs.umich.edu        inst->renameDestReg(dest_idx,
11417430Sgblack@eecs.umich.edu                            rename_result.first,
11427430Sgblack@eecs.umich.edu                            rename_result.second);
11437430Sgblack@eecs.umich.edu
11447430Sgblack@eecs.umich.edu        ++renameRenamedOperands;
11457430Sgblack@eecs.umich.edu    }
11467430Sgblack@eecs.umich.edu}
11477430Sgblack@eecs.umich.edu
11487430Sgblack@eecs.umich.edutemplate <class Impl>
11497430Sgblack@eecs.umich.eduinline int
11507430Sgblack@eecs.umich.eduDefaultRename<Impl>::calcFreeROBEntries(ThreadID tid)
11517430Sgblack@eecs.umich.edu{
11527430Sgblack@eecs.umich.edu    int num_free = freeEntries[tid].robEntries -
11537430Sgblack@eecs.umich.edu                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
11547430Sgblack@eecs.umich.edu
11557430Sgblack@eecs.umich.edu    //DPRINTF(Rename,"[tid:%i]: %i rob free\n",tid,num_free);
11567430Sgblack@eecs.umich.edu
11577430Sgblack@eecs.umich.edu    return num_free;
11587430Sgblack@eecs.umich.edu}
11597430Sgblack@eecs.umich.edu
11607430Sgblack@eecs.umich.edutemplate <class Impl>
11617430Sgblack@eecs.umich.eduinline int
11627430Sgblack@eecs.umich.eduDefaultRename<Impl>::calcFreeIQEntries(ThreadID tid)
11637430Sgblack@eecs.umich.edu{
11647430Sgblack@eecs.umich.edu    int num_free = freeEntries[tid].iqEntries -
11657430Sgblack@eecs.umich.edu                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
11667430Sgblack@eecs.umich.edu
11677430Sgblack@eecs.umich.edu    //DPRINTF(Rename,"[tid:%i]: %i iq free\n",tid,num_free);
11687430Sgblack@eecs.umich.edu
11697430Sgblack@eecs.umich.edu    return num_free;
11707430Sgblack@eecs.umich.edu}
11717430Sgblack@eecs.umich.edu
11727430Sgblack@eecs.umich.edutemplate <class Impl>
11737430Sgblack@eecs.umich.eduinline int
11747430Sgblack@eecs.umich.eduDefaultRename<Impl>::calcFreeLQEntries(ThreadID tid)
1175{
1176        int num_free = freeEntries[tid].lqEntries -
1177                                  (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
1178        DPRINTF(Rename, "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, "
1179                "loads dispatchedToLQ: %d\n", freeEntries[tid].lqEntries,
1180                loadsInProgress[tid], fromIEW->iewInfo[tid].dispatchedToLQ);
1181        return num_free;
1182}
1183
1184template <class Impl>
1185inline int
1186DefaultRename<Impl>::calcFreeSQEntries(ThreadID tid)
1187{
1188        int num_free = freeEntries[tid].sqEntries -
1189                                  (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
1190        DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, storesInProgress: %d, "
1191                "stores dispatchedToSQ: %d\n", freeEntries[tid].sqEntries,
1192                storesInProgress[tid], fromIEW->iewInfo[tid].dispatchedToSQ);
1193        return num_free;
1194}
1195
1196template <class Impl>
1197unsigned
1198DefaultRename<Impl>::validInsts()
1199{
1200    unsigned inst_count = 0;
1201
1202    for (int i=0; i<fromDecode->size; i++) {
1203        if (!fromDecode->insts[i]->isSquashed())
1204            inst_count++;
1205    }
1206
1207    return inst_count;
1208}
1209
1210template <class Impl>
1211void
1212DefaultRename<Impl>::readStallSignals(ThreadID tid)
1213{
1214    if (fromIEW->iewBlock[tid]) {
1215        stalls[tid].iew = true;
1216    }
1217
1218    if (fromIEW->iewUnblock[tid]) {
1219        assert(stalls[tid].iew);
1220        stalls[tid].iew = false;
1221    }
1222}
1223
1224template <class Impl>
1225bool
1226DefaultRename<Impl>::checkStall(ThreadID tid)
1227{
1228    bool ret_val = false;
1229
1230    if (stalls[tid].iew) {
1231        DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid);
1232        ret_val = true;
1233    } else if (calcFreeROBEntries(tid) <= 0) {
1234        DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid);
1235        ret_val = true;
1236    } else if (calcFreeIQEntries(tid) <= 0) {
1237        DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid);
1238        ret_val = true;
1239    } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) {
1240        DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid);
1241        ret_val = true;
1242    } else if (renameMap[tid]->numFreeEntries() <= 0) {
1243        DPRINTF(Rename,"[tid:%i]: Stall: RenameMap has 0 free entries.\n", tid);
1244        ret_val = true;
1245    } else if (renameStatus[tid] == SerializeStall &&
1246               (!emptyROB[tid] || instsInProgress[tid])) {
1247        DPRINTF(Rename,"[tid:%i]: Stall: Serialize stall and ROB is not "
1248                "empty.\n",
1249                tid);
1250        ret_val = true;
1251    }
1252
1253    return ret_val;
1254}
1255
1256template <class Impl>
1257void
1258DefaultRename<Impl>::readFreeEntries(ThreadID tid)
1259{
1260    if (fromIEW->iewInfo[tid].usedIQ)
1261        freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries;
1262
1263    if (fromIEW->iewInfo[tid].usedLSQ) {
1264        freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries;
1265        freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries;
1266    }
1267
1268    if (fromCommit->commitInfo[tid].usedROB) {
1269        freeEntries[tid].robEntries =
1270            fromCommit->commitInfo[tid].freeROBEntries;
1271        emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
1272    }
1273
1274    DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, "
1275                    "Free LQ: %i, Free SQ: %i\n",
1276            tid,
1277            freeEntries[tid].iqEntries,
1278            freeEntries[tid].robEntries,
1279            freeEntries[tid].lqEntries,
1280            freeEntries[tid].sqEntries);
1281
1282    DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n",
1283            tid, instsInProgress[tid]);
1284}
1285
1286template <class Impl>
1287bool
1288DefaultRename<Impl>::checkSignalsAndUpdate(ThreadID tid)
1289{
1290    // Check if there's a squash signal, squash if there is
1291    // Check stall signals, block if necessary.
1292    // If status was blocked
1293    //     check if stall conditions have passed
1294    //         if so then go to unblocking
1295    // If status was Squashing
1296    //     check if squashing is not high.  Switch to running this cycle.
1297    // If status was serialize stall
1298    //     check if ROB is empty and no insts are in flight to the ROB
1299
1300    readFreeEntries(tid);
1301    readStallSignals(tid);
1302
1303    if (fromCommit->commitInfo[tid].squash) {
1304        DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from "
1305                "commit.\n", tid);
1306
1307        squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
1308
1309        return true;
1310    }
1311
1312    if (checkStall(tid)) {
1313        return block(tid);
1314    }
1315
1316    if (renameStatus[tid] == Blocked) {
1317        DPRINTF(Rename, "[tid:%u]: Done blocking, switching to unblocking.\n",
1318                tid);
1319
1320        renameStatus[tid] = Unblocking;
1321
1322        unblock(tid);
1323
1324        return true;
1325    }
1326
1327    if (renameStatus[tid] == Squashing) {
1328        // Switch status to running if rename isn't being told to block or
1329        // squash this cycle.
1330        if (resumeSerialize) {
1331            DPRINTF(Rename, "[tid:%u]: Done squashing, switching to serialize.\n",
1332                    tid);
1333
1334            renameStatus[tid] = SerializeStall;
1335            return true;
1336        } else if (resumeUnblocking) {
1337            DPRINTF(Rename, "[tid:%u]: Done squashing, switching to unblocking.\n",
1338                    tid);
1339            renameStatus[tid] = Unblocking;
1340            return true;
1341        } else {
1342            DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n",
1343                    tid);
1344
1345            renameStatus[tid] = Running;
1346            return false;
1347        }
1348    }
1349
1350    if (renameStatus[tid] == SerializeStall) {
1351        // Stall ends once the ROB is free.
1352        DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to "
1353                "unblocking.\n", tid);
1354
1355        DynInstPtr serial_inst = serializeInst[tid];
1356
1357        renameStatus[tid] = Unblocking;
1358
1359        unblock(tid);
1360
1361        DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with "
1362                "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState());
1363
1364        // Put instruction into queue here.
1365        serial_inst->clearSerializeBefore();
1366
1367        if (!skidBuffer[tid].empty()) {
1368            skidBuffer[tid].push_front(serial_inst);
1369        } else {
1370            insts[tid].push_front(serial_inst);
1371        }
1372
1373        DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename."
1374                " Adding to front of list.\n", tid);
1375
1376        serializeInst[tid] = NULL;
1377
1378        return true;
1379    }
1380
1381    // If we've reached this point, we have not gotten any signals that
1382    // cause rename to change its status.  Rename remains the same as before.
1383    return false;
1384}
1385
1386template<class Impl>
1387void
1388DefaultRename<Impl>::serializeAfter(InstQueue &inst_list, ThreadID tid)
1389{
1390    if (inst_list.empty()) {
1391        // Mark a bit to say that I must serialize on the next instruction.
1392        serializeOnNextInst[tid] = true;
1393        return;
1394    }
1395
1396    // Set the next instruction as serializing.
1397    inst_list.front()->setSerializeBefore();
1398}
1399
1400template <class Impl>
1401inline void
1402DefaultRename<Impl>::incrFullStat(const FullSource &source)
1403{
1404    switch (source) {
1405      case ROB:
1406        ++renameROBFullEvents;
1407        break;
1408      case IQ:
1409        ++renameIQFullEvents;
1410        break;
1411      case LQ:
1412        ++renameLQFullEvents;
1413        break;
1414      case SQ:
1415        ++renameSQFullEvents;
1416        break;
1417      default:
1418        panic("Rename full stall stat should be incremented for a reason!");
1419        break;
1420    }
1421}
1422
1423template <class Impl>
1424void
1425DefaultRename<Impl>::dumpHistory()
1426{
1427    typename std::list<RenameHistory>::iterator buf_it;
1428
1429    for (ThreadID tid = 0; tid < numThreads; tid++) {
1430
1431        buf_it = historyBuffer[tid].begin();
1432
1433        while (buf_it != historyBuffer[tid].end()) {
1434            cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
1435                    "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
1436                    (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
1437
1438            buf_it++;
1439        }
1440    }
1441}
1442
1443#endif//__CPU_O3_RENAME_IMPL_HH__
1444