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