rename_impl.hh revision 2336
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 29955SN/A#include <list> 302665Ssaidi@eecs.umich.edu 312665Ssaidi@eecs.umich.edu#include "config/full_system.hh" 325863Snate@binkert.org#include "cpu/o3/rename.hh" 33955SN/A 34955SN/Ausing namespace std; 35955SN/A 36955SN/Atemplate <class Impl> 37955SN/ADefaultRename<Impl>::DefaultRename(Params *params) 388878Ssteve.reinhardt@amd.com : iewToRenameDelay(params->iewToRenameDelay), 392632Sstever@eecs.umich.edu decodeToRenameDelay(params->decodeToRenameDelay), 408878Ssteve.reinhardt@amd.com commitToRenameDelay(params->commitToRenameDelay), 412632Sstever@eecs.umich.edu renameWidth(params->renameWidth), 42955SN/A commitWidth(params->commitWidth), 438878Ssteve.reinhardt@amd.com numThreads(params->numberOfThreads) 442632Sstever@eecs.umich.edu{ 452761Sstever@eecs.umich.edu _status = Inactive; 462632Sstever@eecs.umich.edu 472632Sstever@eecs.umich.edu for (int i=0; i< numThreads; i++) { 482632Sstever@eecs.umich.edu renameStatus[i] = Idle; 492761Sstever@eecs.umich.edu 502761Sstever@eecs.umich.edu freeEntries[i].iqEntries = 0; 512761Sstever@eecs.umich.edu freeEntries[i].lsqEntries = 0; 528878Ssteve.reinhardt@amd.com freeEntries[i].robEntries = 0; 538878Ssteve.reinhardt@amd.com 542761Sstever@eecs.umich.edu stalls[i].iew = false; 552761Sstever@eecs.umich.edu stalls[i].commit = false; 562761Sstever@eecs.umich.edu serializeInst[i] = NULL; 572761Sstever@eecs.umich.edu 582761Sstever@eecs.umich.edu instsInProgress[i] = 0; 598878Ssteve.reinhardt@amd.com 608878Ssteve.reinhardt@amd.com emptyROB[i] = true; 612632Sstever@eecs.umich.edu 622632Sstever@eecs.umich.edu serializeOnNextInst[i] = false; 638878Ssteve.reinhardt@amd.com } 648878Ssteve.reinhardt@amd.com 652632Sstever@eecs.umich.edu // @todo: Make into a parameter. 66955SN/A skidBufferMax = (2 * (iewToRenameDelay * params->decodeWidth)) + renameWidth; 67955SN/A} 68955SN/A 695863Snate@binkert.orgtemplate <class Impl> 705863Snate@binkert.orgstd::string 715863Snate@binkert.orgDefaultRename<Impl>::name() const 725863Snate@binkert.org{ 735863Snate@binkert.org return cpu->name() + ".rename"; 745863Snate@binkert.org} 755863Snate@binkert.org 765863Snate@binkert.orgtemplate <class Impl> 775863Snate@binkert.orgvoid 785863Snate@binkert.orgDefaultRename<Impl>::regStats() 795863Snate@binkert.org{ 808878Ssteve.reinhardt@amd.com renameSquashCycles 815863Snate@binkert.org .name(name() + ".RENAME:SquashCycles") 825863Snate@binkert.org .desc("Number of cycles rename is squashing") 835863Snate@binkert.org .prereq(renameSquashCycles); 845863Snate@binkert.org renameIdleCycles 855863Snate@binkert.org .name(name() + ".RENAME:IdleCycles") 865863Snate@binkert.org .desc("Number of cycles rename is idle") 875863Snate@binkert.org .prereq(renameIdleCycles); 885863Snate@binkert.org renameBlockCycles 895863Snate@binkert.org .name(name() + ".RENAME:BlockCycles") 905863Snate@binkert.org .desc("Number of cycles rename is blocking") 915863Snate@binkert.org .prereq(renameBlockCycles); 925863Snate@binkert.org renameSerializeStallCycles 935863Snate@binkert.org .name(name() + ".RENAME:serializeStallCycles") 945863Snate@binkert.org .desc("count of cycles rename stalled for serializing inst") 955863Snate@binkert.org .flags(Stats::total); 968878Ssteve.reinhardt@amd.com renameRunCycles 975863Snate@binkert.org .name(name() + ".RENAME:RunCycles") 985863Snate@binkert.org .desc("Number of cycles rename is running") 995863Snate@binkert.org .prereq(renameIdleCycles); 1006654Snate@binkert.org renameUnblockCycles 101955SN/A .name(name() + ".RENAME:UnblockCycles") 1025396Ssaidi@eecs.umich.edu .desc("Number of cycles rename is unblocking") 1035863Snate@binkert.org .prereq(renameUnblockCycles); 1045863Snate@binkert.org renameRenamedInsts 1054202Sbinkertn@umich.edu .name(name() + ".RENAME:RenamedInsts") 1065863Snate@binkert.org .desc("Number of instructions processed by rename") 1075863Snate@binkert.org .prereq(renameRenamedInsts); 1085863Snate@binkert.org renameSquashedInsts 1095863Snate@binkert.org .name(name() + ".RENAME:SquashedInsts") 110955SN/A .desc("Number of squashed instructions processed by rename") 1116654Snate@binkert.org .prereq(renameSquashedInsts); 1125273Sstever@gmail.com renameROBFullEvents 1135871Snate@binkert.org .name(name() + ".RENAME:ROBFullEvents") 1145273Sstever@gmail.com .desc("Number of times rename has blocked due to ROB full") 1156655Snate@binkert.org .prereq(renameROBFullEvents); 1168878Ssteve.reinhardt@amd.com renameIQFullEvents 1176655Snate@binkert.org .name(name() + ".RENAME:IQFullEvents") 1186655Snate@binkert.org .desc("Number of times rename has blocked due to IQ full") 1199219Spower.jg@gmail.com .prereq(renameIQFullEvents); 1206655Snate@binkert.org renameLSQFullEvents 1215871Snate@binkert.org .name(name() + ".RENAME:LSQFullEvents") 1226654Snate@binkert.org .desc("Number of times rename has blocked due to LSQ full") 1238947Sandreas.hansson@arm.com .prereq(renameLSQFullEvents); 1245396Ssaidi@eecs.umich.edu renameFullRegistersEvents 1258120Sgblack@eecs.umich.edu .name(name() + ".RENAME:FullRegisterEvents") 1268120Sgblack@eecs.umich.edu .desc("Number of times there has been no free registers") 1278120Sgblack@eecs.umich.edu .prereq(renameFullRegistersEvents); 1288120Sgblack@eecs.umich.edu renameRenamedOperands 1298120Sgblack@eecs.umich.edu .name(name() + ".RENAME:RenamedOperands") 1308120Sgblack@eecs.umich.edu .desc("Number of destination operands rename has renamed") 1318120Sgblack@eecs.umich.edu .prereq(renameRenamedOperands); 1328120Sgblack@eecs.umich.edu renameRenameLookups 1338879Ssteve.reinhardt@amd.com .name(name() + ".RENAME:RenameLookups") 1348879Ssteve.reinhardt@amd.com .desc("Number of register rename lookups that rename has made") 1358879Ssteve.reinhardt@amd.com .prereq(renameRenameLookups); 1368879Ssteve.reinhardt@amd.com renameCommittedMaps 1378879Ssteve.reinhardt@amd.com .name(name() + ".RENAME:CommittedMaps") 1388879Ssteve.reinhardt@amd.com .desc("Number of HB maps that are committed") 1398879Ssteve.reinhardt@amd.com .prereq(renameCommittedMaps); 1408879Ssteve.reinhardt@amd.com renameUndoneMaps 1418879Ssteve.reinhardt@amd.com .name(name() + ".RENAME:UndoneMaps") 1428879Ssteve.reinhardt@amd.com .desc("Number of HB maps that are undone due to squashing") 1438879Ssteve.reinhardt@amd.com .prereq(renameUndoneMaps); 1448879Ssteve.reinhardt@amd.com renamedSerializing 1458879Ssteve.reinhardt@amd.com .name(name() + ".RENAME:serializingInsts") 1468120Sgblack@eecs.umich.edu .desc("count of serializing insts renamed") 1478120Sgblack@eecs.umich.edu .flags(Stats::total) 1488120Sgblack@eecs.umich.edu ; 1498120Sgblack@eecs.umich.edu renamedTempSerializing 1508120Sgblack@eecs.umich.edu .name(name() + ".RENAME:tempSerializingInsts") 1518120Sgblack@eecs.umich.edu .desc("count of temporary serializing insts renamed") 1528120Sgblack@eecs.umich.edu .flags(Stats::total) 1538120Sgblack@eecs.umich.edu ; 1548120Sgblack@eecs.umich.edu renameSkidInsts 1558120Sgblack@eecs.umich.edu .name(name() + ".RENAME:skidInsts") 1568120Sgblack@eecs.umich.edu .desc("count of insts added to the skid buffer") 1578120Sgblack@eecs.umich.edu .flags(Stats::total) 1588120Sgblack@eecs.umich.edu ; 1598120Sgblack@eecs.umich.edu} 1608879Ssteve.reinhardt@amd.com 1618879Ssteve.reinhardt@amd.comtemplate <class Impl> 1628879Ssteve.reinhardt@amd.comvoid 1638879Ssteve.reinhardt@amd.comDefaultRename<Impl>::setCPU(FullCPU *cpu_ptr) 1648879Ssteve.reinhardt@amd.com{ 1658879Ssteve.reinhardt@amd.com DPRINTF(Rename, "Setting CPU pointer.\n"); 1668879Ssteve.reinhardt@amd.com cpu = cpu_ptr; 1678879Ssteve.reinhardt@amd.com} 1689227Sandreas.hansson@arm.com 1699227Sandreas.hansson@arm.comtemplate <class Impl> 1708879Ssteve.reinhardt@amd.comvoid 1718879Ssteve.reinhardt@amd.comDefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 1728879Ssteve.reinhardt@amd.com{ 1738879Ssteve.reinhardt@amd.com DPRINTF(Rename, "Setting time buffer pointer.\n"); 1748120Sgblack@eecs.umich.edu timeBuffer = tb_ptr; 1758947Sandreas.hansson@arm.com 1767816Ssteve.reinhardt@amd.com // Setup wire to read information from time buffer, from IEW stage. 1775871Snate@binkert.org fromIEW = timeBuffer->getWire(-iewToRenameDelay); 1785871Snate@binkert.org 1796121Snate@binkert.org // Setup wire to read infromation from time buffer, from commit stage. 1805871Snate@binkert.org fromCommit = timeBuffer->getWire(-commitToRenameDelay); 1815871Snate@binkert.org 1829119Sandreas.hansson@arm.com // Setup wire to write information to previous stages. 1839396Sandreas.hansson@arm.com toDecode = timeBuffer->getWire(0); 1849396Sandreas.hansson@arm.com} 185955SN/A 1869416SAndreas.Sandberg@ARM.comtemplate <class Impl> 1879416SAndreas.Sandberg@ARM.comvoid 1889416SAndreas.Sandberg@ARM.comDefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 1899416SAndreas.Sandberg@ARM.com{ 1909416SAndreas.Sandberg@ARM.com DPRINTF(Rename, "Setting rename queue pointer.\n"); 1919416SAndreas.Sandberg@ARM.com renameQueue = rq_ptr; 1929416SAndreas.Sandberg@ARM.com 1935871Snate@binkert.org // Setup wire to write information to future stages. 1945871Snate@binkert.org toIEW = renameQueue->getWire(0); 1959416SAndreas.Sandberg@ARM.com} 1969416SAndreas.Sandberg@ARM.com 1975871Snate@binkert.orgtemplate <class Impl> 198955SN/Avoid 1996121Snate@binkert.orgDefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) 2008881Smarc.orr@gmail.com{ 2016121Snate@binkert.org DPRINTF(Rename, "Setting decode queue pointer.\n"); 2026121Snate@binkert.org decodeQueue = dq_ptr; 2031533SN/A 2049239Sandreas.hansson@arm.com // Setup wire to get information from decode. 2059239Sandreas.hansson@arm.com fromDecode = decodeQueue->getWire(-decodeToRenameDelay); 2069239Sandreas.hansson@arm.com} 2079239Sandreas.hansson@arm.com 2089239Sandreas.hansson@arm.comtemplate <class Impl> 2099239Sandreas.hansson@arm.comvoid 2109239Sandreas.hansson@arm.comDefaultRename<Impl>::initStage() 2119239Sandreas.hansson@arm.com{ 2129239Sandreas.hansson@arm.com // Grab the number of free entries directly from the stages. 2139239Sandreas.hansson@arm.com for (int tid=0; tid < numThreads; tid++) { 2149239Sandreas.hansson@arm.com freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid); 2159239Sandreas.hansson@arm.com freeEntries[tid].lsqEntries = iew_ptr->ldstQueue.numFreeEntries(tid); 2166655Snate@binkert.org freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid); 2176655Snate@binkert.org emptyROB[tid] = true; 2186655Snate@binkert.org } 2196655Snate@binkert.org} 2205871Snate@binkert.org 2215871Snate@binkert.orgtemplate<class Impl> 2225863Snate@binkert.orgvoid 2235871Snate@binkert.orgDefaultRename<Impl>::setActiveThreads(list<unsigned> *at_ptr) 2248878Ssteve.reinhardt@amd.com{ 2255871Snate@binkert.org DPRINTF(Rename, "Setting active threads list pointer.\n"); 2265871Snate@binkert.org activeThreads = at_ptr; 2275871Snate@binkert.org} 2285863Snate@binkert.org 2296121Snate@binkert.org 2305863Snate@binkert.orgtemplate <class Impl> 2315871Snate@binkert.orgvoid 2328336Ssteve.reinhardt@amd.comDefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[]) 2338336Ssteve.reinhardt@amd.com{ 2348336Ssteve.reinhardt@amd.com DPRINTF(Rename, "Setting rename map pointers.\n"); 2358336Ssteve.reinhardt@amd.com 2364678Snate@binkert.org for (int i=0; i<numThreads; i++) { 2378336Ssteve.reinhardt@amd.com renameMap[i] = &rm_ptr[i]; 2388336Ssteve.reinhardt@amd.com } 2398336Ssteve.reinhardt@amd.com} 2404678Snate@binkert.org 2414678Snate@binkert.orgtemplate <class Impl> 2424678Snate@binkert.orgvoid 2434678Snate@binkert.orgDefaultRename<Impl>::setFreeList(FreeList *fl_ptr) 2447827Snate@binkert.org{ 2457827Snate@binkert.org DPRINTF(Rename, "Setting free list pointer.\n"); 2468336Ssteve.reinhardt@amd.com freeList = fl_ptr; 2474678Snate@binkert.org} 2488336Ssteve.reinhardt@amd.com 2498336Ssteve.reinhardt@amd.comtemplate<class Impl> 2508336Ssteve.reinhardt@amd.comvoid 2518336Ssteve.reinhardt@amd.comDefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard) 2528336Ssteve.reinhardt@amd.com{ 2538336Ssteve.reinhardt@amd.com DPRINTF(Rename, "Setting scoreboard pointer.\n"); 2545871Snate@binkert.org scoreboard = _scoreboard; 2555871Snate@binkert.org} 2568336Ssteve.reinhardt@amd.com 2578336Ssteve.reinhardt@amd.comtemplate <class Impl> 2588336Ssteve.reinhardt@amd.comvoid 2598336Ssteve.reinhardt@amd.comDefaultRename<Impl>::switchOut() 2608336Ssteve.reinhardt@amd.com{ 2615871Snate@binkert.org cpu->signalSwitched(); 2628336Ssteve.reinhardt@amd.com} 2638336Ssteve.reinhardt@amd.com 2648336Ssteve.reinhardt@amd.comtemplate <class Impl> 2658336Ssteve.reinhardt@amd.comvoid 2668336Ssteve.reinhardt@amd.comDefaultRename<Impl>::doSwitchOut() 2674678Snate@binkert.org{ 2685871Snate@binkert.org for (int i = 0; i < numThreads; i++) { 2694678Snate@binkert.org typename list<RenameHistory>::iterator hb_it = historyBuffer[i].begin(); 2708336Ssteve.reinhardt@amd.com 2718336Ssteve.reinhardt@amd.com while (!historyBuffer[i].empty()) { 2728336Ssteve.reinhardt@amd.com assert(hb_it != historyBuffer[i].end()); 2738336Ssteve.reinhardt@amd.com 2748336Ssteve.reinhardt@amd.com DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence " 2758336Ssteve.reinhardt@amd.com "number %i.\n", i, (*hb_it).instSeqNum); 2768336Ssteve.reinhardt@amd.com 2778336Ssteve.reinhardt@amd.com // Tell the rename map to set the architected register to the 2788336Ssteve.reinhardt@amd.com // previous physical register that it was renamed to. 2798336Ssteve.reinhardt@amd.com renameMap[i]->setEntry(hb_it->archReg, hb_it->prevPhysReg); 2808336Ssteve.reinhardt@amd.com 2818336Ssteve.reinhardt@amd.com // Put the renamed physical register back on the free list. 2828336Ssteve.reinhardt@amd.com freeList->addReg(hb_it->newPhysReg); 2838336Ssteve.reinhardt@amd.com 2848336Ssteve.reinhardt@amd.com historyBuffer[i].erase(hb_it++); 2858336Ssteve.reinhardt@amd.com } 2868336Ssteve.reinhardt@amd.com insts[i].clear(); 2875871Snate@binkert.org skidBuffer[i].clear(); 2886121Snate@binkert.org } 289955SN/A} 290955SN/A 2912632Sstever@eecs.umich.edutemplate <class Impl> 2922632Sstever@eecs.umich.eduvoid 293955SN/ADefaultRename<Impl>::takeOverFrom() 294955SN/A{ 295955SN/A _status = Inactive; 296955SN/A initStage(); 2978878Ssteve.reinhardt@amd.com 298955SN/A // Reset all state prior to taking over from the other CPU. 2992632Sstever@eecs.umich.edu for (int i=0; i< numThreads; i++) { 3002632Sstever@eecs.umich.edu renameStatus[i] = Idle; 3012632Sstever@eecs.umich.edu 3022632Sstever@eecs.umich.edu stalls[i].iew = false; 3032632Sstever@eecs.umich.edu stalls[i].commit = false; 3042632Sstever@eecs.umich.edu serializeInst[i] = NULL; 3052632Sstever@eecs.umich.edu 3068268Ssteve.reinhardt@amd.com instsInProgress[i] = 0; 3078268Ssteve.reinhardt@amd.com 3088268Ssteve.reinhardt@amd.com emptyROB[i] = true; 3098268Ssteve.reinhardt@amd.com 3108268Ssteve.reinhardt@amd.com serializeOnNextInst[i] = false; 3118268Ssteve.reinhardt@amd.com } 3128268Ssteve.reinhardt@amd.com} 3132632Sstever@eecs.umich.edu 3142632Sstever@eecs.umich.edutemplate <class Impl> 3152632Sstever@eecs.umich.eduvoid 3162632Sstever@eecs.umich.eduDefaultRename<Impl>::squash(unsigned tid) 3178268Ssteve.reinhardt@amd.com{ 3182632Sstever@eecs.umich.edu DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid); 3198268Ssteve.reinhardt@amd.com 3208268Ssteve.reinhardt@amd.com // Clear the stall signal if rename was blocked or unblocking before. 3218268Ssteve.reinhardt@amd.com // If it still needs to block, the blocking should happen the next 3228268Ssteve.reinhardt@amd.com // cycle and there should be space to hold everything due to the squash. 3233718Sstever@eecs.umich.edu if (renameStatus[tid] == Blocked || 3242634Sstever@eecs.umich.edu renameStatus[tid] == Unblocking || 3252634Sstever@eecs.umich.edu renameStatus[tid] == SerializeStall) { 3265863Snate@binkert.org#if 0 3272638Sstever@eecs.umich.edu // In syscall emulation, we can have both a block and a squash due 3288268Ssteve.reinhardt@amd.com // to a syscall in the same cycle. This would cause both signals to 3292632Sstever@eecs.umich.edu // be high. This shouldn't happen in full system. 3302632Sstever@eecs.umich.edu if (toDecode->renameBlock[tid]) { 3312632Sstever@eecs.umich.edu toDecode->renameBlock[tid] = 0; 3322632Sstever@eecs.umich.edu } else { 3332632Sstever@eecs.umich.edu toDecode->renameUnblock[tid] = 1; 3341858SN/A } 3353716Sstever@eecs.umich.edu#else 3362638Sstever@eecs.umich.edu toDecode->renameUnblock[tid] = 1; 3372638Sstever@eecs.umich.edu#endif 3382638Sstever@eecs.umich.edu serializeInst[tid] = NULL; 3392638Sstever@eecs.umich.edu } 3402638Sstever@eecs.umich.edu 3412638Sstever@eecs.umich.edu // Set the status to Squashing. 3422638Sstever@eecs.umich.edu renameStatus[tid] = Squashing; 3435863Snate@binkert.org 3445863Snate@binkert.org // Squash any instructions from decode. 3455863Snate@binkert.org unsigned squashCount = 0; 346955SN/A 3475341Sstever@gmail.com for (int i=0; i<fromDecode->size; i++) { 3485341Sstever@gmail.com if (fromDecode->insts[i]->threadNumber == tid) { 3495863Snate@binkert.org fromDecode->insts[i]->squashed = true; 3507756SAli.Saidi@ARM.com wroteToTimeBuffer = true; 3515341Sstever@gmail.com squashCount++; 3526121Snate@binkert.org } 3534494Ssaidi@eecs.umich.edu } 3546121Snate@binkert.org 3551105SN/A insts[tid].clear(); 3562667Sstever@eecs.umich.edu 3572667Sstever@eecs.umich.edu // Clear the skid buffer in case it has any data in it. 3582667Sstever@eecs.umich.edu skidBuffer[tid].clear(); 3592667Sstever@eecs.umich.edu 3606121Snate@binkert.org doSquash(tid); 3612667Sstever@eecs.umich.edu} 3625341Sstever@gmail.com 3635863Snate@binkert.orgtemplate <class Impl> 3645341Sstever@gmail.comvoid 3655341Sstever@gmail.comDefaultRename<Impl>::tick() 3665341Sstever@gmail.com{ 3678120Sgblack@eecs.umich.edu wroteToTimeBuffer = false; 3685341Sstever@gmail.com 3698120Sgblack@eecs.umich.edu blockThisCycle = false; 3705341Sstever@gmail.com 3718120Sgblack@eecs.umich.edu bool status_change = false; 3726121Snate@binkert.org 3736121Snate@binkert.org toIEWIndex = 0; 3748980Ssteve.reinhardt@amd.com 3759396Sandreas.hansson@arm.com sortInsts(); 3765397Ssaidi@eecs.umich.edu 3775397Ssaidi@eecs.umich.edu list<unsigned>::iterator threads = (*activeThreads).begin(); 3787727SAli.Saidi@ARM.com 3798268Ssteve.reinhardt@amd.com // Check stall and squash signals. 3806168Snate@binkert.org while (threads != (*activeThreads).end()) { 3815341Sstever@gmail.com unsigned tid = *threads++; 3828120Sgblack@eecs.umich.edu 3838120Sgblack@eecs.umich.edu DPRINTF(Rename, "Processing [tid:%i]\n", tid); 3848120Sgblack@eecs.umich.edu 3856814Sgblack@eecs.umich.edu status_change = checkSignalsAndUpdate(tid) || status_change; 3865863Snate@binkert.org 3878120Sgblack@eecs.umich.edu rename(status_change, tid); 3885341Sstever@gmail.com } 3895863Snate@binkert.org 3908268Ssteve.reinhardt@amd.com if (status_change) { 3916121Snate@binkert.org updateStatus(); 3926121Snate@binkert.org } 3938268Ssteve.reinhardt@amd.com 3945742Snate@binkert.org if (wroteToTimeBuffer) { 3955742Snate@binkert.org DPRINTF(Activity, "Activity this cycle.\n"); 3965341Sstever@gmail.com cpu->activityThisCycle(); 3975742Snate@binkert.org } 3985742Snate@binkert.org 3995341Sstever@gmail.com threads = (*activeThreads).begin(); 4006017Snate@binkert.org 4016121Snate@binkert.org while (threads != (*activeThreads).end()) { 4026017Snate@binkert.org unsigned tid = *threads++; 4037816Ssteve.reinhardt@amd.com 4047756SAli.Saidi@ARM.com // If we committed this cycle then doneSeqNum will be > 0 4057756SAli.Saidi@ARM.com if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 4067756SAli.Saidi@ARM.com !fromCommit->commitInfo[tid].squash && 4077756SAli.Saidi@ARM.com renameStatus[tid] != Squashing) { 4087756SAli.Saidi@ARM.com 4097756SAli.Saidi@ARM.com removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum, 4107756SAli.Saidi@ARM.com tid); 4117756SAli.Saidi@ARM.com } 4127816Ssteve.reinhardt@amd.com } 4137816Ssteve.reinhardt@amd.com 4147816Ssteve.reinhardt@amd.com // @todo: make into updateProgress function 4157816Ssteve.reinhardt@amd.com for (int tid=0; tid < numThreads; tid++) { 4167816Ssteve.reinhardt@amd.com instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched; 4177816Ssteve.reinhardt@amd.com 4187816Ssteve.reinhardt@amd.com assert(instsInProgress[tid] >=0); 4197816Ssteve.reinhardt@amd.com } 4207816Ssteve.reinhardt@amd.com 4217816Ssteve.reinhardt@amd.com} 4227756SAli.Saidi@ARM.com 4237816Ssteve.reinhardt@amd.comtemplate<class Impl> 4247816Ssteve.reinhardt@amd.comvoid 4257816Ssteve.reinhardt@amd.comDefaultRename<Impl>::rename(bool &status_change, unsigned tid) 4267816Ssteve.reinhardt@amd.com{ 4277816Ssteve.reinhardt@amd.com // If status is Running or idle, 4287816Ssteve.reinhardt@amd.com // call renameInsts() 4297816Ssteve.reinhardt@amd.com // If status is Unblocking, 4307816Ssteve.reinhardt@amd.com // buffer any instructions coming from decode 4317816Ssteve.reinhardt@amd.com // continue trying to empty skid buffer 4327816Ssteve.reinhardt@amd.com // check if stall conditions have passed 4337816Ssteve.reinhardt@amd.com 4347816Ssteve.reinhardt@amd.com if (renameStatus[tid] == Blocked) { 4357816Ssteve.reinhardt@amd.com ++renameBlockCycles; 4367816Ssteve.reinhardt@amd.com } else if (renameStatus[tid] == Squashing) { 4377816Ssteve.reinhardt@amd.com ++renameSquashCycles; 4387816Ssteve.reinhardt@amd.com } else if (renameStatus[tid] == SerializeStall) { 4397816Ssteve.reinhardt@amd.com ++renameSerializeStallCycles; 4407816Ssteve.reinhardt@amd.com } 4417816Ssteve.reinhardt@amd.com 4427816Ssteve.reinhardt@amd.com if (renameStatus[tid] == Running || 4437816Ssteve.reinhardt@amd.com renameStatus[tid] == Idle) { 4447816Ssteve.reinhardt@amd.com DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run " 4457816Ssteve.reinhardt@amd.com "stage.\n", tid); 4467816Ssteve.reinhardt@amd.com 4477816Ssteve.reinhardt@amd.com renameInsts(tid); 4487816Ssteve.reinhardt@amd.com } else if (renameStatus[tid] == Unblocking) { 4497816Ssteve.reinhardt@amd.com renameInsts(tid); 4507816Ssteve.reinhardt@amd.com 4517816Ssteve.reinhardt@amd.com if (validInsts()) { 4527816Ssteve.reinhardt@amd.com // Add the current inputs to the skid buffer so they can be 4537816Ssteve.reinhardt@amd.com // reprocessed when this stage unblocks. 4547816Ssteve.reinhardt@amd.com skidInsert(tid); 4557816Ssteve.reinhardt@amd.com } 4567816Ssteve.reinhardt@amd.com 4577816Ssteve.reinhardt@amd.com // If we switched over to blocking, then there's a potential for 4587816Ssteve.reinhardt@amd.com // an overall status change. 4597816Ssteve.reinhardt@amd.com status_change = unblock(tid) || status_change || blockThisCycle; 4607816Ssteve.reinhardt@amd.com } 4617816Ssteve.reinhardt@amd.com} 4627816Ssteve.reinhardt@amd.com 4637816Ssteve.reinhardt@amd.comtemplate <class Impl> 4647816Ssteve.reinhardt@amd.comvoid 4657816Ssteve.reinhardt@amd.comDefaultRename<Impl>::renameInsts(unsigned tid) 4667816Ssteve.reinhardt@amd.com{ 4677816Ssteve.reinhardt@amd.com // Instructions can be either in the skid buffer or the queue of 4687816Ssteve.reinhardt@amd.com // instructions coming from decode, depending on the status. 4697816Ssteve.reinhardt@amd.com int insts_available = renameStatus[tid] == Unblocking ? 4707816Ssteve.reinhardt@amd.com skidBuffer[tid].size() : insts[tid].size(); 4717816Ssteve.reinhardt@amd.com 4727816Ssteve.reinhardt@amd.com // Check the decode queue to see if instructions are available. 4737816Ssteve.reinhardt@amd.com // If there are no available instructions to rename, then do nothing. 4747816Ssteve.reinhardt@amd.com if (insts_available == 0) { 4757816Ssteve.reinhardt@amd.com DPRINTF(Rename, "[tid:%u]: Nothing to do, breaking out early.\n", 4767816Ssteve.reinhardt@amd.com tid); 4777816Ssteve.reinhardt@amd.com // Should I change status to idle? 4787816Ssteve.reinhardt@amd.com ++renameIdleCycles; 4797816Ssteve.reinhardt@amd.com return; 4807816Ssteve.reinhardt@amd.com } else if (renameStatus[tid] == Unblocking) { 4817816Ssteve.reinhardt@amd.com ++renameUnblockCycles; 4827816Ssteve.reinhardt@amd.com } else if (renameStatus[tid] == Running) { 4837816Ssteve.reinhardt@amd.com ++renameRunCycles; 4848947Sandreas.hansson@arm.com } 4858947Sandreas.hansson@arm.com 4867756SAli.Saidi@ARM.com DynInstPtr inst; 4878120Sgblack@eecs.umich.edu 4887756SAli.Saidi@ARM.com // Will have to do a different calculation for the number of free 4897756SAli.Saidi@ARM.com // entries. 4907756SAli.Saidi@ARM.com int free_rob_entries = calcFreeROBEntries(tid); 4917756SAli.Saidi@ARM.com int free_iq_entries = calcFreeIQEntries(tid); 4927816Ssteve.reinhardt@amd.com int free_lsq_entries = calcFreeLSQEntries(tid); 4937816Ssteve.reinhardt@amd.com int min_free_entries = free_rob_entries; 4947816Ssteve.reinhardt@amd.com 4957816Ssteve.reinhardt@amd.com FullSource source = ROB; 4967816Ssteve.reinhardt@amd.com 4977816Ssteve.reinhardt@amd.com if (free_iq_entries < min_free_entries) { 4987816Ssteve.reinhardt@amd.com min_free_entries = free_iq_entries; 4997816Ssteve.reinhardt@amd.com source = IQ; 5007816Ssteve.reinhardt@amd.com } 5017816Ssteve.reinhardt@amd.com 5027756SAli.Saidi@ARM.com if (free_lsq_entries < min_free_entries) { 5037756SAli.Saidi@ARM.com min_free_entries = free_lsq_entries; 5049227Sandreas.hansson@arm.com source = LSQ; 5059227Sandreas.hansson@arm.com } 5069227Sandreas.hansson@arm.com 5079227Sandreas.hansson@arm.com // Check if there's any space left. 5086654Snate@binkert.org if (min_free_entries <= 0) { 5096654Snate@binkert.org DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/LSQ " 5105871Snate@binkert.org "entries.\n" 5116121Snate@binkert.org "ROB has %i free entries.\n" 5128946Sandreas.hansson@arm.com "IQ has %i free entries.\n" 5139419Sandreas.hansson@arm.com "LSQ has %i free entries.\n", 5143940Ssaidi@eecs.umich.edu tid, 5153918Ssaidi@eecs.umich.edu free_rob_entries, 5163918Ssaidi@eecs.umich.edu free_iq_entries, 5171858SN/A free_lsq_entries); 5189556Sandreas.hansson@arm.com 5199556Sandreas.hansson@arm.com blockThisCycle = true; 5209556Sandreas.hansson@arm.com 5219556Sandreas.hansson@arm.com block(tid); 5229556Sandreas.hansson@arm.com 5239556Sandreas.hansson@arm.com incrFullStat(source); 5249556Sandreas.hansson@arm.com 5259556Sandreas.hansson@arm.com return; 5269556Sandreas.hansson@arm.com } else if (min_free_entries < insts_available) { 5279556Sandreas.hansson@arm.com DPRINTF(Rename, "[tid:%u]: Will have to block this cycle." 5289556Sandreas.hansson@arm.com "%i insts available, but only %i insts can be " 5299556Sandreas.hansson@arm.com "renamed due to ROB/IQ/LSQ limits.\n", 5309556Sandreas.hansson@arm.com tid, insts_available, min_free_entries); 5319556Sandreas.hansson@arm.com 5329556Sandreas.hansson@arm.com insts_available = min_free_entries; 5339556Sandreas.hansson@arm.com 5349556Sandreas.hansson@arm.com blockThisCycle = true; 5359556Sandreas.hansson@arm.com 5369556Sandreas.hansson@arm.com incrFullStat(source); 5379556Sandreas.hansson@arm.com } 5389556Sandreas.hansson@arm.com 5399556Sandreas.hansson@arm.com InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ? 5409556Sandreas.hansson@arm.com skidBuffer[tid] : insts[tid]; 5419556Sandreas.hansson@arm.com 5429556Sandreas.hansson@arm.com DPRINTF(Rename, "[tid:%u]: %i available instructions to " 5439556Sandreas.hansson@arm.com "send iew.\n", tid, insts_available); 5449556Sandreas.hansson@arm.com 5459556Sandreas.hansson@arm.com DPRINTF(Rename, "[tid:%u]: %i insts pipelining from Rename | %i insts " 5469556Sandreas.hansson@arm.com "dispatched to IQ last cycle.\n", 5479556Sandreas.hansson@arm.com tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched); 5489556Sandreas.hansson@arm.com 5499556Sandreas.hansson@arm.com // Handle serializing the next instruction if necessary. 5506121Snate@binkert.org if (serializeOnNextInst[tid]) { 5519420Sandreas.hansson@arm.com if (emptyROB[tid] && instsInProgress[tid] == 0) { 5529420Sandreas.hansson@arm.com // ROB already empty; no need to serialize. 5539420Sandreas.hansson@arm.com serializeOnNextInst[tid] = false; 5549420Sandreas.hansson@arm.com } else if (!insts_to_rename.empty()) { 5559420Sandreas.hansson@arm.com insts_to_rename.front()->setSerializeBefore(); 5569420Sandreas.hansson@arm.com } 5579420Sandreas.hansson@arm.com } 5589420Sandreas.hansson@arm.com 5599420Sandreas.hansson@arm.com int renamed_insts = 0; 5609420Sandreas.hansson@arm.com 5619420Sandreas.hansson@arm.com while (insts_available > 0 && toIEWIndex < renameWidth) { 5627618SAli.Saidi@arm.com DPRINTF(Rename, "[tid:%u]: Sending instructions to IEW.\n", tid); 5637618SAli.Saidi@arm.com 5647618SAli.Saidi@arm.com assert(!insts_to_rename.empty()); 5657739Sgblack@eecs.umich.edu 5669227Sandreas.hansson@arm.com inst = insts_to_rename.front(); 5679227Sandreas.hansson@arm.com 5689227Sandreas.hansson@arm.com insts_to_rename.pop_front(); 5699227Sandreas.hansson@arm.com 5709227Sandreas.hansson@arm.com if (renameStatus[tid] == Unblocking) { 5719227Sandreas.hansson@arm.com DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%#x from rename " 5729227Sandreas.hansson@arm.com "skidBuffer\n", 5739227Sandreas.hansson@arm.com tid, inst->seqNum, inst->readPC()); 5749227Sandreas.hansson@arm.com } 5759227Sandreas.hansson@arm.com 5769227Sandreas.hansson@arm.com if (inst->isSquashed()) { 5779227Sandreas.hansson@arm.com DPRINTF(Rename, "[tid:%u]: instruction %i with PC %#x is " 5789227Sandreas.hansson@arm.com "squashed, skipping.\n", 5799227Sandreas.hansson@arm.com tid, inst->seqNum, inst->threadNumber,inst->readPC()); 5809227Sandreas.hansson@arm.com 5819227Sandreas.hansson@arm.com ++renameSquashedInsts; 5829227Sandreas.hansson@arm.com 5839227Sandreas.hansson@arm.com // Decrement how many instructions are available. 5848737Skoansin.tan@gmail.com --insts_available; 5859420Sandreas.hansson@arm.com 5869420Sandreas.hansson@arm.com continue; 5879420Sandreas.hansson@arm.com } 5888737Skoansin.tan@gmail.com 5898737Skoansin.tan@gmail.com DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with " 5908737Skoansin.tan@gmail.com "PC %#x.\n", 5918737Skoansin.tan@gmail.com tid, inst->seqNum, inst->readPC()); 5928737Skoansin.tan@gmail.com 5938737Skoansin.tan@gmail.com // Handle serializeAfter/serializeBefore instructions. 5948737Skoansin.tan@gmail.com // serializeAfter marks the next instruction as serializeBefore. 5958737Skoansin.tan@gmail.com // serializeBefore makes the instruction wait in rename until the ROB 5968737Skoansin.tan@gmail.com // is empty. 5978737Skoansin.tan@gmail.com 5988737Skoansin.tan@gmail.com // In this model, IPR accesses are serialize before 5998737Skoansin.tan@gmail.com // instructions, and store conditionals are serialize after 6009556Sandreas.hansson@arm.com // instructions. This is mainly due to lack of support for 6019556Sandreas.hansson@arm.com // out-of-order operations of either of those classes of 6029556Sandreas.hansson@arm.com // instructions. 6039556Sandreas.hansson@arm.com if ((inst->isIprAccess() || inst->isSerializeBefore()) && 6049556Sandreas.hansson@arm.com !inst->isSerializeHandled()) { 6059556Sandreas.hansson@arm.com DPRINTF(Rename, "Serialize before instruction encountered.\n"); 6069556Sandreas.hansson@arm.com 6079556Sandreas.hansson@arm.com if (!inst->isTempSerializeBefore()) { 6089556Sandreas.hansson@arm.com renamedSerializing++; 6099556Sandreas.hansson@arm.com inst->setSerializeHandled(); 6109420Sandreas.hansson@arm.com } else { 6119420Sandreas.hansson@arm.com renamedTempSerializing++; 6129420Sandreas.hansson@arm.com } 6139420Sandreas.hansson@arm.com 6149420Sandreas.hansson@arm.com // Change status over to SerializeStall so that other stages know 6159420Sandreas.hansson@arm.com // what this is blocked on. 6169420Sandreas.hansson@arm.com renameStatus[tid] = SerializeStall; 6179420Sandreas.hansson@arm.com 6189420Sandreas.hansson@arm.com serializeInst[tid] = inst; 6199420Sandreas.hansson@arm.com 6208946Sandreas.hansson@arm.com blockThisCycle = true; 6213918Ssaidi@eecs.umich.edu 6229068SAli.Saidi@ARM.com break; 6239068SAli.Saidi@ARM.com } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) && 6249068SAli.Saidi@ARM.com !inst->isSerializeHandled()) { 6259068SAli.Saidi@ARM.com DPRINTF(Rename, "Serialize after instruction encountered.\n"); 6269068SAli.Saidi@ARM.com 6279068SAli.Saidi@ARM.com renamedSerializing++; 6289068SAli.Saidi@ARM.com 6299068SAli.Saidi@ARM.com inst->setSerializeHandled(); 6309068SAli.Saidi@ARM.com 6319419Sandreas.hansson@arm.com serializeAfter(insts_to_rename, tid); 6329068SAli.Saidi@ARM.com } 6339068SAli.Saidi@ARM.com 6349068SAli.Saidi@ARM.com // Check here to make sure there are enough destination registers 6359068SAli.Saidi@ARM.com // to rename to. Otherwise block. 6369068SAli.Saidi@ARM.com if (renameMap[tid]->numFreeEntries() < inst->numDestRegs()) { 6379068SAli.Saidi@ARM.com DPRINTF(Rename, "Blocking due to lack of free " 6383918Ssaidi@eecs.umich.edu "physical registers to rename to.\n"); 6393918Ssaidi@eecs.umich.edu blockThisCycle = true; 6406157Snate@binkert.org 6416157Snate@binkert.org ++renameFullRegistersEvents; 6426157Snate@binkert.org 6436157Snate@binkert.org break; 6445397Ssaidi@eecs.umich.edu } 6455397Ssaidi@eecs.umich.edu 6466121Snate@binkert.org renameSrcRegs(inst, inst->threadNumber); 6476121Snate@binkert.org 6486121Snate@binkert.org renameDestRegs(inst, inst->threadNumber); 6496121Snate@binkert.org 6506121Snate@binkert.org ++renamed_insts; 6516121Snate@binkert.org 6525397Ssaidi@eecs.umich.edu // Put instruction in rename queue. 6531851SN/A toIEW->insts[toIEWIndex] = inst; 6541851SN/A ++(toIEW->size); 6557739Sgblack@eecs.umich.edu 656955SN/A // Increment which instruction we're on. 6579396Sandreas.hansson@arm.com ++toIEWIndex; 6589396Sandreas.hansson@arm.com 6599396Sandreas.hansson@arm.com // Decrement how many instructions are available. 6609396Sandreas.hansson@arm.com --insts_available; 6619396Sandreas.hansson@arm.com } 6629396Sandreas.hansson@arm.com 6639396Sandreas.hansson@arm.com instsInProgress[tid] += renamed_insts; 6649396Sandreas.hansson@arm.com renameRenamedInsts += renamed_insts; 6659396Sandreas.hansson@arm.com 6669396Sandreas.hansson@arm.com // If we wrote to the time buffer, record this. 6679396Sandreas.hansson@arm.com if (toIEWIndex) { 6689396Sandreas.hansson@arm.com wroteToTimeBuffer = true; 6699396Sandreas.hansson@arm.com } 6709396Sandreas.hansson@arm.com 6719396Sandreas.hansson@arm.com // Check if there's any instructions left that haven't yet been renamed. 6729396Sandreas.hansson@arm.com // If so then block. 6739477Sandreas.hansson@arm.com if (insts_available) { 6749477Sandreas.hansson@arm.com blockThisCycle = true; 6759477Sandreas.hansson@arm.com } 6769477Sandreas.hansson@arm.com 6779477Sandreas.hansson@arm.com if (blockThisCycle) { 6789477Sandreas.hansson@arm.com block(tid); 6799477Sandreas.hansson@arm.com toDecode->renameUnblock[tid] = false; 6809477Sandreas.hansson@arm.com } 6819477Sandreas.hansson@arm.com} 6829477Sandreas.hansson@arm.com 6839477Sandreas.hansson@arm.comtemplate<class Impl> 6849477Sandreas.hansson@arm.comvoid 6859477Sandreas.hansson@arm.comDefaultRename<Impl>::skidInsert(unsigned tid) 6869477Sandreas.hansson@arm.com{ 6879477Sandreas.hansson@arm.com DynInstPtr inst = NULL; 6889477Sandreas.hansson@arm.com 6899477Sandreas.hansson@arm.com while (!insts[tid].empty()) { 6909477Sandreas.hansson@arm.com inst = insts[tid].front(); 6919477Sandreas.hansson@arm.com 6929477Sandreas.hansson@arm.com insts[tid].pop_front(); 6939477Sandreas.hansson@arm.com 6949477Sandreas.hansson@arm.com assert(tid == inst->threadNumber); 6959396Sandreas.hansson@arm.com 6963053Sstever@eecs.umich.edu DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC:%#x into Rename " 6976121Snate@binkert.org "skidBuffer\n", tid, inst->seqNum, inst->readPC()); 6983053Sstever@eecs.umich.edu 6993053Sstever@eecs.umich.edu ++renameSkidInsts; 7003053Sstever@eecs.umich.edu 7013053Sstever@eecs.umich.edu skidBuffer[tid].push_back(inst); 7023053Sstever@eecs.umich.edu } 7039072Sandreas.hansson@arm.com 7043053Sstever@eecs.umich.edu if (skidBuffer[tid].size() > skidBufferMax) 7054742Sstever@eecs.umich.edu panic("Skidbuffer Exceeded Max Size"); 7064742Sstever@eecs.umich.edu} 7073053Sstever@eecs.umich.edu 7083053Sstever@eecs.umich.edutemplate <class Impl> 7093053Sstever@eecs.umich.eduvoid 7108960Ssteve.reinhardt@amd.comDefaultRename<Impl>::sortInsts() 7116654Snate@binkert.org{ 7123053Sstever@eecs.umich.edu int insts_from_decode = fromDecode->size; 7133053Sstever@eecs.umich.edu#ifdef DEBUG 7143053Sstever@eecs.umich.edu for (int i=0; i < numThreads; i++) 7153053Sstever@eecs.umich.edu assert(insts[i].empty()); 7162667Sstever@eecs.umich.edu#endif 7174554Sbinkertn@umich.edu for (int i = 0; i < insts_from_decode; ++i) { 7186121Snate@binkert.org DynInstPtr inst = fromDecode->insts[i]; 7192667Sstever@eecs.umich.edu insts[inst->threadNumber].push_back(inst); 7204554Sbinkertn@umich.edu } 7214554Sbinkertn@umich.edu} 7224554Sbinkertn@umich.edu 7236121Snate@binkert.orgtemplate<class Impl> 7244554Sbinkertn@umich.edubool 7254554Sbinkertn@umich.eduDefaultRename<Impl>::skidsEmpty() 7264554Sbinkertn@umich.edu{ 7274781Snate@binkert.org list<unsigned>::iterator threads = (*activeThreads).begin(); 7284554Sbinkertn@umich.edu 7294554Sbinkertn@umich.edu while (threads != (*activeThreads).end()) { 7302667Sstever@eecs.umich.edu if (!skidBuffer[*threads++].empty()) 7314554Sbinkertn@umich.edu return false; 7324554Sbinkertn@umich.edu } 7334554Sbinkertn@umich.edu 7344554Sbinkertn@umich.edu return true; 7352667Sstever@eecs.umich.edu} 7364554Sbinkertn@umich.edu 7372667Sstever@eecs.umich.edutemplate<class Impl> 7384554Sbinkertn@umich.eduvoid 7396121Snate@binkert.orgDefaultRename<Impl>::updateStatus() 7402667Sstever@eecs.umich.edu{ 7415522Snate@binkert.org bool any_unblocking = false; 7425522Snate@binkert.org 7435522Snate@binkert.org list<unsigned>::iterator threads = (*activeThreads).begin(); 7445522Snate@binkert.org 7455522Snate@binkert.org threads = (*activeThreads).begin(); 7465522Snate@binkert.org 7475522Snate@binkert.org while (threads != (*activeThreads).end()) { 7485522Snate@binkert.org unsigned tid = *threads++; 7495522Snate@binkert.org 7505522Snate@binkert.org if (renameStatus[tid] == Unblocking) { 7515522Snate@binkert.org any_unblocking = true; 7525522Snate@binkert.org break; 7535522Snate@binkert.org } 7545522Snate@binkert.org } 7555522Snate@binkert.org 7565522Snate@binkert.org // Rename will have activity if it's unblocking. 7575522Snate@binkert.org if (any_unblocking) { 7585522Snate@binkert.org if (_status == Inactive) { 7595522Snate@binkert.org _status = Active; 7605522Snate@binkert.org 7615522Snate@binkert.org DPRINTF(Activity, "Activating stage.\n"); 7625522Snate@binkert.org 7635522Snate@binkert.org cpu->activateStage(FullCPU::RenameIdx); 7645522Snate@binkert.org } 7655522Snate@binkert.org } else { 7665522Snate@binkert.org // If it's not unblocking, then rename will not have any internal 7672638Sstever@eecs.umich.edu // activity. Switch it to inactive. 7682638Sstever@eecs.umich.edu if (_status == Active) { 7696121Snate@binkert.org _status = Inactive; 7703716Sstever@eecs.umich.edu DPRINTF(Activity, "Deactivating stage.\n"); 7715522Snate@binkert.org 7729420Sandreas.hansson@arm.com cpu->deactivateStage(FullCPU::RenameIdx); 7735522Snate@binkert.org } 7745522Snate@binkert.org } 7755522Snate@binkert.org} 7765522Snate@binkert.org 7771858SN/Atemplate <class Impl> 7785227Ssaidi@eecs.umich.edubool 7795227Ssaidi@eecs.umich.eduDefaultRename<Impl>::block(unsigned tid) 7805227Ssaidi@eecs.umich.edu{ 7815227Ssaidi@eecs.umich.edu DPRINTF(Rename, "[tid:%u]: Blocking.\n", tid); 7826654Snate@binkert.org 7836654Snate@binkert.org // Add the current inputs onto the skid buffer, so they can be 7847769SAli.Saidi@ARM.com // reprocessed when this stage unblocks. 7857769SAli.Saidi@ARM.com skidInsert(tid); 7867769SAli.Saidi@ARM.com 7877769SAli.Saidi@ARM.com // Only signal backwards to block if the previous stages do not think 7885227Ssaidi@eecs.umich.edu // rename is already blocked. 7895227Ssaidi@eecs.umich.edu if (renameStatus[tid] != Blocked) { 7905227Ssaidi@eecs.umich.edu if (renameStatus[tid] != Unblocking) { 7915204Sstever@gmail.com toDecode->renameBlock[tid] = true; 7925204Sstever@gmail.com toDecode->renameUnblock[tid] = false; 7935204Sstever@gmail.com wroteToTimeBuffer = true; 7945204Sstever@gmail.com } 7955204Sstever@gmail.com 7965204Sstever@gmail.com // Rename can not go from SerializeStall to Blocked, otherwise 7975204Sstever@gmail.com // it would not know to complete the serialize stall. 7985204Sstever@gmail.com if (renameStatus[tid] != SerializeStall) { 7995204Sstever@gmail.com // Set status to Blocked. 8005204Sstever@gmail.com renameStatus[tid] = Blocked; 8015204Sstever@gmail.com return true; 8025204Sstever@gmail.com } 8035204Sstever@gmail.com } 8045204Sstever@gmail.com 8055204Sstever@gmail.com return false; 8065204Sstever@gmail.com} 8075204Sstever@gmail.com 8086121Snate@binkert.orgtemplate <class Impl> 8095204Sstever@gmail.combool 8103118Sstever@eecs.umich.eduDefaultRename<Impl>::unblock(unsigned tid) 8113118Sstever@eecs.umich.edu{ 8123118Sstever@eecs.umich.edu DPRINTF(Rename, "[tid:%u]: Trying to unblock.\n", tid); 8133118Sstever@eecs.umich.edu 8143118Sstever@eecs.umich.edu // Rename is done unblocking if the skid buffer is empty. 8155863Snate@binkert.org if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) { 8163118Sstever@eecs.umich.edu 8175863Snate@binkert.org DPRINTF(Rename, "[tid:%u]: Done unblocking.\n", tid); 8183118Sstever@eecs.umich.edu 8197457Snate@binkert.org toDecode->renameUnblock[tid] = true; 8207457Snate@binkert.org wroteToTimeBuffer = true; 8215863Snate@binkert.org 8225863Snate@binkert.org renameStatus[tid] = Running; 8235863Snate@binkert.org return true; 8245863Snate@binkert.org } 8255863Snate@binkert.org 8265863Snate@binkert.org return false; 8275863Snate@binkert.org} 8286003Snate@binkert.org 8295863Snate@binkert.orgtemplate <class Impl> 8305863Snate@binkert.orgvoid 8315863Snate@binkert.orgDefaultRename<Impl>::doSquash(unsigned tid) 8326120Snate@binkert.org{ 8335863Snate@binkert.org typename list<RenameHistory>::iterator hb_it = historyBuffer[tid].begin(); 8345863Snate@binkert.org 8355863Snate@binkert.org InstSeqNum squashed_seq_num = fromCommit->commitInfo[tid].doneSeqNum; 8368655Sandreas.hansson@arm.com 8378655Sandreas.hansson@arm.com // After a syscall squashes everything, the history buffer may be empty 8388655Sandreas.hansson@arm.com // but the ROB may still be squashing instructions. 8398655Sandreas.hansson@arm.com if (historyBuffer[tid].empty()) { 8408655Sandreas.hansson@arm.com return; 8418655Sandreas.hansson@arm.com } 8428655Sandreas.hansson@arm.com 8438655Sandreas.hansson@arm.com // Go through the most recent instructions, undoing the mappings 8446120Snate@binkert.org // they did and freeing up the registers. 8455863Snate@binkert.org while (!historyBuffer[tid].empty() && 8466121Snate@binkert.org (*hb_it).instSeqNum > squashed_seq_num) { 8476121Snate@binkert.org assert(hb_it != historyBuffer[tid].end()); 8485863Snate@binkert.org 8497727SAli.Saidi@ARM.com DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence " 8507727SAli.Saidi@ARM.com "number %i.\n", tid, (*hb_it).instSeqNum); 8517727SAli.Saidi@ARM.com 8527727SAli.Saidi@ARM.com // Tell the rename map to set the architected register to the 8537727SAli.Saidi@ARM.com // previous physical register that it was renamed to. 8547727SAli.Saidi@ARM.com renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg); 8555863Snate@binkert.org 8563118Sstever@eecs.umich.edu // Put the renamed physical register back on the free list. 8575863Snate@binkert.org freeList->addReg(hb_it->newPhysReg); 8589239Sandreas.hansson@arm.com 8593118Sstever@eecs.umich.edu historyBuffer[tid].erase(hb_it++); 8603118Sstever@eecs.umich.edu 8615863Snate@binkert.org ++renameUndoneMaps; 8625863Snate@binkert.org } 8635863Snate@binkert.org} 8645863Snate@binkert.org 8653118Sstever@eecs.umich.edutemplate<class Impl> 8663483Ssaidi@eecs.umich.eduvoid 8673494Ssaidi@eecs.umich.eduDefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, unsigned tid) 8683494Ssaidi@eecs.umich.edu{ 8693483Ssaidi@eecs.umich.edu DPRINTF(Rename, "[tid:%u]: Removing a committed instruction from the " 8703483Ssaidi@eecs.umich.edu "history buffer %u (size=%i), until [sn:%lli].\n", 8713483Ssaidi@eecs.umich.edu tid, tid, historyBuffer[tid].size(), inst_seq_num); 8723053Sstever@eecs.umich.edu 8733053Sstever@eecs.umich.edu typename list<RenameHistory>::iterator hb_it = historyBuffer[tid].end(); 8743918Ssaidi@eecs.umich.edu 8753053Sstever@eecs.umich.edu --hb_it; 8763053Sstever@eecs.umich.edu 8773053Sstever@eecs.umich.edu if (historyBuffer[tid].empty()) { 8783053Sstever@eecs.umich.edu DPRINTF(Rename, "[tid:%u]: History buffer is empty.\n", tid); 8793053Sstever@eecs.umich.edu return; 8809396Sandreas.hansson@arm.com } else if (hb_it->instSeqNum > inst_seq_num) { 8819396Sandreas.hansson@arm.com DPRINTF(Rename, "[tid:%u]: Old sequence number encountered. Ensure " 8829396Sandreas.hansson@arm.com "that a syscall happened recently.\n", tid); 8839396Sandreas.hansson@arm.com return; 8849396Sandreas.hansson@arm.com } 8859396Sandreas.hansson@arm.com 8869396Sandreas.hansson@arm.com // Commit all the renames up until (and including) the committed sequence 8879396Sandreas.hansson@arm.com // number. Some or even all of the committed instructions may not have 8889396Sandreas.hansson@arm.com // rename histories if they did not have destination registers that were 8899477Sandreas.hansson@arm.com // renamed. 8909396Sandreas.hansson@arm.com while (!historyBuffer[tid].empty() && 8919477Sandreas.hansson@arm.com hb_it != historyBuffer[tid].end() && 8929477Sandreas.hansson@arm.com (*hb_it).instSeqNum <= inst_seq_num) { 8939477Sandreas.hansson@arm.com 8949477Sandreas.hansson@arm.com DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, " 8959396Sandreas.hansson@arm.com "[sn:%lli].\n", 8967840Snate@binkert.org tid, (*hb_it).prevPhysReg, (*hb_it).instSeqNum); 8977865Sgblack@eecs.umich.edu 8987865Sgblack@eecs.umich.edu freeList->addReg((*hb_it).prevPhysReg); 8997865Sgblack@eecs.umich.edu ++renameCommittedMaps; 9007865Sgblack@eecs.umich.edu 9017865Sgblack@eecs.umich.edu historyBuffer[tid].erase(hb_it--); 9027840Snate@binkert.org } 9039045SAli.Saidi@ARM.com} 9049045SAli.Saidi@ARM.com 9059045SAli.Saidi@ARM.comtemplate <class Impl> 9069045SAli.Saidi@ARM.cominline void 9079045SAli.Saidi@ARM.comDefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst,unsigned tid) 9089045SAli.Saidi@ARM.com{ 9099071Sandreas.hansson@arm.com assert(renameMap[tid] != 0); 9109071Sandreas.hansson@arm.com 9119045SAli.Saidi@ARM.com unsigned num_src_regs = inst->numSrcRegs(); 9127840Snate@binkert.org 9137840Snate@binkert.org // Get the architectual register numbers from the source and 9147840Snate@binkert.org // destination operands, and redirect them to the right register. 9151858SN/A // Will need to mark dependencies though. 9161858SN/A for (int src_idx = 0; src_idx < num_src_regs; src_idx++) { 9171858SN/A RegIndex src_reg = inst->srcRegIdx(src_idx); 9181858SN/A 9191858SN/A // Look up the source registers to get the phys. register they've 9201858SN/A // been renamed to, and set the sources to those registers. 9215863Snate@binkert.org PhysRegIndex renamed_reg = renameMap[tid]->lookup(src_reg); 9225863Snate@binkert.org 9235863Snate@binkert.org DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got " 9245863Snate@binkert.org "physical reg %i.\n", tid, (int)src_reg, 9256121Snate@binkert.org (int)renamed_reg); 9261858SN/A 9275863Snate@binkert.org inst->renameSrcReg(src_idx, renamed_reg); 9285863Snate@binkert.org 9295863Snate@binkert.org // See if the register is ready or not. 9305863Snate@binkert.org if (scoreboard->getReg(renamed_reg) == true) { 9315863Snate@binkert.org DPRINTF(Rename, "[tid:%u]: Register is ready.\n", tid); 9322139SN/A 9334202Sbinkertn@umich.edu inst->markSrcRegReady(src_idx); 9344202Sbinkertn@umich.edu } 9352139SN/A 9366994Snate@binkert.org ++renameRenameLookups; 9376994Snate@binkert.org } 9386994Snate@binkert.org} 9396994Snate@binkert.org 9406994Snate@binkert.orgtemplate <class Impl> 9416994Snate@binkert.orginline void 9426994Snate@binkert.orgDefaultRename<Impl>::renameDestRegs(DynInstPtr &inst,unsigned tid) 9436994Snate@binkert.org{ 9446994Snate@binkert.org typename RenameMap::RenameInfo rename_result; 9456994Snate@binkert.org 9466994Snate@binkert.org unsigned num_dest_regs = inst->numDestRegs(); 9476994Snate@binkert.org 9486994Snate@binkert.org // Rename the destination registers. 9496994Snate@binkert.org for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) { 9506994Snate@binkert.org RegIndex dest_reg = inst->destRegIdx(dest_idx); 9516994Snate@binkert.org 9526994Snate@binkert.org // Get the physical register that the destination will be 9536994Snate@binkert.org // renamed to. 9546994Snate@binkert.org rename_result = renameMap[tid]->rename(dest_reg); 9556994Snate@binkert.org 9566994Snate@binkert.org //Mark Scoreboard entry as not ready 9576994Snate@binkert.org scoreboard->unsetReg(rename_result.first); 9586994Snate@binkert.org 9596994Snate@binkert.org DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical " 9606994Snate@binkert.org "reg %i.\n", tid, (int)dest_reg, 9616994Snate@binkert.org (int)rename_result.first); 9626994Snate@binkert.org 9636994Snate@binkert.org // Record the rename information so that a history can be kept. 9642155SN/A RenameHistory hb_entry(inst->seqNum, dest_reg, 9655863Snate@binkert.org rename_result.first, 9661869SN/A rename_result.second); 9671869SN/A 9685863Snate@binkert.org historyBuffer[tid].push_front(hb_entry); 9695863Snate@binkert.org 9704202Sbinkertn@umich.edu DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer, " 9716108Snate@binkert.org "[sn:%lli].\n",tid, 9726108Snate@binkert.org (*historyBuffer[tid].begin()).instSeqNum); 9736108Snate@binkert.org 9746108Snate@binkert.org // Tell the instruction to rename the appropriate destination 9759219Spower.jg@gmail.com // register (dest_idx) to the new physical register 9769219Spower.jg@gmail.com // (rename_result.first), and record the previous physical 9779219Spower.jg@gmail.com // register that the same logical register was renamed to 9789219Spower.jg@gmail.com // (rename_result.second). 9799219Spower.jg@gmail.com inst->renameDestReg(dest_idx, 9809219Spower.jg@gmail.com rename_result.first, 9819219Spower.jg@gmail.com rename_result.second); 9829219Spower.jg@gmail.com 9834202Sbinkertn@umich.edu ++renameRenamedOperands; 9845863Snate@binkert.org } 9858474Sgblack@eecs.umich.edu} 9868474Sgblack@eecs.umich.edu 9875742Snate@binkert.orgtemplate <class Impl> 9888268Ssteve.reinhardt@amd.cominline int 9898268Ssteve.reinhardt@amd.comDefaultRename<Impl>::calcFreeROBEntries(unsigned tid) 9908268Ssteve.reinhardt@amd.com{ 9915742Snate@binkert.org int num_free = freeEntries[tid].robEntries - 9925341Sstever@gmail.com (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched); 9938474Sgblack@eecs.umich.edu 9948474Sgblack@eecs.umich.edu //DPRINTF(Rename,"[tid:%i]: %i rob free\n",tid,num_free); 9955342Sstever@gmail.com 9964202Sbinkertn@umich.edu return num_free; 9974202Sbinkertn@umich.edu} 9984202Sbinkertn@umich.edu 9995863Snate@binkert.orgtemplate <class Impl> 10005863Snate@binkert.orginline int 10016994Snate@binkert.orgDefaultRename<Impl>::calcFreeIQEntries(unsigned tid) 10026994Snate@binkert.org{ 10036994Snate@binkert.org int num_free = freeEntries[tid].iqEntries - 10045863Snate@binkert.org (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched); 10055863Snate@binkert.org 10065863Snate@binkert.org //DPRINTF(Rename,"[tid:%i]: %i iq free\n",tid,num_free); 10075863Snate@binkert.org 10085863Snate@binkert.org return num_free; 10095863Snate@binkert.org} 10105863Snate@binkert.org 10115863Snate@binkert.orgtemplate <class Impl> 10127840Snate@binkert.orginline int 10135863Snate@binkert.orgDefaultRename<Impl>::calcFreeLSQEntries(unsigned tid) 10145952Ssaidi@eecs.umich.edu{ 10159219Spower.jg@gmail.com int num_free = freeEntries[tid].lsqEntries - 10169219Spower.jg@gmail.com (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLSQ); 10171869SN/A 10181858SN/A //DPRINTF(Rename,"[tid:%i]: %i lsq free\n",tid,num_free); 10195863Snate@binkert.org 10209420Sandreas.hansson@arm.com return num_free; 10219420Sandreas.hansson@arm.com} 10221858SN/A 1023955SN/Atemplate <class Impl> 1024955SN/Aunsigned 10251869SN/ADefaultRename<Impl>::validInsts() 10261869SN/A{ 10271869SN/A unsigned inst_count = 0; 10281869SN/A 10291869SN/A for (int i=0; i<fromDecode->size; i++) { 10305863Snate@binkert.org if (!fromDecode->insts[i]->squashed) 10315863Snate@binkert.org inst_count++; 10325863Snate@binkert.org } 10331869SN/A 10345863Snate@binkert.org return inst_count; 10351869SN/A} 10365863Snate@binkert.org 10371869SN/Atemplate <class Impl> 10381869SN/Avoid 10391869SN/ADefaultRename<Impl>::readStallSignals(unsigned tid) 10401869SN/A{ 10418483Sgblack@eecs.umich.edu if (fromIEW->iewBlock[tid]) { 10421869SN/A stalls[tid].iew = true; 10431869SN/A } 10441869SN/A 10451869SN/A if (fromIEW->iewUnblock[tid]) { 10465863Snate@binkert.org assert(stalls[tid].iew); 10475863Snate@binkert.org stalls[tid].iew = false; 10481869SN/A } 10495863Snate@binkert.org 10505863Snate@binkert.org if (fromCommit->commitBlock[tid]) { 10513356Sbinkertn@umich.edu stalls[tid].commit = true; 10523356Sbinkertn@umich.edu } 10533356Sbinkertn@umich.edu 10543356Sbinkertn@umich.edu if (fromCommit->commitUnblock[tid]) { 10553356Sbinkertn@umich.edu assert(stalls[tid].commit); 10564781Snate@binkert.org stalls[tid].commit = false; 10575863Snate@binkert.org } 10585863Snate@binkert.org} 10591869SN/A 10601869SN/Atemplate <class Impl> 10611869SN/Abool 10626121Snate@binkert.orgDefaultRename<Impl>::checkStall(unsigned tid) 10631869SN/A{ 10642638Sstever@eecs.umich.edu bool ret_val = false; 10656121Snate@binkert.org 10666121Snate@binkert.org if (stalls[tid].iew) { 10672638Sstever@eecs.umich.edu DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid); 10685749Scws3k@cs.virginia.edu ret_val = true; 10696121Snate@binkert.org } else if (stalls[tid].commit) { 10706121Snate@binkert.org DPRINTF(Rename,"[tid:%i]: Stall from Commit stage detected.\n", tid); 10715749Scws3k@cs.virginia.edu ret_val = true; 10729537Satgutier@umich.edu } else if (calcFreeROBEntries(tid) <= 0) { 10739537Satgutier@umich.edu DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid); 10749537Satgutier@umich.edu ret_val = true; 10759537Satgutier@umich.edu } else if (calcFreeIQEntries(tid) <= 0) { 10761869SN/A DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid); 10771869SN/A ret_val = true; 10783546Sgblack@eecs.umich.edu } else if (calcFreeLSQEntries(tid) <= 0) { 10793546Sgblack@eecs.umich.edu DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid); 10803546Sgblack@eecs.umich.edu ret_val = true; 10813546Sgblack@eecs.umich.edu } else if (renameMap[tid]->numFreeEntries() <= 0) { 10826121Snate@binkert.org DPRINTF(Rename,"[tid:%i]: Stall: RenameMap has 0 free entries.\n", tid); 10835863Snate@binkert.org ret_val = true; 10843546Sgblack@eecs.umich.edu } else if (renameStatus[tid] == SerializeStall && 10853546Sgblack@eecs.umich.edu (!emptyROB[tid] || instsInProgress[tid])) { 10863546Sgblack@eecs.umich.edu DPRINTF(Rename,"[tid:%i]: Stall: Serialize stall and ROB is not " 10873546Sgblack@eecs.umich.edu "empty.\n", 10884781Snate@binkert.org tid); 10894781Snate@binkert.org ret_val = true; 10906658Snate@binkert.org } 10916658Snate@binkert.org 10924781Snate@binkert.org return ret_val; 10933546Sgblack@eecs.umich.edu} 10943546Sgblack@eecs.umich.edu 10953546Sgblack@eecs.umich.edutemplate <class Impl> 10963546Sgblack@eecs.umich.eduvoid 10977756SAli.Saidi@ARM.comDefaultRename<Impl>::readFreeEntries(unsigned tid) 10987816Ssteve.reinhardt@amd.com{ 10993546Sgblack@eecs.umich.edu bool updated = false; 11003546Sgblack@eecs.umich.edu if (fromIEW->iewInfo[tid].usedIQ) { 11013546Sgblack@eecs.umich.edu freeEntries[tid].iqEntries = 11023546Sgblack@eecs.umich.edu fromIEW->iewInfo[tid].freeIQEntries; 11034202Sbinkertn@umich.edu updated = true; 11043546Sgblack@eecs.umich.edu } 11053546Sgblack@eecs.umich.edu 11063546Sgblack@eecs.umich.edu if (fromIEW->iewInfo[tid].usedLSQ) { 1107955SN/A freeEntries[tid].lsqEntries = 1108955SN/A fromIEW->iewInfo[tid].freeLSQEntries; 1109955SN/A updated = true; 1110955SN/A } 11115863Snate@binkert.org 11125863Snate@binkert.org if (fromCommit->commitInfo[tid].usedROB) { 11135343Sstever@gmail.com freeEntries[tid].robEntries = 11145343Sstever@gmail.com fromCommit->commitInfo[tid].freeROBEntries; 11156121Snate@binkert.org emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB; 11165863Snate@binkert.org updated = true; 11174773Snate@binkert.org } 11185863Snate@binkert.org 11192632Sstever@eecs.umich.edu DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, Free LSQ: %i\n", 11205863Snate@binkert.org tid, 11212023SN/A freeEntries[tid].iqEntries, 11225863Snate@binkert.org freeEntries[tid].robEntries, 11235863Snate@binkert.org freeEntries[tid].lsqEntries); 11245863Snate@binkert.org 11255863Snate@binkert.org DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n", 11265863Snate@binkert.org tid, instsInProgress[tid]); 11275863Snate@binkert.org} 11285863Snate@binkert.org 11295863Snate@binkert.orgtemplate <class Impl> 11305863Snate@binkert.orgbool 11312632Sstever@eecs.umich.eduDefaultRename<Impl>::checkSignalsAndUpdate(unsigned tid) 11325863Snate@binkert.org{ 11332023SN/A // Check if there's a squash signal, squash if there is 11342632Sstever@eecs.umich.edu // Check stall signals, block if necessary. 11355863Snate@binkert.org // If status was blocked 11365342Sstever@gmail.com // check if stall conditions have passed 11375863Snate@binkert.org // if so then go to unblocking 11382632Sstever@eecs.umich.edu // If status was Squashing 11395863Snate@binkert.org // check if squashing is not high. Switch to running this cycle. 11405863Snate@binkert.org // If status was serialize stall 11418267Ssteve.reinhardt@amd.com // check if ROB is empty and no insts are in flight to the ROB 11428120Sgblack@eecs.umich.edu 11438267Ssteve.reinhardt@amd.com readFreeEntries(tid); 11448267Ssteve.reinhardt@amd.com readStallSignals(tid); 11458267Ssteve.reinhardt@amd.com 11468267Ssteve.reinhardt@amd.com if (fromCommit->commitInfo[tid].squash) { 11478267Ssteve.reinhardt@amd.com DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from " 11488267Ssteve.reinhardt@amd.com "commit.\n", tid); 11498267Ssteve.reinhardt@amd.com 11508267Ssteve.reinhardt@amd.com squash(tid); 11518267Ssteve.reinhardt@amd.com 11525863Snate@binkert.org return true; 11535863Snate@binkert.org } 11545863Snate@binkert.org 11552632Sstever@eecs.umich.edu if (fromCommit->commitInfo[tid].robSquashing) { 11568267Ssteve.reinhardt@amd.com DPRINTF(Rename, "[tid:%u]: ROB is still squashing.\n", tid); 11578267Ssteve.reinhardt@amd.com 11588267Ssteve.reinhardt@amd.com renameStatus[tid] = Squashing; 11592632Sstever@eecs.umich.edu 11601888SN/A return true; 11615863Snate@binkert.org } 11625863Snate@binkert.org 11631858SN/A if (checkStall(tid)) { 11648120Sgblack@eecs.umich.edu return block(tid); 11658120Sgblack@eecs.umich.edu } 11667756SAli.Saidi@ARM.com 11672598SN/A if (renameStatus[tid] == Blocked) { 11685863Snate@binkert.org DPRINTF(Rename, "[tid:%u]: Done blocking, switching to unblocking.\n", 11691858SN/A tid); 11701858SN/A 11711858SN/A renameStatus[tid] = Unblocking; 11725863Snate@binkert.org 11731858SN/A unblock(tid); 11741858SN/A 11751858SN/A return true; 11765863Snate@binkert.org } 11771871SN/A 11781858SN/A if (renameStatus[tid] == Squashing) { 11791858SN/A // Switch status to running if rename isn't being told to block or 11801858SN/A // squash this cycle. 11811858SN/A DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n", 11825863Snate@binkert.org tid); 11835863Snate@binkert.org 11841869SN/A renameStatus[tid] = Running; 11851965SN/A 11867739Sgblack@eecs.umich.edu return false; 11871965SN/A } 11889045SAli.Saidi@ARM.com 11899045SAli.Saidi@ARM.com if (renameStatus[tid] == SerializeStall) { 11909045SAli.Saidi@ARM.com // Stall ends once the ROB is free. 11912761Sstever@eecs.umich.edu DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to " 11925863Snate@binkert.org "unblocking.\n", tid); 11931869SN/A 11945863Snate@binkert.org DynInstPtr serial_inst = serializeInst[tid]; 11952667Sstever@eecs.umich.edu 11961869SN/A renameStatus[tid] = Unblocking; 11971869SN/A 11982929Sktlim@umich.edu unblock(tid); 11992929Sktlim@umich.edu 12005863Snate@binkert.org DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with " 12012929Sktlim@umich.edu "PC %#x.\n", 1202955SN/A tid, serial_inst->seqNum, serial_inst->readPC()); 12038120Sgblack@eecs.umich.edu 12048120Sgblack@eecs.umich.edu // Put instruction into queue here. 12058120Sgblack@eecs.umich.edu serial_inst->clearSerializeBefore(); 12068120Sgblack@eecs.umich.edu 12078120Sgblack@eecs.umich.edu if (!skidBuffer[tid].empty()) { 12088120Sgblack@eecs.umich.edu skidBuffer[tid].push_front(serial_inst); 12098120Sgblack@eecs.umich.edu } else { 12108120Sgblack@eecs.umich.edu insts[tid].push_front(serial_inst); 12118120Sgblack@eecs.umich.edu } 12128120Sgblack@eecs.umich.edu 12138120Sgblack@eecs.umich.edu DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename." 12148120Sgblack@eecs.umich.edu " Adding to front of list.", tid); 1215 1216 serializeInst[tid] = NULL; 1217 1218 return true; 1219 } 1220 1221 // If we've reached this point, we have not gotten any signals that 1222 // cause rename to change its status. Rename remains the same as before. 1223 return false; 1224} 1225 1226template<class Impl> 1227void 1228DefaultRename<Impl>::serializeAfter(InstQueue &inst_list, 1229 unsigned tid) 1230{ 1231 if (inst_list.empty()) { 1232 // Mark a bit to say that I must serialize on the next instruction. 1233 serializeOnNextInst[tid] = true; 1234 return; 1235 } 1236 1237 // Set the next instruction as serializing. 1238 inst_list.front()->setSerializeBefore(); 1239} 1240 1241template <class Impl> 1242inline void 1243DefaultRename<Impl>::incrFullStat(const FullSource &source) 1244{ 1245 switch (source) { 1246 case ROB: 1247 ++renameROBFullEvents; 1248 break; 1249 case IQ: 1250 ++renameIQFullEvents; 1251 break; 1252 case LSQ: 1253 ++renameLSQFullEvents; 1254 break; 1255 default: 1256 panic("Rename full stall stat should be incremented for a reason!"); 1257 break; 1258 } 1259} 1260 1261template <class Impl> 1262void 1263DefaultRename<Impl>::dumpHistory() 1264{ 1265 typename list<RenameHistory>::iterator buf_it; 1266 1267 for (int i = 0; i < numThreads; i++) { 1268 1269 buf_it = historyBuffer[i].begin(); 1270 1271 while (buf_it != historyBuffer[i].end()) { 1272 cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys " 1273 "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg, 1274 (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg); 1275 1276 buf_it++; 1277 } 1278 } 1279} 1280