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