rename_impl.hh revision 13831
13569Sgblack@eecs.umich.edu/*
23569Sgblack@eecs.umich.edu * Copyright (c) 2010-2012, 2014-2016 ARM Limited
33569Sgblack@eecs.umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc.
43569Sgblack@eecs.umich.edu * All rights reserved.
53569Sgblack@eecs.umich.edu *
63569Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
73569Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
83569Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
93569Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
103569Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
113569Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
123569Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
133569Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
143569Sgblack@eecs.umich.edu *
153569Sgblack@eecs.umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan
163569Sgblack@eecs.umich.edu * All rights reserved.
173569Sgblack@eecs.umich.edu *
183569Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
193569Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
203569Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
213569Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
223569Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
233569Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
243569Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
253569Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
263569Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
273569Sgblack@eecs.umich.edu * this software without specific prior written permission.
283804Ssaidi@eecs.umich.edu *
293569Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
303569Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
313804Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
323811Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
333569Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
343824Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
353811Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
363811Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
373823Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
383823Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
393823Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
403569Sgblack@eecs.umich.edu *
413569Sgblack@eecs.umich.edu * Authors: Kevin Lim
423804Ssaidi@eecs.umich.edu *          Korey Sewell
433804Ssaidi@eecs.umich.edu */
443569Sgblack@eecs.umich.edu
453569Sgblack@eecs.umich.edu#ifndef __CPU_O3_RENAME_IMPL_HH__
463569Sgblack@eecs.umich.edu#define __CPU_O3_RENAME_IMPL_HH__
473804Ssaidi@eecs.umich.edu
483881Ssaidi@eecs.umich.edu#include <list>
493881Ssaidi@eecs.umich.edu
503804Ssaidi@eecs.umich.edu#include "arch/isa_traits.hh"
513804Ssaidi@eecs.umich.edu#include "arch/registers.hh"
523804Ssaidi@eecs.umich.edu#include "config/the_isa.hh"
533804Ssaidi@eecs.umich.edu#include "cpu/o3/rename.hh"
543569Sgblack@eecs.umich.edu#include "cpu/reg_class.hh"
553804Ssaidi@eecs.umich.edu#include "debug/Activity.hh"
563804Ssaidi@eecs.umich.edu#include "debug/Rename.hh"
573881Ssaidi@eecs.umich.edu#include "debug/O3PipeView.hh"
583881Ssaidi@eecs.umich.edu#include "params/DerivO3CPU.hh"
593881Ssaidi@eecs.umich.edu
603804Ssaidi@eecs.umich.eduusing namespace std;
613569Sgblack@eecs.umich.edu
623804Ssaidi@eecs.umich.edutemplate <class Impl>
633804Ssaidi@eecs.umich.eduDefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params)
643804Ssaidi@eecs.umich.edu    : cpu(_cpu),
653804Ssaidi@eecs.umich.edu      iewToRenameDelay(params->iewToRenameDelay),
663881Ssaidi@eecs.umich.edu      decodeToRenameDelay(params->decodeToRenameDelay),
673804Ssaidi@eecs.umich.edu      commitToRenameDelay(params->commitToRenameDelay),
683804Ssaidi@eecs.umich.edu      renameWidth(params->renameWidth),
693804Ssaidi@eecs.umich.edu      commitWidth(params->commitWidth),
703804Ssaidi@eecs.umich.edu      numThreads(params->numThreads)
713804Ssaidi@eecs.umich.edu{
723804Ssaidi@eecs.umich.edu    if (renameWidth > Impl::MaxWidth)
733804Ssaidi@eecs.umich.edu        fatal("renameWidth (%d) is larger than compiled limit (%d),\n"
743569Sgblack@eecs.umich.edu             "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
753569Sgblack@eecs.umich.edu             renameWidth, static_cast<int>(Impl::MaxWidth));
763804Ssaidi@eecs.umich.edu
773804Ssaidi@eecs.umich.edu    // @todo: Make into a parameter.
783826Ssaidi@eecs.umich.edu    skidBufferMax = (decodeToRenameDelay + 1) * params->decodeWidth;
793804Ssaidi@eecs.umich.edu    for (uint32_t tid = 0; tid < Impl::MaxThreads; tid++) {
803569Sgblack@eecs.umich.edu        renameStatus[tid] = Idle;
813569Sgblack@eecs.umich.edu        renameMap[tid] = nullptr;
823804Ssaidi@eecs.umich.edu        instsInProgress[tid] = 0;
833826Ssaidi@eecs.umich.edu        loadsInProgress[tid] = 0;
843907Ssaidi@eecs.umich.edu        storesInProgress[tid] = 0;
853826Ssaidi@eecs.umich.edu        freeEntries[tid] = {0, 0, 0, 0};
863811Ssaidi@eecs.umich.edu        emptyROB[tid] = true;
873836Ssaidi@eecs.umich.edu        stalls[tid] = {false, false};
883907Ssaidi@eecs.umich.edu        serializeInst[tid] = nullptr;
893881Ssaidi@eecs.umich.edu        serializeOnNextInst[tid] = false;
903881Ssaidi@eecs.umich.edu    }
913881Ssaidi@eecs.umich.edu}
923881Ssaidi@eecs.umich.edu
933907Ssaidi@eecs.umich.edutemplate <class Impl>
943881Ssaidi@eecs.umich.edustd::string
953881Ssaidi@eecs.umich.eduDefaultRename<Impl>::name() const
963881Ssaidi@eecs.umich.edu{
973881Ssaidi@eecs.umich.edu    return cpu->name() + ".rename";
983881Ssaidi@eecs.umich.edu}
993907Ssaidi@eecs.umich.edu
1003907Ssaidi@eecs.umich.edutemplate <class Impl>
1013907Ssaidi@eecs.umich.eduvoid
1023907Ssaidi@eecs.umich.eduDefaultRename<Impl>::regStats()
1033907Ssaidi@eecs.umich.edu{
1043907Ssaidi@eecs.umich.edu    renameSquashCycles
1053907Ssaidi@eecs.umich.edu        .name(name() + ".SquashCycles")
1063907Ssaidi@eecs.umich.edu        .desc("Number of cycles rename is squashing")
1073907Ssaidi@eecs.umich.edu        .prereq(renameSquashCycles);
1083907Ssaidi@eecs.umich.edu    renameIdleCycles
1093907Ssaidi@eecs.umich.edu        .name(name() + ".IdleCycles")
1103907Ssaidi@eecs.umich.edu        .desc("Number of cycles rename is idle")
1113907Ssaidi@eecs.umich.edu        .prereq(renameIdleCycles);
1123907Ssaidi@eecs.umich.edu    renameBlockCycles
1133907Ssaidi@eecs.umich.edu        .name(name() + ".BlockCycles")
1143907Ssaidi@eecs.umich.edu        .desc("Number of cycles rename is blocking")
1153907Ssaidi@eecs.umich.edu        .prereq(renameBlockCycles);
1163907Ssaidi@eecs.umich.edu    renameSerializeStallCycles
1173907Ssaidi@eecs.umich.edu        .name(name() + ".serializeStallCycles")
1183907Ssaidi@eecs.umich.edu        .desc("count of cycles rename stalled for serializing inst")
1193907Ssaidi@eecs.umich.edu        .flags(Stats::total);
1203907Ssaidi@eecs.umich.edu    renameRunCycles
1213907Ssaidi@eecs.umich.edu        .name(name() + ".RunCycles")
1223881Ssaidi@eecs.umich.edu        .desc("Number of cycles rename is running")
1233881Ssaidi@eecs.umich.edu        .prereq(renameIdleCycles);
1243881Ssaidi@eecs.umich.edu    renameUnblockCycles
1253881Ssaidi@eecs.umich.edu        .name(name() + ".UnblockCycles")
1263881Ssaidi@eecs.umich.edu        .desc("Number of cycles rename is unblocking")
1273881Ssaidi@eecs.umich.edu        .prereq(renameUnblockCycles);
1283881Ssaidi@eecs.umich.edu    renameRenamedInsts
1293881Ssaidi@eecs.umich.edu        .name(name() + ".RenamedInsts")
1303881Ssaidi@eecs.umich.edu        .desc("Number of instructions processed by rename")
1313881Ssaidi@eecs.umich.edu        .prereq(renameRenamedInsts);
1323881Ssaidi@eecs.umich.edu    renameSquashedInsts
1333881Ssaidi@eecs.umich.edu        .name(name() + ".SquashedInsts")
1343907Ssaidi@eecs.umich.edu        .desc("Number of squashed instructions processed by rename")
1353811Ssaidi@eecs.umich.edu        .prereq(renameSquashedInsts);
1363826Ssaidi@eecs.umich.edu    renameROBFullEvents
1373826Ssaidi@eecs.umich.edu        .name(name() + ".ROBFullEvents")
1383826Ssaidi@eecs.umich.edu        .desc("Number of times rename has blocked due to ROB full")
1393826Ssaidi@eecs.umich.edu        .prereq(renameROBFullEvents);
1403881Ssaidi@eecs.umich.edu    renameIQFullEvents
1413881Ssaidi@eecs.umich.edu        .name(name() + ".IQFullEvents")
1423881Ssaidi@eecs.umich.edu        .desc("Number of times rename has blocked due to IQ full")
1433881Ssaidi@eecs.umich.edu        .prereq(renameIQFullEvents);
1443881Ssaidi@eecs.umich.edu    renameLQFullEvents
1453881Ssaidi@eecs.umich.edu        .name(name() + ".LQFullEvents")
1463881Ssaidi@eecs.umich.edu        .desc("Number of times rename has blocked due to LQ full")
1473881Ssaidi@eecs.umich.edu        .prereq(renameLQFullEvents);
1483881Ssaidi@eecs.umich.edu    renameSQFullEvents
1493881Ssaidi@eecs.umich.edu        .name(name() + ".SQFullEvents")
1503881Ssaidi@eecs.umich.edu        .desc("Number of times rename has blocked due to SQ full")
1513881Ssaidi@eecs.umich.edu        .prereq(renameSQFullEvents);
1523881Ssaidi@eecs.umich.edu    renameFullRegistersEvents
1533881Ssaidi@eecs.umich.edu        .name(name() + ".FullRegisterEvents")
1543881Ssaidi@eecs.umich.edu        .desc("Number of times there has been no free registers")
1553826Ssaidi@eecs.umich.edu        .prereq(renameFullRegistersEvents);
1563826Ssaidi@eecs.umich.edu    renameRenamedOperands
1573826Ssaidi@eecs.umich.edu        .name(name() + ".RenamedOperands")
1583826Ssaidi@eecs.umich.edu        .desc("Number of destination operands rename has renamed")
1593826Ssaidi@eecs.umich.edu        .prereq(renameRenamedOperands);
1603881Ssaidi@eecs.umich.edu    renameRenameLookups
1613569Sgblack@eecs.umich.edu        .name(name() + ".RenameLookups")
1623569Sgblack@eecs.umich.edu        .desc("Number of register rename lookups that rename has made")
1633881Ssaidi@eecs.umich.edu        .prereq(renameRenameLookups);
1643804Ssaidi@eecs.umich.edu    renameCommittedMaps
1653881Ssaidi@eecs.umich.edu        .name(name() + ".CommittedMaps")
1663826Ssaidi@eecs.umich.edu        .desc("Number of HB maps that are committed")
1673881Ssaidi@eecs.umich.edu        .prereq(renameCommittedMaps);
1683881Ssaidi@eecs.umich.edu    renameUndoneMaps
1693881Ssaidi@eecs.umich.edu        .name(name() + ".UndoneMaps")
1703907Ssaidi@eecs.umich.edu        .desc("Number of HB maps that are undone due to squashing")
1713907Ssaidi@eecs.umich.edu        .prereq(renameUndoneMaps);
1723907Ssaidi@eecs.umich.edu    renamedSerializing
1733907Ssaidi@eecs.umich.edu        .name(name() + ".serializingInsts")
1743907Ssaidi@eecs.umich.edu        .desc("count of serializing insts renamed")
1753907Ssaidi@eecs.umich.edu        .flags(Stats::total)
1763881Ssaidi@eecs.umich.edu        ;
1773569Sgblack@eecs.umich.edu    renamedTempSerializing
1783804Ssaidi@eecs.umich.edu        .name(name() + ".tempSerializingInsts")
1793804Ssaidi@eecs.umich.edu        .desc("count of temporary serializing insts renamed")
1803881Ssaidi@eecs.umich.edu        .flags(Stats::total)
1813804Ssaidi@eecs.umich.edu        ;
1823804Ssaidi@eecs.umich.edu    renameSkidInsts
1833804Ssaidi@eecs.umich.edu        .name(name() + ".skidInsts")
1843804Ssaidi@eecs.umich.edu        .desc("count of insts added to the skid buffer")
1853804Ssaidi@eecs.umich.edu        .flags(Stats::total)
1863804Ssaidi@eecs.umich.edu        ;
1873804Ssaidi@eecs.umich.edu    intRenameLookups
1883569Sgblack@eecs.umich.edu        .name(name() + ".int_rename_lookups")
1893569Sgblack@eecs.umich.edu        .desc("Number of integer rename lookups")
1903569Sgblack@eecs.umich.edu        .prereq(intRenameLookups);
1913863Ssaidi@eecs.umich.edu    fpRenameLookups
1923863Ssaidi@eecs.umich.edu        .name(name() + ".fp_rename_lookups")
1933804Ssaidi@eecs.umich.edu        .desc("Number of floating rename lookups")
1943804Ssaidi@eecs.umich.edu        .prereq(fpRenameLookups);
1953804Ssaidi@eecs.umich.edu    vecRenameLookups
1963804Ssaidi@eecs.umich.edu        .name(name() + ".vec_rename_lookups")
1973804Ssaidi@eecs.umich.edu        .desc("Number of vector rename lookups")
1983804Ssaidi@eecs.umich.edu        .prereq(vecRenameLookups);
1993804Ssaidi@eecs.umich.edu    vecPredRenameLookups
2003804Ssaidi@eecs.umich.edu        .name(name() + ".vec_pred_rename_lookups")
2013804Ssaidi@eecs.umich.edu        .desc("Number of vector predicate rename lookups")
2023569Sgblack@eecs.umich.edu        .prereq(vecPredRenameLookups);
2033804Ssaidi@eecs.umich.edu}
2043804Ssaidi@eecs.umich.edu
2053804Ssaidi@eecs.umich.edutemplate <class Impl>
2063804Ssaidi@eecs.umich.eduvoid
2073804Ssaidi@eecs.umich.eduDefaultRename<Impl>::regProbePoints()
2083804Ssaidi@eecs.umich.edu{
2093804Ssaidi@eecs.umich.edu    ppRename = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Rename");
2103804Ssaidi@eecs.umich.edu    ppSquashInRename = new ProbePointArg<SeqNumRegPair>(cpu->getProbeManager(),
2113804Ssaidi@eecs.umich.edu                                                        "SquashInRename");
2123811Ssaidi@eecs.umich.edu}
2133811Ssaidi@eecs.umich.edu
2143804Ssaidi@eecs.umich.edutemplate <class Impl>
2153804Ssaidi@eecs.umich.eduvoid
2163863Ssaidi@eecs.umich.eduDefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
2173804Ssaidi@eecs.umich.edu{
2183804Ssaidi@eecs.umich.edu    timeBuffer = tb_ptr;
2193804Ssaidi@eecs.umich.edu
2203804Ssaidi@eecs.umich.edu    // Setup wire to read information from time buffer, from IEW stage.
2213804Ssaidi@eecs.umich.edu    fromIEW = timeBuffer->getWire(-iewToRenameDelay);
2223804Ssaidi@eecs.umich.edu
2233804Ssaidi@eecs.umich.edu    // Setup wire to read infromation from time buffer, from commit stage.
2243811Ssaidi@eecs.umich.edu    fromCommit = timeBuffer->getWire(-commitToRenameDelay);
2253804Ssaidi@eecs.umich.edu
2263804Ssaidi@eecs.umich.edu    // Setup wire to write information to previous stages.
2273804Ssaidi@eecs.umich.edu    toDecode = timeBuffer->getWire(0);
2283804Ssaidi@eecs.umich.edu}
2293804Ssaidi@eecs.umich.edu
2303826Ssaidi@eecs.umich.edutemplate <class Impl>
2313826Ssaidi@eecs.umich.eduvoid
2323804Ssaidi@eecs.umich.eduDefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
2333804Ssaidi@eecs.umich.edu{
2343804Ssaidi@eecs.umich.edu    renameQueue = rq_ptr;
2353804Ssaidi@eecs.umich.edu
2363804Ssaidi@eecs.umich.edu    // Setup wire to write information to future stages.
2373804Ssaidi@eecs.umich.edu    toIEW = renameQueue->getWire(0);
2383804Ssaidi@eecs.umich.edu}
2393804Ssaidi@eecs.umich.edu
2403804Ssaidi@eecs.umich.edutemplate <class Impl>
2413804Ssaidi@eecs.umich.eduvoid
2423804Ssaidi@eecs.umich.eduDefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
2433804Ssaidi@eecs.umich.edu{
2443804Ssaidi@eecs.umich.edu    decodeQueue = dq_ptr;
2453826Ssaidi@eecs.umich.edu
2463826Ssaidi@eecs.umich.edu    // Setup wire to get information from decode.
2473826Ssaidi@eecs.umich.edu    fromDecode = decodeQueue->getWire(-decodeToRenameDelay);
2483863Ssaidi@eecs.umich.edu}
2493826Ssaidi@eecs.umich.edu
2503826Ssaidi@eecs.umich.edutemplate <class Impl>
2513826Ssaidi@eecs.umich.eduvoid
2523826Ssaidi@eecs.umich.eduDefaultRename<Impl>::startupStage()
2533826Ssaidi@eecs.umich.edu{
2543826Ssaidi@eecs.umich.edu    resetStage();
2553826Ssaidi@eecs.umich.edu}
2563826Ssaidi@eecs.umich.edu
2573826Ssaidi@eecs.umich.edutemplate <class Impl>
2583804Ssaidi@eecs.umich.eduvoid
2593804Ssaidi@eecs.umich.eduDefaultRename<Impl>::clearStates(ThreadID tid)
2603804Ssaidi@eecs.umich.edu{
2613804Ssaidi@eecs.umich.edu    renameStatus[tid] = Idle;
2623804Ssaidi@eecs.umich.edu
2633804Ssaidi@eecs.umich.edu    freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);
2643804Ssaidi@eecs.umich.edu    freeEntries[tid].lqEntries = iew_ptr->ldstQueue.numFreeLoadEntries(tid);
2653863Ssaidi@eecs.umich.edu    freeEntries[tid].sqEntries = iew_ptr->ldstQueue.numFreeStoreEntries(tid);
2663863Ssaidi@eecs.umich.edu    freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);
2673863Ssaidi@eecs.umich.edu    emptyROB[tid] = true;
2683836Ssaidi@eecs.umich.edu
2693836Ssaidi@eecs.umich.edu    stalls[tid].iew = false;
2703804Ssaidi@eecs.umich.edu    serializeInst[tid] = NULL;
2713804Ssaidi@eecs.umich.edu
2723863Ssaidi@eecs.umich.edu    instsInProgress[tid] = 0;
2733804Ssaidi@eecs.umich.edu    loadsInProgress[tid] = 0;
2743804Ssaidi@eecs.umich.edu    storesInProgress[tid] = 0;
2753804Ssaidi@eecs.umich.edu
2763804Ssaidi@eecs.umich.edu    serializeOnNextInst[tid] = false;
2773804Ssaidi@eecs.umich.edu}
2783804Ssaidi@eecs.umich.edu
2793804Ssaidi@eecs.umich.edutemplate <class Impl>
2803863Ssaidi@eecs.umich.eduvoid
2813804Ssaidi@eecs.umich.eduDefaultRename<Impl>::resetStage()
2823804Ssaidi@eecs.umich.edu{
2833804Ssaidi@eecs.umich.edu    _status = Inactive;
2843804Ssaidi@eecs.umich.edu
2853804Ssaidi@eecs.umich.edu    resumeSerialize = false;
2863881Ssaidi@eecs.umich.edu    resumeUnblocking = false;
2873881Ssaidi@eecs.umich.edu
2883804Ssaidi@eecs.umich.edu    // Grab the number of free entries directly from the stages.
2893804Ssaidi@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
2903804Ssaidi@eecs.umich.edu        renameStatus[tid] = Idle;
2913804Ssaidi@eecs.umich.edu
2923804Ssaidi@eecs.umich.edu        freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);
2933804Ssaidi@eecs.umich.edu        freeEntries[tid].lqEntries = iew_ptr->ldstQueue.numFreeLoadEntries(tid);
2943804Ssaidi@eecs.umich.edu        freeEntries[tid].sqEntries = iew_ptr->ldstQueue.numFreeStoreEntries(tid);
2953804Ssaidi@eecs.umich.edu        freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);
2963863Ssaidi@eecs.umich.edu        emptyROB[tid] = true;
2973863Ssaidi@eecs.umich.edu
2983836Ssaidi@eecs.umich.edu        stalls[tid].iew = false;
2993804Ssaidi@eecs.umich.edu        serializeInst[tid] = NULL;
3003804Ssaidi@eecs.umich.edu
3013804Ssaidi@eecs.umich.edu        instsInProgress[tid] = 0;
3023881Ssaidi@eecs.umich.edu        loadsInProgress[tid] = 0;
3033881Ssaidi@eecs.umich.edu        storesInProgress[tid] = 0;
3043881Ssaidi@eecs.umich.edu
3053881Ssaidi@eecs.umich.edu        serializeOnNextInst[tid] = false;
3063804Ssaidi@eecs.umich.edu    }
3073804Ssaidi@eecs.umich.edu}
3083804Ssaidi@eecs.umich.edu
3093804Ssaidi@eecs.umich.edutemplate<class Impl>
3103804Ssaidi@eecs.umich.eduvoid
3113804Ssaidi@eecs.umich.eduDefaultRename<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
3123804Ssaidi@eecs.umich.edu{
3133804Ssaidi@eecs.umich.edu    activeThreads = at_ptr;
3143804Ssaidi@eecs.umich.edu}
3153804Ssaidi@eecs.umich.edu
3163804Ssaidi@eecs.umich.edu
3173804Ssaidi@eecs.umich.edutemplate <class Impl>
3183804Ssaidi@eecs.umich.eduvoid
3193804Ssaidi@eecs.umich.eduDefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[])
3203863Ssaidi@eecs.umich.edu{
3213836Ssaidi@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++)
3223804Ssaidi@eecs.umich.edu        renameMap[tid] = &rm_ptr[tid];
3233804Ssaidi@eecs.umich.edu}
3243881Ssaidi@eecs.umich.edu
3253881Ssaidi@eecs.umich.edutemplate <class Impl>
3263881Ssaidi@eecs.umich.eduvoid
3273881Ssaidi@eecs.umich.eduDefaultRename<Impl>::setFreeList(FreeList *fl_ptr)
3283804Ssaidi@eecs.umich.edu{
3293804Ssaidi@eecs.umich.edu    freeList = fl_ptr;
3303804Ssaidi@eecs.umich.edu}
3313804Ssaidi@eecs.umich.edu
3323804Ssaidi@eecs.umich.edutemplate<class Impl>
3333804Ssaidi@eecs.umich.eduvoid
3343804Ssaidi@eecs.umich.eduDefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard)
3353804Ssaidi@eecs.umich.edu{
3363804Ssaidi@eecs.umich.edu    scoreboard = _scoreboard;
3373804Ssaidi@eecs.umich.edu}
3383804Ssaidi@eecs.umich.edu
3393804Ssaidi@eecs.umich.edutemplate <class Impl>
3403804Ssaidi@eecs.umich.edubool
3413804Ssaidi@eecs.umich.eduDefaultRename<Impl>::isDrained() const
3423836Ssaidi@eecs.umich.edu{
3433836Ssaidi@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
3443881Ssaidi@eecs.umich.edu        if (instsInProgress[tid] != 0 ||
3453907Ssaidi@eecs.umich.edu            !historyBuffer[tid].empty() ||
3463804Ssaidi@eecs.umich.edu            !skidBuffer[tid].empty() ||
3473881Ssaidi@eecs.umich.edu            !insts[tid].empty() ||
3483881Ssaidi@eecs.umich.edu            (renameStatus[tid] != Idle && renameStatus[tid] != Running))
3493804Ssaidi@eecs.umich.edu            return false;
3503907Ssaidi@eecs.umich.edu    }
3513804Ssaidi@eecs.umich.edu    return true;
3523804Ssaidi@eecs.umich.edu}
3533804Ssaidi@eecs.umich.edu
3543804Ssaidi@eecs.umich.edutemplate <class Impl>
3553804Ssaidi@eecs.umich.eduvoid
3563804Ssaidi@eecs.umich.eduDefaultRename<Impl>::takeOverFrom()
3573881Ssaidi@eecs.umich.edu{
3583881Ssaidi@eecs.umich.edu    resetStage();
3593881Ssaidi@eecs.umich.edu}
3603804Ssaidi@eecs.umich.edu
3613881Ssaidi@eecs.umich.edutemplate <class Impl>
3623881Ssaidi@eecs.umich.eduvoid
3633881Ssaidi@eecs.umich.eduDefaultRename<Impl>::drainSanityCheck() const
3643881Ssaidi@eecs.umich.edu{
3653804Ssaidi@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
3663804Ssaidi@eecs.umich.edu        assert(historyBuffer[tid].empty());
3673804Ssaidi@eecs.umich.edu        assert(insts[tid].empty());
3683804Ssaidi@eecs.umich.edu        assert(skidBuffer[tid].empty());
3693804Ssaidi@eecs.umich.edu        assert(instsInProgress[tid] == 0);
3703804Ssaidi@eecs.umich.edu    }
3713881Ssaidi@eecs.umich.edu}
3723881Ssaidi@eecs.umich.edu
3733804Ssaidi@eecs.umich.edutemplate <class Impl>
3743881Ssaidi@eecs.umich.eduvoid
3753881Ssaidi@eecs.umich.eduDefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, ThreadID tid)
3763881Ssaidi@eecs.umich.edu{
3773804Ssaidi@eecs.umich.edu    DPRINTF(Rename, "[tid:%i] [squash sn:%llu] Squashing instructions.\n",
3783804Ssaidi@eecs.umich.edu        tid,squash_seq_num);
3793804Ssaidi@eecs.umich.edu
3803804Ssaidi@eecs.umich.edu    // Clear the stall signal if rename was blocked or unblocking before.
3813804Ssaidi@eecs.umich.edu    // If it still needs to block, the blocking should happen the next
3823804Ssaidi@eecs.umich.edu    // cycle and there should be space to hold everything due to the squash.
3833804Ssaidi@eecs.umich.edu    if (renameStatus[tid] == Blocked ||
3843804Ssaidi@eecs.umich.edu        renameStatus[tid] == Unblocking) {
3853804Ssaidi@eecs.umich.edu        toDecode->renameUnblock[tid] = 1;
3863804Ssaidi@eecs.umich.edu
3873804Ssaidi@eecs.umich.edu        resumeSerialize = false;
3883804Ssaidi@eecs.umich.edu        serializeInst[tid] = NULL;
3893804Ssaidi@eecs.umich.edu    } else if (renameStatus[tid] == SerializeStall) {
3903804Ssaidi@eecs.umich.edu        if (serializeInst[tid]->seqNum <= squash_seq_num) {
3913804Ssaidi@eecs.umich.edu            DPRINTF(Rename, "[tid:%i] [squash sn:%llu] "
3923804Ssaidi@eecs.umich.edu                "Rename will resume serializing after squash\n",
3933804Ssaidi@eecs.umich.edu                tid,squash_seq_num);
3943804Ssaidi@eecs.umich.edu            resumeSerialize = true;
3953804Ssaidi@eecs.umich.edu            assert(serializeInst[tid]);
3963804Ssaidi@eecs.umich.edu        } else {
3973804Ssaidi@eecs.umich.edu            resumeSerialize = false;
3983804Ssaidi@eecs.umich.edu            toDecode->renameUnblock[tid] = 1;
3993804Ssaidi@eecs.umich.edu
4003804Ssaidi@eecs.umich.edu            serializeInst[tid] = NULL;
4013804Ssaidi@eecs.umich.edu        }
4023804Ssaidi@eecs.umich.edu    }
4033804Ssaidi@eecs.umich.edu
4043804Ssaidi@eecs.umich.edu    // Set the status to Squashing.
4053804Ssaidi@eecs.umich.edu    renameStatus[tid] = Squashing;
4063804Ssaidi@eecs.umich.edu
4073804Ssaidi@eecs.umich.edu    // Squash any instructions from decode.
4083804Ssaidi@eecs.umich.edu    for (int i=0; i<fromDecode->size; i++) {
4093804Ssaidi@eecs.umich.edu        if (fromDecode->insts[i]->threadNumber == tid &&
4103804Ssaidi@eecs.umich.edu            fromDecode->insts[i]->seqNum > squash_seq_num) {
4113826Ssaidi@eecs.umich.edu            fromDecode->insts[i]->setSquashed();
4123804Ssaidi@eecs.umich.edu            wroteToTimeBuffer = true;
4133804Ssaidi@eecs.umich.edu        }
4143826Ssaidi@eecs.umich.edu
4153826Ssaidi@eecs.umich.edu    }
4163826Ssaidi@eecs.umich.edu
4173826Ssaidi@eecs.umich.edu    // Clear the instruction list and skid buffer in case they have any
4183826Ssaidi@eecs.umich.edu    // insts in them.
4193804Ssaidi@eecs.umich.edu    insts[tid].clear();
4203804Ssaidi@eecs.umich.edu
4213804Ssaidi@eecs.umich.edu    // Clear the skid buffer in case it has any data in it.
4223804Ssaidi@eecs.umich.edu    skidBuffer[tid].clear();
4233804Ssaidi@eecs.umich.edu
4243811Ssaidi@eecs.umich.edu    doSquash(squash_seq_num, tid);
4253811Ssaidi@eecs.umich.edu}
4263804Ssaidi@eecs.umich.edu
4273804Ssaidi@eecs.umich.edutemplate <class Impl>
4283804Ssaidi@eecs.umich.eduvoid
4293804Ssaidi@eecs.umich.eduDefaultRename<Impl>::tick()
4303826Ssaidi@eecs.umich.edu{
4313826Ssaidi@eecs.umich.edu    wroteToTimeBuffer = false;
4323826Ssaidi@eecs.umich.edu
4333826Ssaidi@eecs.umich.edu    blockThisCycle = false;
4343826Ssaidi@eecs.umich.edu
4353826Ssaidi@eecs.umich.edu    bool status_change = false;
4363804Ssaidi@eecs.umich.edu
4373804Ssaidi@eecs.umich.edu    toIEWIndex = 0;
4383804Ssaidi@eecs.umich.edu
4393811Ssaidi@eecs.umich.edu    sortInsts();
4403811Ssaidi@eecs.umich.edu
4413804Ssaidi@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4423826Ssaidi@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4433804Ssaidi@eecs.umich.edu
4443804Ssaidi@eecs.umich.edu    // Check stall and squash signals.
4453836Ssaidi@eecs.umich.edu    while (threads != end) {
4463826Ssaidi@eecs.umich.edu        ThreadID tid = *threads++;
4473826Ssaidi@eecs.umich.edu
4483826Ssaidi@eecs.umich.edu        DPRINTF(Rename, "Processing [tid:%i]\n", tid);
4493826Ssaidi@eecs.umich.edu
4503826Ssaidi@eecs.umich.edu        status_change = checkSignalsAndUpdate(tid) || status_change;
4513826Ssaidi@eecs.umich.edu
4523804Ssaidi@eecs.umich.edu        rename(status_change, tid);
4533804Ssaidi@eecs.umich.edu    }
4543804Ssaidi@eecs.umich.edu
4553804Ssaidi@eecs.umich.edu    if (status_change) {
4563833Ssaidi@eecs.umich.edu        updateStatus();
4573833Ssaidi@eecs.umich.edu    }
4583836Ssaidi@eecs.umich.edu
4593836Ssaidi@eecs.umich.edu    if (wroteToTimeBuffer) {
4603836Ssaidi@eecs.umich.edu        DPRINTF(Activity, "Activity this cycle.\n");
4613836Ssaidi@eecs.umich.edu        cpu->activityThisCycle();
4623836Ssaidi@eecs.umich.edu    }
4633836Ssaidi@eecs.umich.edu
4643836Ssaidi@eecs.umich.edu    threads = activeThreads->begin();
4653836Ssaidi@eecs.umich.edu
4663836Ssaidi@eecs.umich.edu    while (threads != end) {
4673836Ssaidi@eecs.umich.edu        ThreadID tid = *threads++;
4683836Ssaidi@eecs.umich.edu
4693836Ssaidi@eecs.umich.edu        // If we committed this cycle then doneSeqNum will be > 0
4703836Ssaidi@eecs.umich.edu        if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
4713836Ssaidi@eecs.umich.edu            !fromCommit->commitInfo[tid].squash &&
4723836Ssaidi@eecs.umich.edu            renameStatus[tid] != Squashing) {
4733836Ssaidi@eecs.umich.edu
4743836Ssaidi@eecs.umich.edu            removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum,
4753836Ssaidi@eecs.umich.edu                                  tid);
4763836Ssaidi@eecs.umich.edu        }
4773836Ssaidi@eecs.umich.edu    }
4783836Ssaidi@eecs.umich.edu
4793836Ssaidi@eecs.umich.edu    // @todo: make into updateProgress function
4803836Ssaidi@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
4813833Ssaidi@eecs.umich.edu        instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;
4823833Ssaidi@eecs.umich.edu        loadsInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToLQ;
4833833Ssaidi@eecs.umich.edu        storesInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToSQ;
4843833Ssaidi@eecs.umich.edu        assert(loadsInProgress[tid] >= 0);
4853833Ssaidi@eecs.umich.edu        assert(storesInProgress[tid] >= 0);
4863833Ssaidi@eecs.umich.edu        assert(instsInProgress[tid] >=0);
4873833Ssaidi@eecs.umich.edu    }
4883833Ssaidi@eecs.umich.edu
4893833Ssaidi@eecs.umich.edu}
4903804Ssaidi@eecs.umich.edu
4913804Ssaidi@eecs.umich.edutemplate<class Impl>
4923804Ssaidi@eecs.umich.eduvoid
4933804Ssaidi@eecs.umich.eduDefaultRename<Impl>::rename(bool &status_change, ThreadID tid)
4943804Ssaidi@eecs.umich.edu{
4953833Ssaidi@eecs.umich.edu    // If status is Running or idle,
4963833Ssaidi@eecs.umich.edu    //     call renameInsts()
4973811Ssaidi@eecs.umich.edu    // If status is Unblocking,
4983804Ssaidi@eecs.umich.edu    //     buffer any instructions coming from decode
4993804Ssaidi@eecs.umich.edu    //     continue trying to empty skid buffer
5003804Ssaidi@eecs.umich.edu    //     check if stall conditions have passed
5013804Ssaidi@eecs.umich.edu
5023804Ssaidi@eecs.umich.edu    if (renameStatus[tid] == Blocked) {
5033804Ssaidi@eecs.umich.edu        ++renameBlockCycles;
5043804Ssaidi@eecs.umich.edu    } else if (renameStatus[tid] == Squashing) {
5053833Ssaidi@eecs.umich.edu        ++renameSquashCycles;
5063804Ssaidi@eecs.umich.edu    } else if (renameStatus[tid] == SerializeStall) {
5073804Ssaidi@eecs.umich.edu        ++renameSerializeStallCycles;
5083833Ssaidi@eecs.umich.edu        // If we are currently in SerializeStall and resumeSerialize
5093836Ssaidi@eecs.umich.edu        // was set, then that means that we are resuming serializing
5103836Ssaidi@eecs.umich.edu        // this cycle.  Tell the previous stages to block.
5113836Ssaidi@eecs.umich.edu        if (resumeSerialize) {
5123836Ssaidi@eecs.umich.edu            resumeSerialize = false;
5133804Ssaidi@eecs.umich.edu            block(tid);
5143804Ssaidi@eecs.umich.edu            toDecode->renameUnblock[tid] = false;
5153804Ssaidi@eecs.umich.edu        }
5163836Ssaidi@eecs.umich.edu    } else if (renameStatus[tid] == Unblocking) {
5173836Ssaidi@eecs.umich.edu        if (resumeUnblocking) {
5183804Ssaidi@eecs.umich.edu            block(tid);
5193804Ssaidi@eecs.umich.edu            resumeUnblocking = false;
5203804Ssaidi@eecs.umich.edu            toDecode->renameUnblock[tid] = false;
5213804Ssaidi@eecs.umich.edu        }
5223804Ssaidi@eecs.umich.edu    }
5233804Ssaidi@eecs.umich.edu
5243804Ssaidi@eecs.umich.edu    if (renameStatus[tid] == Running ||
5253804Ssaidi@eecs.umich.edu        renameStatus[tid] == Idle) {
5263804Ssaidi@eecs.umich.edu        DPRINTF(Rename,
5273804Ssaidi@eecs.umich.edu                "[tid:%i] "
5283804Ssaidi@eecs.umich.edu                "Not blocked, so attempting to run stage.\n",
5293804Ssaidi@eecs.umich.edu                tid);
5303833Ssaidi@eecs.umich.edu
5313836Ssaidi@eecs.umich.edu        renameInsts(tid);
5323804Ssaidi@eecs.umich.edu    } else if (renameStatus[tid] == Unblocking) {
5333804Ssaidi@eecs.umich.edu        renameInsts(tid);
5343804Ssaidi@eecs.umich.edu
5353804Ssaidi@eecs.umich.edu        if (validInsts()) {
5363804Ssaidi@eecs.umich.edu            // Add the current inputs to the skid buffer so they can be
5373804Ssaidi@eecs.umich.edu            // reprocessed when this stage unblocks.
5383804Ssaidi@eecs.umich.edu            skidInsert(tid);
5393804Ssaidi@eecs.umich.edu        }
5403804Ssaidi@eecs.umich.edu
5413804Ssaidi@eecs.umich.edu        // If we switched over to blocking, then there's a potential for
5423804Ssaidi@eecs.umich.edu        // an overall status change.
5433804Ssaidi@eecs.umich.edu        status_change = unblock(tid) || status_change || blockThisCycle;
5443804Ssaidi@eecs.umich.edu    }
5453804Ssaidi@eecs.umich.edu}
5463804Ssaidi@eecs.umich.edu
5473804Ssaidi@eecs.umich.edutemplate <class Impl>
5483804Ssaidi@eecs.umich.eduvoid
5493804Ssaidi@eecs.umich.eduDefaultRename<Impl>::renameInsts(ThreadID tid)
5503804Ssaidi@eecs.umich.edu{
5513804Ssaidi@eecs.umich.edu    // Instructions can be either in the skid buffer or the queue of
5523804Ssaidi@eecs.umich.edu    // instructions coming from decode, depending on the status.
5533836Ssaidi@eecs.umich.edu    int insts_available = renameStatus[tid] == Unblocking ?
5543836Ssaidi@eecs.umich.edu        skidBuffer[tid].size() : insts[tid].size();
5553836Ssaidi@eecs.umich.edu
5563836Ssaidi@eecs.umich.edu    // Check the decode queue to see if instructions are available.
5573836Ssaidi@eecs.umich.edu    // If there are no available instructions to rename, then do nothing.
5583826Ssaidi@eecs.umich.edu    if (insts_available == 0) {
5593836Ssaidi@eecs.umich.edu        DPRINTF(Rename, "[tid:%i] Nothing to do, breaking out early.\n",
5603836Ssaidi@eecs.umich.edu                tid);
5613804Ssaidi@eecs.umich.edu        // Should I change status to idle?
5623804Ssaidi@eecs.umich.edu        ++renameIdleCycles;
5633804Ssaidi@eecs.umich.edu        return;
5643804Ssaidi@eecs.umich.edu    } else if (renameStatus[tid] == Unblocking) {
5653804Ssaidi@eecs.umich.edu        ++renameUnblockCycles;
5663804Ssaidi@eecs.umich.edu    } else if (renameStatus[tid] == Running) {
5673804Ssaidi@eecs.umich.edu        ++renameRunCycles;
5683804Ssaidi@eecs.umich.edu    }
5693804Ssaidi@eecs.umich.edu
5703833Ssaidi@eecs.umich.edu    // Will have to do a different calculation for the number of free
5713836Ssaidi@eecs.umich.edu    // entries.
5723836Ssaidi@eecs.umich.edu    int free_rob_entries = calcFreeROBEntries(tid);
5733836Ssaidi@eecs.umich.edu    int free_iq_entries  = calcFreeIQEntries(tid);
5743836Ssaidi@eecs.umich.edu    int min_free_entries = free_rob_entries;
5753836Ssaidi@eecs.umich.edu
5763836Ssaidi@eecs.umich.edu    FullSource source = ROB;
5773833Ssaidi@eecs.umich.edu
5783836Ssaidi@eecs.umich.edu    if (free_iq_entries < min_free_entries) {
5793836Ssaidi@eecs.umich.edu        min_free_entries = free_iq_entries;
5803836Ssaidi@eecs.umich.edu        source = IQ;
5813836Ssaidi@eecs.umich.edu    }
5823836Ssaidi@eecs.umich.edu
5833836Ssaidi@eecs.umich.edu    // Check if there's any space left.
5843836Ssaidi@eecs.umich.edu    if (min_free_entries <= 0) {
5853836Ssaidi@eecs.umich.edu        DPRINTF(Rename,
5863836Ssaidi@eecs.umich.edu                "[tid:%i] Blocking due to no free ROB/IQ/ entries.\n"
5873836Ssaidi@eecs.umich.edu                "ROB has %i free entries.\n"
5883836Ssaidi@eecs.umich.edu                "IQ has %i free entries.\n",
5893836Ssaidi@eecs.umich.edu                tid, free_rob_entries, free_iq_entries);
5903836Ssaidi@eecs.umich.edu
5913836Ssaidi@eecs.umich.edu        blockThisCycle = true;
5923881Ssaidi@eecs.umich.edu
5933836Ssaidi@eecs.umich.edu        block(tid);
5943836Ssaidi@eecs.umich.edu
5953836Ssaidi@eecs.umich.edu        incrFullStat(source);
5963836Ssaidi@eecs.umich.edu
5973836Ssaidi@eecs.umich.edu        return;
5983881Ssaidi@eecs.umich.edu    } else if (min_free_entries < insts_available) {
5993836Ssaidi@eecs.umich.edu        DPRINTF(Rename,
6003836Ssaidi@eecs.umich.edu                "[tid:%i] "
6013836Ssaidi@eecs.umich.edu                "Will have to block this cycle. "
6023836Ssaidi@eecs.umich.edu                "%i insts available, "
6033836Ssaidi@eecs.umich.edu                "but only %i insts can be renamed due to ROB/IQ/LSQ limits.\n",
6043836Ssaidi@eecs.umich.edu                tid, insts_available, min_free_entries);
6053833Ssaidi@eecs.umich.edu
6063833Ssaidi@eecs.umich.edu        insts_available = min_free_entries;
6073833Ssaidi@eecs.umich.edu
6083833Ssaidi@eecs.umich.edu        blockThisCycle = true;
6093833Ssaidi@eecs.umich.edu
6103833Ssaidi@eecs.umich.edu        incrFullStat(source);
6113833Ssaidi@eecs.umich.edu    }
6123833Ssaidi@eecs.umich.edu
6133833Ssaidi@eecs.umich.edu    InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ?
6143833Ssaidi@eecs.umich.edu        skidBuffer[tid] : insts[tid];
6153804Ssaidi@eecs.umich.edu
6163832Ssaidi@eecs.umich.edu    DPRINTF(Rename,
6173832Ssaidi@eecs.umich.edu            "[tid:%i] "
6183804Ssaidi@eecs.umich.edu            "%i available instructions to send iew.\n",
6193804Ssaidi@eecs.umich.edu            tid, insts_available);
6203804Ssaidi@eecs.umich.edu
6213833Ssaidi@eecs.umich.edu    DPRINTF(Rename,
6223833Ssaidi@eecs.umich.edu            "[tid:%i] "
6233804Ssaidi@eecs.umich.edu            "%i insts pipelining from Rename | "
6243804Ssaidi@eecs.umich.edu            "%i insts dispatched to IQ last cycle.\n",
6253804Ssaidi@eecs.umich.edu            tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched);
6263804Ssaidi@eecs.umich.edu
6273804Ssaidi@eecs.umich.edu    // Handle serializing the next instruction if necessary.
6283804Ssaidi@eecs.umich.edu    if (serializeOnNextInst[tid]) {
6293804Ssaidi@eecs.umich.edu        if (emptyROB[tid] && instsInProgress[tid] == 0) {
6303804Ssaidi@eecs.umich.edu            // ROB already empty; no need to serialize.
6313804Ssaidi@eecs.umich.edu            serializeOnNextInst[tid] = false;
6323833Ssaidi@eecs.umich.edu        } else if (!insts_to_rename.empty()) {
6333804Ssaidi@eecs.umich.edu            insts_to_rename.front()->setSerializeBefore();
6343910Ssaidi@eecs.umich.edu        }
6353804Ssaidi@eecs.umich.edu    }
6363910Ssaidi@eecs.umich.edu
6373804Ssaidi@eecs.umich.edu    int renamed_insts = 0;
6383804Ssaidi@eecs.umich.edu
6393804Ssaidi@eecs.umich.edu    while (insts_available > 0 &&  toIEWIndex < renameWidth) {
6403804Ssaidi@eecs.umich.edu        DPRINTF(Rename, "[tid:%i] Sending instructions to IEW.\n", tid);
6413910Ssaidi@eecs.umich.edu
6423910Ssaidi@eecs.umich.edu        assert(!insts_to_rename.empty());
6433804Ssaidi@eecs.umich.edu
6443804Ssaidi@eecs.umich.edu        DynInstPtr inst = insts_to_rename.front();
6453804Ssaidi@eecs.umich.edu
6463804Ssaidi@eecs.umich.edu        //For all kind of instructions, check ROB and IQ first
6473910Ssaidi@eecs.umich.edu        //For load instruction, check LQ size and take into account the inflight loads
6483910Ssaidi@eecs.umich.edu        //For store instruction, check SQ size and take into account the inflight stores
6493910Ssaidi@eecs.umich.edu
6503910Ssaidi@eecs.umich.edu        if (inst->isLoad()) {
6513910Ssaidi@eecs.umich.edu            if (calcFreeLQEntries(tid) <= 0) {
6523910Ssaidi@eecs.umich.edu                DPRINTF(Rename, "[tid:%i] Cannot rename due to no free LQ\n");
6533910Ssaidi@eecs.umich.edu                source = LQ;
6543910Ssaidi@eecs.umich.edu                incrFullStat(source);
6553910Ssaidi@eecs.umich.edu                break;
6563910Ssaidi@eecs.umich.edu            }
6573910Ssaidi@eecs.umich.edu        }
6583910Ssaidi@eecs.umich.edu
6593910Ssaidi@eecs.umich.edu        if (inst->isStore() || inst->isAtomic()) {
6603902Ssaidi@eecs.umich.edu            if (calcFreeSQEntries(tid) <= 0) {
6613804Ssaidi@eecs.umich.edu                DPRINTF(Rename, "[tid:%i] Cannot rename due to no free SQ\n");
6623804Ssaidi@eecs.umich.edu                source = SQ;
6633804Ssaidi@eecs.umich.edu                incrFullStat(source);
6643804Ssaidi@eecs.umich.edu                break;
6653804Ssaidi@eecs.umich.edu            }
6663804Ssaidi@eecs.umich.edu        }
6673804Ssaidi@eecs.umich.edu
6683804Ssaidi@eecs.umich.edu        insts_to_rename.pop_front();
6693910Ssaidi@eecs.umich.edu
6703910Ssaidi@eecs.umich.edu        if (renameStatus[tid] == Unblocking) {
6713910Ssaidi@eecs.umich.edu            DPRINTF(Rename,
6723910Ssaidi@eecs.umich.edu                    "[tid:%i] "
6733908Ssaidi@eecs.umich.edu                    "Removing [sn:%llu] PC:%s from rename skidBuffer\n",
6743856Ssaidi@eecs.umich.edu                    tid, inst->seqNum, inst->pcState());
6753856Ssaidi@eecs.umich.edu        }
6763804Ssaidi@eecs.umich.edu
6773804Ssaidi@eecs.umich.edu        if (inst->isSquashed()) {
6783804Ssaidi@eecs.umich.edu            DPRINTF(Rename,
6793804Ssaidi@eecs.umich.edu                    "[tid:%i] "
6803824Ssaidi@eecs.umich.edu                    "instruction %i with PC %s is squashed, skipping.\n",
6813824Ssaidi@eecs.umich.edu                    tid, inst->seqNum, inst->pcState());
6823823Ssaidi@eecs.umich.edu
6833804Ssaidi@eecs.umich.edu            ++renameSquashedInsts;
6843804Ssaidi@eecs.umich.edu
6853804Ssaidi@eecs.umich.edu            // Decrement how many instructions are available.
6863804Ssaidi@eecs.umich.edu            --insts_available;
6873824Ssaidi@eecs.umich.edu
6883824Ssaidi@eecs.umich.edu            continue;
6893825Ssaidi@eecs.umich.edu        }
6903825Ssaidi@eecs.umich.edu
6913823Ssaidi@eecs.umich.edu        DPRINTF(Rename,
6923910Ssaidi@eecs.umich.edu                "[tid:%i] "
6933823Ssaidi@eecs.umich.edu                "Processing instruction [sn:%llu] with PC %s.\n",
6943804Ssaidi@eecs.umich.edu                tid, inst->seqNum, inst->pcState());
6953804Ssaidi@eecs.umich.edu
6963826Ssaidi@eecs.umich.edu        // Check here to make sure there are enough destination registers
6973826Ssaidi@eecs.umich.edu        // to rename to.  Otherwise block.
6983826Ssaidi@eecs.umich.edu        if (!renameMap[tid]->canRename(inst->numIntDestRegs(),
6993826Ssaidi@eecs.umich.edu                                       inst->numFPDestRegs(),
7003826Ssaidi@eecs.umich.edu                                       inst->numVecDestRegs(),
7013826Ssaidi@eecs.umich.edu                                       inst->numVecElemDestRegs(),
7023826Ssaidi@eecs.umich.edu                                       inst->numVecPredDestRegs(),
7033826Ssaidi@eecs.umich.edu                                       inst->numCCDestRegs())) {
7043826Ssaidi@eecs.umich.edu            DPRINTF(Rename,
7053826Ssaidi@eecs.umich.edu                    "Blocking due to "
7063826Ssaidi@eecs.umich.edu                    " lack of free physical registers to rename to.\n");
7073826Ssaidi@eecs.umich.edu            blockThisCycle = true;
7083826Ssaidi@eecs.umich.edu            insts_to_rename.push_front(inst);
7093826Ssaidi@eecs.umich.edu            ++renameFullRegistersEvents;
7103826Ssaidi@eecs.umich.edu
7113826Ssaidi@eecs.umich.edu            break;
7123910Ssaidi@eecs.umich.edu        }
7133804Ssaidi@eecs.umich.edu
7143804Ssaidi@eecs.umich.edu        // Handle serializeAfter/serializeBefore instructions.
7153804Ssaidi@eecs.umich.edu        // serializeAfter marks the next instruction as serializeBefore.
7163804Ssaidi@eecs.umich.edu        // serializeBefore makes the instruction wait in rename until the ROB
7173804Ssaidi@eecs.umich.edu        // is empty.
7183836Ssaidi@eecs.umich.edu
7193804Ssaidi@eecs.umich.edu        // In this model, IPR accesses are serialize before
7203804Ssaidi@eecs.umich.edu        // instructions, and store conditionals are serialize after
7213804Ssaidi@eecs.umich.edu        // instructions.  This is mainly due to lack of support for
7223836Ssaidi@eecs.umich.edu        // out-of-order operations of either of those classes of
7233804Ssaidi@eecs.umich.edu        // instructions.
7243804Ssaidi@eecs.umich.edu        if ((inst->isIprAccess() || inst->isSerializeBefore()) &&
7253804Ssaidi@eecs.umich.edu            !inst->isSerializeHandled()) {
7263804Ssaidi@eecs.umich.edu            DPRINTF(Rename, "Serialize before instruction encountered.\n");
7273811Ssaidi@eecs.umich.edu
7283804Ssaidi@eecs.umich.edu            if (!inst->isTempSerializeBefore()) {
7293804Ssaidi@eecs.umich.edu                renamedSerializing++;
7303804Ssaidi@eecs.umich.edu                inst->setSerializeHandled();
7313804Ssaidi@eecs.umich.edu            } else {
7323804Ssaidi@eecs.umich.edu                renamedTempSerializing++;
7333804Ssaidi@eecs.umich.edu            }
7343804Ssaidi@eecs.umich.edu
7353804Ssaidi@eecs.umich.edu            // Change status over to SerializeStall so that other stages know
7363804Ssaidi@eecs.umich.edu            // what this is blocked on.
7373804Ssaidi@eecs.umich.edu            renameStatus[tid] = SerializeStall;
7383804Ssaidi@eecs.umich.edu
7393804Ssaidi@eecs.umich.edu            serializeInst[tid] = inst;
7403804Ssaidi@eecs.umich.edu
7413804Ssaidi@eecs.umich.edu            blockThisCycle = true;
7423804Ssaidi@eecs.umich.edu
7433804Ssaidi@eecs.umich.edu            break;
7443804Ssaidi@eecs.umich.edu        } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) &&
7453804Ssaidi@eecs.umich.edu                   !inst->isSerializeHandled()) {
7463804Ssaidi@eecs.umich.edu            DPRINTF(Rename, "Serialize after instruction encountered.\n");
7473804Ssaidi@eecs.umich.edu
7483804Ssaidi@eecs.umich.edu            renamedSerializing++;
7493804Ssaidi@eecs.umich.edu
7503804Ssaidi@eecs.umich.edu            inst->setSerializeHandled();
7513804Ssaidi@eecs.umich.edu
7523804Ssaidi@eecs.umich.edu            serializeAfter(insts_to_rename, tid);
7533804Ssaidi@eecs.umich.edu        }
7543804Ssaidi@eecs.umich.edu
7553836Ssaidi@eecs.umich.edu        renameSrcRegs(inst, inst->threadNumber);
7563836Ssaidi@eecs.umich.edu
7573881Ssaidi@eecs.umich.edu        renameDestRegs(inst, inst->threadNumber);
7583881Ssaidi@eecs.umich.edu
7593881Ssaidi@eecs.umich.edu        if (inst->isAtomic() || inst->isStore()) {
7603881Ssaidi@eecs.umich.edu            storesInProgress[tid]++;
7613881Ssaidi@eecs.umich.edu        } else if (inst->isLoad()) {
7623836Ssaidi@eecs.umich.edu            loadsInProgress[tid]++;
7633836Ssaidi@eecs.umich.edu        }
7643836Ssaidi@eecs.umich.edu
7653836Ssaidi@eecs.umich.edu        ++renamed_insts;
7663836Ssaidi@eecs.umich.edu        // Notify potential listeners that source and destination registers for
7673836Ssaidi@eecs.umich.edu        // this instruction have been renamed.
7683836Ssaidi@eecs.umich.edu        ppRename->notify(inst);
7693836Ssaidi@eecs.umich.edu
7703881Ssaidi@eecs.umich.edu        // Put instruction in rename queue.
7713826Ssaidi@eecs.umich.edu        toIEW->insts[toIEWIndex] = inst;
7723836Ssaidi@eecs.umich.edu        ++(toIEW->size);
7733836Ssaidi@eecs.umich.edu
7743804Ssaidi@eecs.umich.edu        // Increment which instruction we're on.
7753806Ssaidi@eecs.umich.edu        ++toIEWIndex;
7763804Ssaidi@eecs.umich.edu
7773806Ssaidi@eecs.umich.edu        // Decrement how many instructions are available.
7783806Ssaidi@eecs.umich.edu        --insts_available;
7793806Ssaidi@eecs.umich.edu    }
7803806Ssaidi@eecs.umich.edu
7813806Ssaidi@eecs.umich.edu    instsInProgress[tid] += renamed_insts;
7823824Ssaidi@eecs.umich.edu    renameRenamedInsts += renamed_insts;
7833824Ssaidi@eecs.umich.edu
7843824Ssaidi@eecs.umich.edu    // If we wrote to the time buffer, record this.
7853824Ssaidi@eecs.umich.edu    if (toIEWIndex) {
7863824Ssaidi@eecs.umich.edu        wroteToTimeBuffer = true;
7873824Ssaidi@eecs.umich.edu    }
7883824Ssaidi@eecs.umich.edu
7893881Ssaidi@eecs.umich.edu    // Check if there's any instructions left that haven't yet been renamed.
7903824Ssaidi@eecs.umich.edu    // If so then block.
7913824Ssaidi@eecs.umich.edu    if (insts_available) {
7923824Ssaidi@eecs.umich.edu        blockThisCycle = true;
7933824Ssaidi@eecs.umich.edu    }
7943824Ssaidi@eecs.umich.edu
7953825Ssaidi@eecs.umich.edu    if (blockThisCycle) {
7963825Ssaidi@eecs.umich.edu        block(tid);
7973825Ssaidi@eecs.umich.edu        toDecode->renameUnblock[tid] = false;
7983825Ssaidi@eecs.umich.edu    }
7993825Ssaidi@eecs.umich.edu}
8003825Ssaidi@eecs.umich.edu
8013825Ssaidi@eecs.umich.edutemplate<class Impl>
8023825Ssaidi@eecs.umich.eduvoid
8033825Ssaidi@eecs.umich.eduDefaultRename<Impl>::skidInsert(ThreadID tid)
8043825Ssaidi@eecs.umich.edu{
8053825Ssaidi@eecs.umich.edu    DynInstPtr inst = NULL;
8063825Ssaidi@eecs.umich.edu
8073825Ssaidi@eecs.umich.edu    while (!insts[tid].empty()) {
8083824Ssaidi@eecs.umich.edu        inst = insts[tid].front();
8093804Ssaidi@eecs.umich.edu
8103811Ssaidi@eecs.umich.edu        insts[tid].pop_front();
8113806Ssaidi@eecs.umich.edu
8123806Ssaidi@eecs.umich.edu        assert(tid == inst->threadNumber);
8133806Ssaidi@eecs.umich.edu
8143804Ssaidi@eecs.umich.edu        DPRINTF(Rename, "[tid:%i] Inserting [sn:%llu] PC: %s into Rename "
8153804Ssaidi@eecs.umich.edu                "skidBuffer\n", tid, inst->seqNum, inst->pcState());
8163806Ssaidi@eecs.umich.edu
8173806Ssaidi@eecs.umich.edu        ++renameSkidInsts;
8183806Ssaidi@eecs.umich.edu
8193823Ssaidi@eecs.umich.edu        skidBuffer[tid].push_back(inst);
8203823Ssaidi@eecs.umich.edu    }
8213833Ssaidi@eecs.umich.edu
8223833Ssaidi@eecs.umich.edu    if (skidBuffer[tid].size() > skidBufferMax)
8233823Ssaidi@eecs.umich.edu    {
8243823Ssaidi@eecs.umich.edu        typename InstQueue::iterator it;
8253823Ssaidi@eecs.umich.edu        warn("Skidbuffer contents:\n");
8263823Ssaidi@eecs.umich.edu        for (it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++)
8273823Ssaidi@eecs.umich.edu        {
8283823Ssaidi@eecs.umich.edu            warn("[tid:%i] %s [sn:%llu].\n", tid,
8293823Ssaidi@eecs.umich.edu                    (*it)->staticInst->disassemble(inst->instAddr()),
8303823Ssaidi@eecs.umich.edu                    (*it)->seqNum);
8313823Ssaidi@eecs.umich.edu        }
8323823Ssaidi@eecs.umich.edu        panic("Skidbuffer Exceeded Max Size");
8333823Ssaidi@eecs.umich.edu    }
8343823Ssaidi@eecs.umich.edu}
8353823Ssaidi@eecs.umich.edu
8363823Ssaidi@eecs.umich.edutemplate <class Impl>
8373823Ssaidi@eecs.umich.eduvoid
8383823Ssaidi@eecs.umich.eduDefaultRename<Impl>::sortInsts()
8393823Ssaidi@eecs.umich.edu{
8403823Ssaidi@eecs.umich.edu    int insts_from_decode = fromDecode->size;
8413823Ssaidi@eecs.umich.edu    for (int i = 0; i < insts_from_decode; ++i) {
8423823Ssaidi@eecs.umich.edu        const DynInstPtr &inst = fromDecode->insts[i];
8433823Ssaidi@eecs.umich.edu        insts[inst->threadNumber].push_back(inst);
8443824Ssaidi@eecs.umich.edu#if TRACING_ON
8453824Ssaidi@eecs.umich.edu        if (DTRACE(O3PipeView)) {
8463824Ssaidi@eecs.umich.edu            inst->renameTick = curTick() - inst->fetchTick;
8473824Ssaidi@eecs.umich.edu        }
8483823Ssaidi@eecs.umich.edu#endif
8493823Ssaidi@eecs.umich.edu    }
8503823Ssaidi@eecs.umich.edu}
8513823Ssaidi@eecs.umich.edu
8523823Ssaidi@eecs.umich.edutemplate<class Impl>
8533823Ssaidi@eecs.umich.edubool
8543823Ssaidi@eecs.umich.eduDefaultRename<Impl>::skidsEmpty()
8553823Ssaidi@eecs.umich.edu{
8563823Ssaidi@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
8573823Ssaidi@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
8583823Ssaidi@eecs.umich.edu
8593823Ssaidi@eecs.umich.edu    while (threads != end) {
8603823Ssaidi@eecs.umich.edu        ThreadID tid = *threads++;
8613823Ssaidi@eecs.umich.edu
8623823Ssaidi@eecs.umich.edu        if (!skidBuffer[tid].empty())
8633823Ssaidi@eecs.umich.edu            return false;
8643823Ssaidi@eecs.umich.edu    }
8653823Ssaidi@eecs.umich.edu
8663823Ssaidi@eecs.umich.edu    return true;
8673823Ssaidi@eecs.umich.edu}
8683823Ssaidi@eecs.umich.edu
8693823Ssaidi@eecs.umich.edutemplate<class Impl>
8703823Ssaidi@eecs.umich.eduvoid
8713823Ssaidi@eecs.umich.eduDefaultRename<Impl>::updateStatus()
8723823Ssaidi@eecs.umich.edu{
8733823Ssaidi@eecs.umich.edu    bool any_unblocking = false;
8743823Ssaidi@eecs.umich.edu
8753823Ssaidi@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
8763823Ssaidi@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
8773823Ssaidi@eecs.umich.edu
8783823Ssaidi@eecs.umich.edu    while (threads != end) {
8793823Ssaidi@eecs.umich.edu        ThreadID tid = *threads++;
8803823Ssaidi@eecs.umich.edu
8813823Ssaidi@eecs.umich.edu        if (renameStatus[tid] == Unblocking) {
8823823Ssaidi@eecs.umich.edu            any_unblocking = true;
8833823Ssaidi@eecs.umich.edu            break;
8843823Ssaidi@eecs.umich.edu        }
8853823Ssaidi@eecs.umich.edu    }
8863823Ssaidi@eecs.umich.edu
8873823Ssaidi@eecs.umich.edu    // Rename will have activity if it's unblocking.
8883823Ssaidi@eecs.umich.edu    if (any_unblocking) {
8893823Ssaidi@eecs.umich.edu        if (_status == Inactive) {
8903823Ssaidi@eecs.umich.edu            _status = Active;
8913823Ssaidi@eecs.umich.edu
8923823Ssaidi@eecs.umich.edu            DPRINTF(Activity, "Activating stage.\n");
8933823Ssaidi@eecs.umich.edu
8943823Ssaidi@eecs.umich.edu            cpu->activateStage(O3CPU::RenameIdx);
8953823Ssaidi@eecs.umich.edu        }
8963826Ssaidi@eecs.umich.edu    } else {
8973826Ssaidi@eecs.umich.edu        // If it's not unblocking, then rename will not have any internal
8983910Ssaidi@eecs.umich.edu        // activity.  Switch it to inactive.
8993826Ssaidi@eecs.umich.edu        if (_status == Active) {
9003823Ssaidi@eecs.umich.edu            _status = Inactive;
9013823Ssaidi@eecs.umich.edu            DPRINTF(Activity, "Deactivating stage.\n");
9023823Ssaidi@eecs.umich.edu
9033823Ssaidi@eecs.umich.edu            cpu->deactivateStage(O3CPU::RenameIdx);
9043826Ssaidi@eecs.umich.edu        }
9053826Ssaidi@eecs.umich.edu    }
9063833Ssaidi@eecs.umich.edu}
9073833Ssaidi@eecs.umich.edu
9083833Ssaidi@eecs.umich.edutemplate <class Impl>
9093833Ssaidi@eecs.umich.edubool
9103906Ssaidi@eecs.umich.eduDefaultRename<Impl>::block(ThreadID tid)
9113906Ssaidi@eecs.umich.edu{
9123906Ssaidi@eecs.umich.edu    DPRINTF(Rename, "[tid:%i] Blocking.\n", tid);
9133826Ssaidi@eecs.umich.edu
9143826Ssaidi@eecs.umich.edu    // Add the current inputs onto the skid buffer, so they can be
9153826Ssaidi@eecs.umich.edu    // reprocessed when this stage unblocks.
9163826Ssaidi@eecs.umich.edu    skidInsert(tid);
9173826Ssaidi@eecs.umich.edu
9183826Ssaidi@eecs.umich.edu    // Only signal backwards to block if the previous stages do not think
9193826Ssaidi@eecs.umich.edu    // rename is already blocked.
9203823Ssaidi@eecs.umich.edu    if (renameStatus[tid] != Blocked) {
9213823Ssaidi@eecs.umich.edu        // If resumeUnblocking is set, we unblocked during the squash,
9223833Ssaidi@eecs.umich.edu        // but now we're have unblocking status. We need to tell earlier
9233833Ssaidi@eecs.umich.edu        // stages to block.
9243833Ssaidi@eecs.umich.edu        if (resumeUnblocking || renameStatus[tid] != Unblocking) {
9253833Ssaidi@eecs.umich.edu            toDecode->renameBlock[tid] = true;
9263906Ssaidi@eecs.umich.edu            toDecode->renameUnblock[tid] = false;
9273906Ssaidi@eecs.umich.edu            wroteToTimeBuffer = true;
9283906Ssaidi@eecs.umich.edu        }
9293906Ssaidi@eecs.umich.edu
9303906Ssaidi@eecs.umich.edu        // Rename can not go from SerializeStall to Blocked, otherwise
9313906Ssaidi@eecs.umich.edu        // it would not know to complete the serialize stall.
9323826Ssaidi@eecs.umich.edu        if (renameStatus[tid] != SerializeStall) {
9333826Ssaidi@eecs.umich.edu            // Set status to Blocked.
9343826Ssaidi@eecs.umich.edu            renameStatus[tid] = Blocked;
9353823Ssaidi@eecs.umich.edu            return true;
9363823Ssaidi@eecs.umich.edu        }
9373823Ssaidi@eecs.umich.edu    }
9383823Ssaidi@eecs.umich.edu
9393823Ssaidi@eecs.umich.edu    return false;
9403823Ssaidi@eecs.umich.edu}
9413823Ssaidi@eecs.umich.edu
9423833Ssaidi@eecs.umich.edutemplate <class Impl>
9433833Ssaidi@eecs.umich.edubool
9443833Ssaidi@eecs.umich.eduDefaultRename<Impl>::unblock(ThreadID tid)
9453833Ssaidi@eecs.umich.edu{
9463833Ssaidi@eecs.umich.edu    DPRINTF(Rename, "[tid:%i] Trying to unblock.\n", tid);
9473833Ssaidi@eecs.umich.edu
9483833Ssaidi@eecs.umich.edu    // Rename is done unblocking if the skid buffer is empty.
9493833Ssaidi@eecs.umich.edu    if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) {
9503833Ssaidi@eecs.umich.edu
9513833Ssaidi@eecs.umich.edu        DPRINTF(Rename, "[tid:%i] Done unblocking.\n", tid);
9523833Ssaidi@eecs.umich.edu
9533833Ssaidi@eecs.umich.edu        toDecode->renameUnblock[tid] = true;
9543833Ssaidi@eecs.umich.edu        wroteToTimeBuffer = true;
9553833Ssaidi@eecs.umich.edu
9563833Ssaidi@eecs.umich.edu        renameStatus[tid] = Running;
9573833Ssaidi@eecs.umich.edu        return true;
9583833Ssaidi@eecs.umich.edu    }
9593833Ssaidi@eecs.umich.edu
9603833Ssaidi@eecs.umich.edu    return false;
9613833Ssaidi@eecs.umich.edu}
9623833Ssaidi@eecs.umich.edu
9633833Ssaidi@eecs.umich.edutemplate <class Impl>
9643833Ssaidi@eecs.umich.eduvoid
9653833Ssaidi@eecs.umich.eduDefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
9663833Ssaidi@eecs.umich.edu{
9673833Ssaidi@eecs.umich.edu    typename std::list<RenameHistory>::iterator hb_it =
9683910Ssaidi@eecs.umich.edu        historyBuffer[tid].begin();
9693833Ssaidi@eecs.umich.edu
9703833Ssaidi@eecs.umich.edu    // After a syscall squashes everything, the history buffer may be empty
9713833Ssaidi@eecs.umich.edu    // but the ROB may still be squashing instructions.
9723899Ssaidi@eecs.umich.edu    // Go through the most recent instructions, undoing the mappings
9733899Ssaidi@eecs.umich.edu    // they did and freeing up the registers.
9743899Ssaidi@eecs.umich.edu    while (!historyBuffer[tid].empty() &&
9753899Ssaidi@eecs.umich.edu           hb_it->instSeqNum > squashed_seq_num) {
9763899Ssaidi@eecs.umich.edu        assert(hb_it != historyBuffer[tid].end());
9773899Ssaidi@eecs.umich.edu
9783899Ssaidi@eecs.umich.edu        DPRINTF(Rename, "[tid:%i] Removing history entry with sequence "
9793899Ssaidi@eecs.umich.edu                "number %i.\n", tid, hb_it->instSeqNum);
9803899Ssaidi@eecs.umich.edu
9813899Ssaidi@eecs.umich.edu        // Undo the rename mapping only if it was really a change.
9823899Ssaidi@eecs.umich.edu        // Special regs that are not really renamed (like misc regs
9833899Ssaidi@eecs.umich.edu        // and the zero reg) can be recognized because the new mapping
9843899Ssaidi@eecs.umich.edu        // is the same as the old one.  While it would be merely a
9853899Ssaidi@eecs.umich.edu        // waste of time to update the rename table, we definitely
9863899Ssaidi@eecs.umich.edu        // don't want to put these on the free list.
9873899Ssaidi@eecs.umich.edu        if (hb_it->newPhysReg != hb_it->prevPhysReg) {
9883899Ssaidi@eecs.umich.edu            // Tell the rename map to set the architected register to the
9893899Ssaidi@eecs.umich.edu            // previous physical register that it was renamed to.
9903899Ssaidi@eecs.umich.edu            renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
9913899Ssaidi@eecs.umich.edu
9923899Ssaidi@eecs.umich.edu            // Put the renamed physical register back on the free list.
9933899Ssaidi@eecs.umich.edu            freeList->addReg(hb_it->newPhysReg);
9943899Ssaidi@eecs.umich.edu        }
9953899Ssaidi@eecs.umich.edu
9963899Ssaidi@eecs.umich.edu        // Notify potential listeners that the register mapping needs to be
9973899Ssaidi@eecs.umich.edu        // removed because the instruction it was mapped to got squashed. Note
9983910Ssaidi@eecs.umich.edu        // that this is done before hb_it is incremented.
9993899Ssaidi@eecs.umich.edu        ppSquashInRename->notify(std::make_pair(hb_it->instSeqNum,
10003899Ssaidi@eecs.umich.edu                                                hb_it->newPhysReg));
10013899Ssaidi@eecs.umich.edu
10023833Ssaidi@eecs.umich.edu        historyBuffer[tid].erase(hb_it++);
10033823Ssaidi@eecs.umich.edu
10043823Ssaidi@eecs.umich.edu        ++renameUndoneMaps;
10053823Ssaidi@eecs.umich.edu    }
10063823Ssaidi@eecs.umich.edu
10073823Ssaidi@eecs.umich.edu    // Check if we need to change vector renaming mode after squashing
10083823Ssaidi@eecs.umich.edu    cpu->switchRenameMode(tid, freeList);
10093823Ssaidi@eecs.umich.edu}
10103806Ssaidi@eecs.umich.edu
10113806Ssaidi@eecs.umich.edutemplate<class Impl>
10123806Ssaidi@eecs.umich.eduvoid
10133806Ssaidi@eecs.umich.eduDefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
10143806Ssaidi@eecs.umich.edu{
10153823Ssaidi@eecs.umich.edu    DPRINTF(Rename, "[tid:%i] Removing a committed instruction from the "
10163823Ssaidi@eecs.umich.edu            "history buffer %u (size=%i), until [sn:%llu].\n",
10173823Ssaidi@eecs.umich.edu            tid, tid, historyBuffer[tid].size(), inst_seq_num);
10183823Ssaidi@eecs.umich.edu
10193826Ssaidi@eecs.umich.edu    typename std::list<RenameHistory>::iterator hb_it =
10203826Ssaidi@eecs.umich.edu        historyBuffer[tid].end();
10213826Ssaidi@eecs.umich.edu
10223826Ssaidi@eecs.umich.edu    --hb_it;
10233826Ssaidi@eecs.umich.edu
10243826Ssaidi@eecs.umich.edu    if (historyBuffer[tid].empty()) {
10253863Ssaidi@eecs.umich.edu        DPRINTF(Rename, "[tid:%i] History buffer is empty.\n", tid);
10263863Ssaidi@eecs.umich.edu        return;
10273863Ssaidi@eecs.umich.edu    } else if (hb_it->instSeqNum > inst_seq_num) {
10283826Ssaidi@eecs.umich.edu        DPRINTF(Rename, "[tid:%i] [sn:%llu] "
10293826Ssaidi@eecs.umich.edu                "Old sequence number encountered. "
10303825Ssaidi@eecs.umich.edu                "Ensure that a syscall happened recently.\n",
10313823Ssaidi@eecs.umich.edu                tid,inst_seq_num);
10323823Ssaidi@eecs.umich.edu        return;
10333823Ssaidi@eecs.umich.edu    }
10343823Ssaidi@eecs.umich.edu
10353823Ssaidi@eecs.umich.edu    // Commit all the renames up until (and including) the committed sequence
10363823Ssaidi@eecs.umich.edu    // number. Some or even all of the committed instructions may not have
10373823Ssaidi@eecs.umich.edu    // rename histories if they did not have destination registers that were
10383823Ssaidi@eecs.umich.edu    // renamed.
10393823Ssaidi@eecs.umich.edu    while (!historyBuffer[tid].empty() &&
10403823Ssaidi@eecs.umich.edu           hb_it != historyBuffer[tid].end() &&
10413823Ssaidi@eecs.umich.edu           hb_it->instSeqNum <= inst_seq_num) {
10423823Ssaidi@eecs.umich.edu
10433823Ssaidi@eecs.umich.edu        DPRINTF(Rename, "[tid:%i] Freeing up older rename of reg %i (%s), "
10443823Ssaidi@eecs.umich.edu                "[sn:%llu].\n",
10453823Ssaidi@eecs.umich.edu                tid, hb_it->prevPhysReg->index(),
10463823Ssaidi@eecs.umich.edu                hb_it->prevPhysReg->className(),
10473823Ssaidi@eecs.umich.edu                hb_it->instSeqNum);
10483823Ssaidi@eecs.umich.edu
10493823Ssaidi@eecs.umich.edu        // Don't free special phys regs like misc and zero regs, which
10503824Ssaidi@eecs.umich.edu        // can be recognized because the new mapping is the same as
10513825Ssaidi@eecs.umich.edu        // the old one.
10523824Ssaidi@eecs.umich.edu        if (hb_it->newPhysReg != hb_it->prevPhysReg) {
10533824Ssaidi@eecs.umich.edu            freeList->addReg(hb_it->prevPhysReg);
10543824Ssaidi@eecs.umich.edu        }
10553823Ssaidi@eecs.umich.edu
10563823Ssaidi@eecs.umich.edu        ++renameCommittedMaps;
10573823Ssaidi@eecs.umich.edu
10583823Ssaidi@eecs.umich.edu        historyBuffer[tid].erase(hb_it--);
10593823Ssaidi@eecs.umich.edu    }
10603823Ssaidi@eecs.umich.edu}
10613823Ssaidi@eecs.umich.edu
10623823Ssaidi@eecs.umich.edutemplate <class Impl>
10633823Ssaidi@eecs.umich.eduinline void
10643823Ssaidi@eecs.umich.eduDefaultRename<Impl>::renameSrcRegs(const DynInstPtr &inst, ThreadID tid)
10653823Ssaidi@eecs.umich.edu{
10663823Ssaidi@eecs.umich.edu    ThreadContext *tc = inst->tcBase();
10673823Ssaidi@eecs.umich.edu    RenameMap *map = renameMap[tid];
10683823Ssaidi@eecs.umich.edu    unsigned num_src_regs = inst->numSrcRegs();
10693823Ssaidi@eecs.umich.edu
10703823Ssaidi@eecs.umich.edu    // Get the architectual register numbers from the source and
10713823Ssaidi@eecs.umich.edu    // operands, and redirect them to the right physical register.
10723823Ssaidi@eecs.umich.edu    for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
10733823Ssaidi@eecs.umich.edu        const RegId& src_reg = inst->srcRegIdx(src_idx);
10743823Ssaidi@eecs.umich.edu        PhysRegIdPtr renamed_reg;
10753823Ssaidi@eecs.umich.edu
10763823Ssaidi@eecs.umich.edu        renamed_reg = map->lookup(tc->flattenRegId(src_reg));
10773823Ssaidi@eecs.umich.edu        switch (src_reg.classValue()) {
10783823Ssaidi@eecs.umich.edu          case IntRegClass:
10793823Ssaidi@eecs.umich.edu            intRenameLookups++;
10803823Ssaidi@eecs.umich.edu            break;
10813823Ssaidi@eecs.umich.edu          case FloatRegClass:
10823823Ssaidi@eecs.umich.edu            fpRenameLookups++;
10833823Ssaidi@eecs.umich.edu            break;
10843823Ssaidi@eecs.umich.edu          case VecRegClass:
10853823Ssaidi@eecs.umich.edu          case VecElemClass:
10863823Ssaidi@eecs.umich.edu            vecRenameLookups++;
10873823Ssaidi@eecs.umich.edu            break;
10883823Ssaidi@eecs.umich.edu          case VecPredRegClass:
10893823Ssaidi@eecs.umich.edu            vecPredRenameLookups++;
10903823Ssaidi@eecs.umich.edu            break;
10913823Ssaidi@eecs.umich.edu          case CCRegClass:
10923823Ssaidi@eecs.umich.edu          case MiscRegClass:
10933823Ssaidi@eecs.umich.edu            break;
10943823Ssaidi@eecs.umich.edu
10953823Ssaidi@eecs.umich.edu          default:
10963823Ssaidi@eecs.umich.edu            panic("Invalid register class: %d.", src_reg.classValue());
10973823Ssaidi@eecs.umich.edu        }
10983823Ssaidi@eecs.umich.edu
10993823Ssaidi@eecs.umich.edu        DPRINTF(Rename,
11003823Ssaidi@eecs.umich.edu                "[tid:%i] "
11013823Ssaidi@eecs.umich.edu                "Looking up %s arch reg %i, got phys reg %i (%s)\n",
11023823Ssaidi@eecs.umich.edu                tid, src_reg.className(),
11033825Ssaidi@eecs.umich.edu                src_reg.index(), renamed_reg->index(),
11043825Ssaidi@eecs.umich.edu                renamed_reg->className());
11053825Ssaidi@eecs.umich.edu
11063825Ssaidi@eecs.umich.edu        inst->renameSrcReg(src_idx, renamed_reg);
11073823Ssaidi@eecs.umich.edu
11083823Ssaidi@eecs.umich.edu        // See if the register is ready or not.
11093823Ssaidi@eecs.umich.edu        if (scoreboard->getReg(renamed_reg)) {
11103823Ssaidi@eecs.umich.edu            DPRINTF(Rename,
11113826Ssaidi@eecs.umich.edu                    "[tid:%i] "
11123826Ssaidi@eecs.umich.edu                    "Register %d (flat: %d) (%s) is ready.\n",
11133906Ssaidi@eecs.umich.edu                    tid, renamed_reg->index(), renamed_reg->flatIndex(),
11143906Ssaidi@eecs.umich.edu                    renamed_reg->className());
11153906Ssaidi@eecs.umich.edu
11163826Ssaidi@eecs.umich.edu            inst->markSrcRegReady(src_idx);
11173826Ssaidi@eecs.umich.edu        } else {
11183826Ssaidi@eecs.umich.edu            DPRINTF(Rename,
11193826Ssaidi@eecs.umich.edu                    "[tid:%i] "
11203826Ssaidi@eecs.umich.edu                    "Register %d (flat: %d) (%s) is not ready.\n",
11213826Ssaidi@eecs.umich.edu                    tid, renamed_reg->index(), renamed_reg->flatIndex(),
11223826Ssaidi@eecs.umich.edu                    renamed_reg->className());
11233826Ssaidi@eecs.umich.edu        }
11243826Ssaidi@eecs.umich.edu
11253826Ssaidi@eecs.umich.edu        ++renameRenameLookups;
11263826Ssaidi@eecs.umich.edu    }
11273826Ssaidi@eecs.umich.edu}
11283826Ssaidi@eecs.umich.edu
11293826Ssaidi@eecs.umich.edutemplate <class Impl>
11303826Ssaidi@eecs.umich.eduinline void
11313826Ssaidi@eecs.umich.eduDefaultRename<Impl>::renameDestRegs(const DynInstPtr &inst, ThreadID tid)
11323826Ssaidi@eecs.umich.edu{
11333826Ssaidi@eecs.umich.edu    ThreadContext *tc = inst->tcBase();
11343826Ssaidi@eecs.umich.edu    RenameMap *map = renameMap[tid];
11353826Ssaidi@eecs.umich.edu    unsigned num_dest_regs = inst->numDestRegs();
11363826Ssaidi@eecs.umich.edu
11373826Ssaidi@eecs.umich.edu    // Rename the destination registers.
11383826Ssaidi@eecs.umich.edu    for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
11393826Ssaidi@eecs.umich.edu        const RegId& dest_reg = inst->destRegIdx(dest_idx);
11403826Ssaidi@eecs.umich.edu        typename RenameMap::RenameInfo rename_result;
11413826Ssaidi@eecs.umich.edu
11423826Ssaidi@eecs.umich.edu        RegId flat_dest_regid = tc->flattenRegId(dest_reg);
11433826Ssaidi@eecs.umich.edu
11443826Ssaidi@eecs.umich.edu        rename_result = map->rename(flat_dest_regid);
11453826Ssaidi@eecs.umich.edu
11463826Ssaidi@eecs.umich.edu        inst->flattenDestReg(dest_idx, flat_dest_regid);
11473826Ssaidi@eecs.umich.edu
11483826Ssaidi@eecs.umich.edu        // Mark Scoreboard entry as not ready
11493826Ssaidi@eecs.umich.edu        scoreboard->unsetReg(rename_result.first);
11503863Ssaidi@eecs.umich.edu
11513863Ssaidi@eecs.umich.edu        DPRINTF(Rename,
11523863Ssaidi@eecs.umich.edu                "[tid:%i] "
11533863Ssaidi@eecs.umich.edu                "Renaming arch reg %i (%s) to physical reg %i (%i).\n",
11543863Ssaidi@eecs.umich.edu                tid, dest_reg.index(), dest_reg.className(),
11553863Ssaidi@eecs.umich.edu                rename_result.first->index(),
11563863Ssaidi@eecs.umich.edu                rename_result.first->flatIndex());
11573863Ssaidi@eecs.umich.edu
11583863Ssaidi@eecs.umich.edu        // Record the rename information so that a history can be kept.
11593863Ssaidi@eecs.umich.edu        RenameHistory hb_entry(inst->seqNum, flat_dest_regid,
11603863Ssaidi@eecs.umich.edu                               rename_result.first,
11613863Ssaidi@eecs.umich.edu                               rename_result.second);
11623863Ssaidi@eecs.umich.edu
11633863Ssaidi@eecs.umich.edu        historyBuffer[tid].push_front(hb_entry);
11643863Ssaidi@eecs.umich.edu
11653863Ssaidi@eecs.umich.edu        DPRINTF(Rename, "[tid:%i] [sn:%llu] "
11663863Ssaidi@eecs.umich.edu                "Adding instruction to history buffer (size=%i).\n",
11673863Ssaidi@eecs.umich.edu                tid,(*historyBuffer[tid].begin()).instSeqNum,
11683863Ssaidi@eecs.umich.edu                historyBuffer[tid].size());
11693863Ssaidi@eecs.umich.edu
11703863Ssaidi@eecs.umich.edu        // Tell the instruction to rename the appropriate destination
11713863Ssaidi@eecs.umich.edu        // register (dest_idx) to the new physical register
11723863Ssaidi@eecs.umich.edu        // (rename_result.first), and record the previous physical
11733863Ssaidi@eecs.umich.edu        // register that the same logical register was renamed to
11743863Ssaidi@eecs.umich.edu        // (rename_result.second).
11753863Ssaidi@eecs.umich.edu        inst->renameDestReg(dest_idx,
11763863Ssaidi@eecs.umich.edu                            rename_result.first,
11773863Ssaidi@eecs.umich.edu                            rename_result.second);
11783863Ssaidi@eecs.umich.edu
11793863Ssaidi@eecs.umich.edu        ++renameRenamedOperands;
11803863Ssaidi@eecs.umich.edu    }
11813863Ssaidi@eecs.umich.edu}
11823863Ssaidi@eecs.umich.edu
11833863Ssaidi@eecs.umich.edutemplate <class Impl>
11843863Ssaidi@eecs.umich.eduinline int
11853823Ssaidi@eecs.umich.eduDefaultRename<Impl>::calcFreeROBEntries(ThreadID tid)
11863823Ssaidi@eecs.umich.edu{
11873906Ssaidi@eecs.umich.edu    int num_free = freeEntries[tid].robEntries -
11883906Ssaidi@eecs.umich.edu                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
11893906Ssaidi@eecs.umich.edu
11903826Ssaidi@eecs.umich.edu    //DPRINTF(Rename,"[tid:%i] %i rob free\n",tid,num_free);
11913826Ssaidi@eecs.umich.edu
11923826Ssaidi@eecs.umich.edu    return num_free;
11933823Ssaidi@eecs.umich.edu}
11943823Ssaidi@eecs.umich.edu
11953823Ssaidi@eecs.umich.edutemplate <class Impl>
11963823Ssaidi@eecs.umich.eduinline int
11973823Ssaidi@eecs.umich.eduDefaultRename<Impl>::calcFreeIQEntries(ThreadID tid)
11983823Ssaidi@eecs.umich.edu{
11993823Ssaidi@eecs.umich.edu    int num_free = freeEntries[tid].iqEntries -
12003863Ssaidi@eecs.umich.edu                  (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched);
12013863Ssaidi@eecs.umich.edu
12023863Ssaidi@eecs.umich.edu    //DPRINTF(Rename,"[tid:%i] %i iq free\n",tid,num_free);
12033863Ssaidi@eecs.umich.edu
12043863Ssaidi@eecs.umich.edu    return num_free;
12053863Ssaidi@eecs.umich.edu}
12063863Ssaidi@eecs.umich.edu
12073863Ssaidi@eecs.umich.edutemplate <class Impl>
12083863Ssaidi@eecs.umich.eduinline int
12093863Ssaidi@eecs.umich.eduDefaultRename<Impl>::calcFreeLQEntries(ThreadID tid)
12103863Ssaidi@eecs.umich.edu{
12113863Ssaidi@eecs.umich.edu        int num_free = freeEntries[tid].lqEntries -
12123863Ssaidi@eecs.umich.edu                                  (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ);
12133863Ssaidi@eecs.umich.edu        DPRINTF(Rename,
12143863Ssaidi@eecs.umich.edu                "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, "
12153863Ssaidi@eecs.umich.edu                "loads dispatchedToLQ: %d\n",
12163863Ssaidi@eecs.umich.edu                freeEntries[tid].lqEntries, loadsInProgress[tid],
12173863Ssaidi@eecs.umich.edu                fromIEW->iewInfo[tid].dispatchedToLQ);
12183863Ssaidi@eecs.umich.edu        return num_free;
12193863Ssaidi@eecs.umich.edu}
12203863Ssaidi@eecs.umich.edu
12213863Ssaidi@eecs.umich.edutemplate <class Impl>
12223863Ssaidi@eecs.umich.eduinline int
12233863Ssaidi@eecs.umich.eduDefaultRename<Impl>::calcFreeSQEntries(ThreadID tid)
12243863Ssaidi@eecs.umich.edu{
12253863Ssaidi@eecs.umich.edu        int num_free = freeEntries[tid].sqEntries -
12263863Ssaidi@eecs.umich.edu                                  (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ);
12273863Ssaidi@eecs.umich.edu        DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, storesInProgress: %d, "
12283863Ssaidi@eecs.umich.edu                "stores dispatchedToSQ: %d\n", freeEntries[tid].sqEntries,
12293863Ssaidi@eecs.umich.edu                storesInProgress[tid], fromIEW->iewInfo[tid].dispatchedToSQ);
12303863Ssaidi@eecs.umich.edu        return num_free;
12313863Ssaidi@eecs.umich.edu}
12323863Ssaidi@eecs.umich.edu
12333863Ssaidi@eecs.umich.edutemplate <class Impl>
12343823Ssaidi@eecs.umich.eduunsigned
12353823Ssaidi@eecs.umich.eduDefaultRename<Impl>::validInsts()
12363823Ssaidi@eecs.umich.edu{
12373823Ssaidi@eecs.umich.edu    unsigned inst_count = 0;
12383823Ssaidi@eecs.umich.edu
12393823Ssaidi@eecs.umich.edu    for (int i=0; i<fromDecode->size; i++) {
12403823Ssaidi@eecs.umich.edu        if (!fromDecode->insts[i]->isSquashed())
12413806Ssaidi@eecs.umich.edu            inst_count++;
12423806Ssaidi@eecs.umich.edu    }
12433804Ssaidi@eecs.umich.edu
12443804Ssaidi@eecs.umich.edu    return inst_count;
12453804Ssaidi@eecs.umich.edu}
12463804Ssaidi@eecs.umich.edu
12473804Ssaidi@eecs.umich.edutemplate <class Impl>
12483804Ssaidi@eecs.umich.eduvoid
12493804Ssaidi@eecs.umich.eduDefaultRename<Impl>::readStallSignals(ThreadID tid)
12503804Ssaidi@eecs.umich.edu{
12513804Ssaidi@eecs.umich.edu    if (fromIEW->iewBlock[tid]) {
12523804Ssaidi@eecs.umich.edu        stalls[tid].iew = true;
12533804Ssaidi@eecs.umich.edu    }
12543804Ssaidi@eecs.umich.edu
12553804Ssaidi@eecs.umich.edu    if (fromIEW->iewUnblock[tid]) {
12563804Ssaidi@eecs.umich.edu        assert(stalls[tid].iew);
12573804Ssaidi@eecs.umich.edu        stalls[tid].iew = false;
12583804Ssaidi@eecs.umich.edu    }
12593804Ssaidi@eecs.umich.edu}
12603804Ssaidi@eecs.umich.edu
12613804Ssaidi@eecs.umich.edutemplate <class Impl>
12623804Ssaidi@eecs.umich.edubool
12633804Ssaidi@eecs.umich.eduDefaultRename<Impl>::checkStall(ThreadID tid)
12643804Ssaidi@eecs.umich.edu{
12653804Ssaidi@eecs.umich.edu    bool ret_val = false;
12663804Ssaidi@eecs.umich.edu
12673804Ssaidi@eecs.umich.edu    if (stalls[tid].iew) {
12683804Ssaidi@eecs.umich.edu        DPRINTF(Rename,"[tid:%i] Stall from IEW stage detected.\n", tid);
12693804Ssaidi@eecs.umich.edu        ret_val = true;
12703804Ssaidi@eecs.umich.edu    } else if (calcFreeROBEntries(tid) <= 0) {
12713804Ssaidi@eecs.umich.edu        DPRINTF(Rename,"[tid:%i] Stall: ROB has 0 free entries.\n", tid);
12723804Ssaidi@eecs.umich.edu        ret_val = true;
12733804Ssaidi@eecs.umich.edu    } else if (calcFreeIQEntries(tid) <= 0) {
12743804Ssaidi@eecs.umich.edu        DPRINTF(Rename,"[tid:%i] Stall: IQ has 0 free entries.\n", tid);
12753804Ssaidi@eecs.umich.edu        ret_val = true;
12763804Ssaidi@eecs.umich.edu    } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) {
12773804Ssaidi@eecs.umich.edu        DPRINTF(Rename,"[tid:%i] Stall: LSQ has 0 free entries.\n", tid);
12783804Ssaidi@eecs.umich.edu        ret_val = true;
12793804Ssaidi@eecs.umich.edu    } else if (renameMap[tid]->numFreeEntries() <= 0) {
12803804Ssaidi@eecs.umich.edu        DPRINTF(Rename,"[tid:%i] Stall: RenameMap has 0 free entries.\n", tid);
12813804Ssaidi@eecs.umich.edu        ret_val = true;
12823804Ssaidi@eecs.umich.edu    } else if (renameStatus[tid] == SerializeStall &&
12833804Ssaidi@eecs.umich.edu               (!emptyROB[tid] || instsInProgress[tid])) {
12843804Ssaidi@eecs.umich.edu        DPRINTF(Rename,"[tid:%i] Stall: Serialize stall and ROB is not "
12853804Ssaidi@eecs.umich.edu                "empty.\n",
12863804Ssaidi@eecs.umich.edu                tid);
12873804Ssaidi@eecs.umich.edu        ret_val = true;
12883804Ssaidi@eecs.umich.edu    }
12893804Ssaidi@eecs.umich.edu
12903804Ssaidi@eecs.umich.edu    return ret_val;
12913804Ssaidi@eecs.umich.edu}
12923804Ssaidi@eecs.umich.edu
12933804Ssaidi@eecs.umich.edutemplate <class Impl>
12943804Ssaidi@eecs.umich.eduvoid
12953804Ssaidi@eecs.umich.eduDefaultRename<Impl>::readFreeEntries(ThreadID tid)
12963804Ssaidi@eecs.umich.edu{
12973804Ssaidi@eecs.umich.edu    if (fromIEW->iewInfo[tid].usedIQ)
1298        freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries;
1299
1300    if (fromIEW->iewInfo[tid].usedLSQ) {
1301        freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries;
1302        freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries;
1303    }
1304
1305    if (fromCommit->commitInfo[tid].usedROB) {
1306        freeEntries[tid].robEntries =
1307            fromCommit->commitInfo[tid].freeROBEntries;
1308        emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB;
1309    }
1310
1311    DPRINTF(Rename, "[tid:%i] Free IQ: %i, Free ROB: %i, "
1312                    "Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i %i)\n",
1313            tid,
1314            freeEntries[tid].iqEntries,
1315            freeEntries[tid].robEntries,
1316            freeEntries[tid].lqEntries,
1317            freeEntries[tid].sqEntries,
1318            renameMap[tid]->numFreeEntries(),
1319            renameMap[tid]->numFreeIntEntries(),
1320            renameMap[tid]->numFreeFloatEntries(),
1321            renameMap[tid]->numFreeVecEntries(),
1322            renameMap[tid]->numFreePredEntries(),
1323            renameMap[tid]->numFreeCCEntries());
1324
1325    DPRINTF(Rename, "[tid:%i] %i instructions not yet in ROB\n",
1326            tid, instsInProgress[tid]);
1327}
1328
1329template <class Impl>
1330bool
1331DefaultRename<Impl>::checkSignalsAndUpdate(ThreadID tid)
1332{
1333    // Check if there's a squash signal, squash if there is
1334    // Check stall signals, block if necessary.
1335    // If status was blocked
1336    //     check if stall conditions have passed
1337    //         if so then go to unblocking
1338    // If status was Squashing
1339    //     check if squashing is not high.  Switch to running this cycle.
1340    // If status was serialize stall
1341    //     check if ROB is empty and no insts are in flight to the ROB
1342
1343    readFreeEntries(tid);
1344    readStallSignals(tid);
1345
1346    if (fromCommit->commitInfo[tid].squash) {
1347        DPRINTF(Rename, "[tid:%i] Squashing instructions due to squash from "
1348                "commit.\n", tid);
1349
1350        squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
1351
1352        return true;
1353    }
1354
1355    if (checkStall(tid)) {
1356        return block(tid);
1357    }
1358
1359    if (renameStatus[tid] == Blocked) {
1360        DPRINTF(Rename, "[tid:%i] Done blocking, switching to unblocking.\n",
1361                tid);
1362
1363        renameStatus[tid] = Unblocking;
1364
1365        unblock(tid);
1366
1367        return true;
1368    }
1369
1370    if (renameStatus[tid] == Squashing) {
1371        // Switch status to running if rename isn't being told to block or
1372        // squash this cycle.
1373        if (resumeSerialize) {
1374            DPRINTF(Rename,
1375                    "[tid:%i] Done squashing, switching to serialize.\n", tid);
1376
1377            renameStatus[tid] = SerializeStall;
1378            return true;
1379        } else if (resumeUnblocking) {
1380            DPRINTF(Rename,
1381                    "[tid:%i] Done squashing, switching to unblocking.\n",
1382                    tid);
1383            renameStatus[tid] = Unblocking;
1384            return true;
1385        } else {
1386            DPRINTF(Rename, "[tid:%i] Done squashing, switching to running.\n",
1387                    tid);
1388            renameStatus[tid] = Running;
1389            return false;
1390        }
1391    }
1392
1393    if (renameStatus[tid] == SerializeStall) {
1394        // Stall ends once the ROB is free.
1395        DPRINTF(Rename, "[tid:%i] Done with serialize stall, switching to "
1396                "unblocking.\n", tid);
1397
1398        DynInstPtr serial_inst = serializeInst[tid];
1399
1400        renameStatus[tid] = Unblocking;
1401
1402        unblock(tid);
1403
1404        DPRINTF(Rename, "[tid:%i] Processing instruction [%lli] with "
1405                "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState());
1406
1407        // Put instruction into queue here.
1408        serial_inst->clearSerializeBefore();
1409
1410        if (!skidBuffer[tid].empty()) {
1411            skidBuffer[tid].push_front(serial_inst);
1412        } else {
1413            insts[tid].push_front(serial_inst);
1414        }
1415
1416        DPRINTF(Rename, "[tid:%i] Instruction must be processed by rename."
1417                " Adding to front of list.\n", tid);
1418
1419        serializeInst[tid] = NULL;
1420
1421        return true;
1422    }
1423
1424    // If we've reached this point, we have not gotten any signals that
1425    // cause rename to change its status.  Rename remains the same as before.
1426    return false;
1427}
1428
1429template<class Impl>
1430void
1431DefaultRename<Impl>::serializeAfter(InstQueue &inst_list, ThreadID tid)
1432{
1433    if (inst_list.empty()) {
1434        // Mark a bit to say that I must serialize on the next instruction.
1435        serializeOnNextInst[tid] = true;
1436        return;
1437    }
1438
1439    // Set the next instruction as serializing.
1440    inst_list.front()->setSerializeBefore();
1441}
1442
1443template <class Impl>
1444inline void
1445DefaultRename<Impl>::incrFullStat(const FullSource &source)
1446{
1447    switch (source) {
1448      case ROB:
1449        ++renameROBFullEvents;
1450        break;
1451      case IQ:
1452        ++renameIQFullEvents;
1453        break;
1454      case LQ:
1455        ++renameLQFullEvents;
1456        break;
1457      case SQ:
1458        ++renameSQFullEvents;
1459        break;
1460      default:
1461        panic("Rename full stall stat should be incremented for a reason!");
1462        break;
1463    }
1464}
1465
1466template <class Impl>
1467void
1468DefaultRename<Impl>::dumpHistory()
1469{
1470    typename std::list<RenameHistory>::iterator buf_it;
1471
1472    for (ThreadID tid = 0; tid < numThreads; tid++) {
1473
1474        buf_it = historyBuffer[tid].begin();
1475
1476        while (buf_it != historyBuffer[tid].end()) {
1477            cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:"
1478                    " %i[%s] Old phys reg: %i[%s]\n",
1479                    (*buf_it).instSeqNum,
1480                    (*buf_it).archReg.className(),
1481                    (*buf_it).archReg.index(),
1482                    (*buf_it).newPhysReg->index(),
1483                    (*buf_it).newPhysReg->className(),
1484                    (*buf_it).prevPhysReg->index(),
1485                    (*buf_it).prevPhysReg->className());
1486
1487            buf_it++;
1488        }
1489    }
1490}
1491
1492#endif//__CPU_O3_RENAME_IMPL_HH__
1493