rename_impl.hh revision 13598
11689SN/A/* 27598Sminkyu.jeong@arm.com * Copyright (c) 2010-2012, 2014-2016 ARM Limited 37598Sminkyu.jeong@arm.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 47598Sminkyu.jeong@arm.com * All rights reserved. 57598Sminkyu.jeong@arm.com * 67598Sminkyu.jeong@arm.com * The license below extends only to copyright in the software and shall 77598Sminkyu.jeong@arm.com * not be construed as granting a license to any other intellectual 87598Sminkyu.jeong@arm.com * property including but not limited to intellectual property relating 97598Sminkyu.jeong@arm.com * to a hardware implementation of the functionality of the software 107598Sminkyu.jeong@arm.com * licensed hereunder. You may use the software subject to the license 117598Sminkyu.jeong@arm.com * terms below provided that you ensure that this notice is replicated 127598Sminkyu.jeong@arm.com * unmodified and in its entirety in all distributions of the software, 137598Sminkyu.jeong@arm.com * modified or unmodified, in source code or in binary form. 142326SN/A * 151689SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 161689SN/A * All rights reserved. 171689SN/A * 181689SN/A * Redistribution and use in source and binary forms, with or without 191689SN/A * modification, are permitted provided that the following conditions are 201689SN/A * met: redistributions of source code must retain the above copyright 211689SN/A * notice, this list of conditions and the following disclaimer; 221689SN/A * redistributions in binary form must reproduce the above copyright 231689SN/A * notice, this list of conditions and the following disclaimer in the 241689SN/A * documentation and/or other materials provided with the distribution; 251689SN/A * neither the name of the copyright holders nor the names of its 261689SN/A * contributors may be used to endorse or promote products derived from 271689SN/A * this software without specific prior written permission. 281689SN/A * 291689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 301689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 311689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 321689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 331689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 341689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 351689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 361689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 371689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 381689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392665Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 411689SN/A * Authors: Kevin Lim 421689SN/A * Korey Sewell 431060SN/A */ 441060SN/A 451689SN/A#ifndef __CPU_O3_RENAME_IMPL_HH__ 461060SN/A#define __CPU_O3_RENAME_IMPL_HH__ 471060SN/A 481060SN/A#include <list> 497813Ssteve.reinhardt@amd.com 506658Snate@binkert.org#include "arch/isa_traits.hh" 512292SN/A#include "arch/registers.hh" 521717SN/A#include "config/the_isa.hh" 535529Snate@binkert.org#include "cpu/o3/rename.hh" 541060SN/A#include "cpu/reg_class.hh" 556221Snate@binkert.org#include "debug/Activity.hh" 566221Snate@binkert.org#include "debug/Rename.hh" 571681SN/A#include "debug/O3PipeView.hh" 585529Snate@binkert.org#include "params/DerivO3CPU.hh" 592873Sktlim@umich.edu 604329Sktlim@umich.eduusing namespace std; 614329Sktlim@umich.edu 624329Sktlim@umich.edutemplate <class Impl> 632292SN/ADefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params) 642292SN/A : cpu(_cpu), 652292SN/A iewToRenameDelay(params->iewToRenameDelay), 662292SN/A decodeToRenameDelay(params->decodeToRenameDelay), 672820Sktlim@umich.edu commitToRenameDelay(params->commitToRenameDelay), 682292SN/A renameWidth(params->renameWidth), 692820Sktlim@umich.edu commitWidth(params->commitWidth), 702820Sktlim@umich.edu numThreads(params->numThreads) 715529Snate@binkert.org{ 722307SN/A if (renameWidth > Impl::MaxWidth) 731060SN/A fatal("renameWidth (%d) is larger than compiled limit (%d),\n" 742292SN/A "\tincrease MaxWidth in src/cpu/o3/impl.hh\n", 752292SN/A renameWidth, static_cast<int>(Impl::MaxWidth)); 762292SN/A 771060SN/A // @todo: Make into a parameter. 781060SN/A skidBufferMax = (decodeToRenameDelay + 1) * params->decodeWidth; 791060SN/A for (uint32_t tid = 0; tid < Impl::MaxThreads; tid++) { 801060SN/A renameStatus[tid] = Idle; 811060SN/A renameMap[tid] = nullptr; 821060SN/A instsInProgress[tid] = 0; 831681SN/A loadsInProgress[tid] = 0; 846221Snate@binkert.org storesInProgress[tid] = 0; 856221Snate@binkert.org freeEntries[tid] = {0, 0, 0, 0}; 866221Snate@binkert.org emptyROB[tid] = true; 876221Snate@binkert.org stalls[tid] = {false, false}; 882292SN/A serializeInst[tid] = nullptr; 892292SN/A serializeOnNextInst[tid] = false; 902820Sktlim@umich.edu } 912820Sktlim@umich.edu} 922292SN/A 932292SN/Atemplate <class Impl> 942820Sktlim@umich.edustd::string 952820Sktlim@umich.eduDefaultRename<Impl>::name() const 962292SN/A{ 972292SN/A return cpu->name() + ".rename"; 982292SN/A} 992292SN/A 1002292SN/Atemplate <class Impl> 1012292SN/Avoid 1022292SN/ADefaultRename<Impl>::regStats() 1032292SN/A{ 1041060SN/A renameSquashCycles 1051060SN/A .name(name() + ".SquashCycles") 1061681SN/A .desc("Number of cycles rename is squashing") 1071062SN/A .prereq(renameSquashCycles); 1082292SN/A renameIdleCycles 1091062SN/A .name(name() + ".IdleCycles") 1102301SN/A .desc("Number of cycles rename is idle") 1112301SN/A .prereq(renameIdleCycles); 1121062SN/A renameBlockCycles 1132727Sktlim@umich.edu .name(name() + ".BlockCycles") 1141062SN/A .desc("Number of cycles rename is blocking") 1151062SN/A .prereq(renameBlockCycles); 1161062SN/A renameSerializeStallCycles 1171062SN/A .name(name() + ".serializeStallCycles") 1181062SN/A .desc("count of cycles rename stalled for serializing inst") 1191062SN/A .flags(Stats::total); 1201062SN/A renameRunCycles 1211062SN/A .name(name() + ".RunCycles") 1221062SN/A .desc("Number of cycles rename is running") 1231062SN/A .prereq(renameIdleCycles); 1241062SN/A renameUnblockCycles 1251062SN/A .name(name() + ".UnblockCycles") 1261062SN/A .desc("Number of cycles rename is unblocking") 1271062SN/A .prereq(renameUnblockCycles); 1281062SN/A renameRenamedInsts 1291062SN/A .name(name() + ".RenamedInsts") 1301062SN/A .desc("Number of instructions processed by rename") 1311062SN/A .prereq(renameRenamedInsts); 1321062SN/A renameSquashedInsts 1331062SN/A .name(name() + ".SquashedInsts") 1341062SN/A .desc("Number of squashed instructions processed by rename") 1351062SN/A .prereq(renameSquashedInsts); 1361062SN/A renameROBFullEvents 1371062SN/A .name(name() + ".ROBFullEvents") 1381062SN/A .desc("Number of times rename has blocked due to ROB full") 1391062SN/A .prereq(renameROBFullEvents); 1401062SN/A renameIQFullEvents 1411062SN/A .name(name() + ".IQFullEvents") 1421062SN/A .desc("Number of times rename has blocked due to IQ full") 1431062SN/A .prereq(renameIQFullEvents); 1441062SN/A renameLQFullEvents 1451062SN/A .name(name() + ".LQFullEvents") 1461062SN/A .desc("Number of times rename has blocked due to LQ full") 1471062SN/A .prereq(renameLQFullEvents); 1481062SN/A renameSQFullEvents 1491062SN/A .name(name() + ".SQFullEvents") 1501062SN/A .desc("Number of times rename has blocked due to SQ full") 1511062SN/A .prereq(renameSQFullEvents); 1521062SN/A renameFullRegistersEvents 1531062SN/A .name(name() + ".FullRegisterEvents") 1541062SN/A .desc("Number of times there has been no free registers") 1552292SN/A .prereq(renameFullRegistersEvents); 1562292SN/A renameRenamedOperands 1572292SN/A .name(name() + ".RenamedOperands") 1582292SN/A .desc("Number of destination operands rename has renamed") 1591062SN/A .prereq(renameRenamedOperands); 1601062SN/A renameRenameLookups 1611062SN/A .name(name() + ".RenameLookups") 1621062SN/A .desc("Number of register rename lookups that rename has made") 1631062SN/A .prereq(renameRenameLookups); 1641062SN/A renameCommittedMaps 1651062SN/A .name(name() + ".CommittedMaps") 1662292SN/A .desc("Number of HB maps that are committed") 1672292SN/A .prereq(renameCommittedMaps); 1682292SN/A renameUndoneMaps 1692292SN/A .name(name() + ".UndoneMaps") 1702292SN/A .desc("Number of HB maps that are undone due to squashing") 1712292SN/A .prereq(renameUndoneMaps); 1722292SN/A renamedSerializing 1732292SN/A .name(name() + ".serializingInsts") 1742292SN/A .desc("count of serializing insts renamed") 1752292SN/A .flags(Stats::total) 1762301SN/A ; 1772727Sktlim@umich.edu renamedTempSerializing 1782353SN/A .name(name() + ".tempSerializingInsts") 1792727Sktlim@umich.edu .desc("count of temporary serializing insts renamed") 1802727Sktlim@umich.edu .flags(Stats::total) 1812727Sktlim@umich.edu ; 1826221Snate@binkert.org renameSkidInsts 1832353SN/A .name(name() + ".skidInsts") 1842727Sktlim@umich.edu .desc("count of insts added to the skid buffer") 1852727Sktlim@umich.edu .flags(Stats::total) 1862727Sktlim@umich.edu ; 1872727Sktlim@umich.edu intRenameLookups 1882353SN/A .name(name() + ".int_rename_lookups") 1892727Sktlim@umich.edu .desc("Number of integer rename lookups") 1902727Sktlim@umich.edu .prereq(intRenameLookups); 1912727Sktlim@umich.edu fpRenameLookups 1926221Snate@binkert.org .name(name() + ".fp_rename_lookups") 1932301SN/A .desc("Number of floating rename lookups") 1942301SN/A .prereq(fpRenameLookups); 1952727Sktlim@umich.edu vecRenameLookups 1962301SN/A .name(name() + ".vec_rename_lookups") 1972727Sktlim@umich.edu .desc("Number of vector rename lookups") 1986221Snate@binkert.org .prereq(vecRenameLookups); 1992301SN/A} 2002301SN/A 2012727Sktlim@umich.edutemplate <class Impl> 2022301SN/Avoid 2032727Sktlim@umich.eduDefaultRename<Impl>::regProbePoints() 2046221Snate@binkert.org{ 2052301SN/A ppRename = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Rename"); 2062301SN/A ppSquashInRename = new ProbePointArg<SeqNumRegPair>(cpu->getProbeManager(), 2072727Sktlim@umich.edu "SquashInRename"); 2082301SN/A} 2092727Sktlim@umich.edu 2106221Snate@binkert.orgtemplate <class Impl> 2112301SN/Avoid 2122301SN/ADefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 2132727Sktlim@umich.edu{ 2142301SN/A timeBuffer = tb_ptr; 2152301SN/A 2162301SN/A // Setup wire to read information from time buffer, from IEW stage. 2172301SN/A fromIEW = timeBuffer->getWire(-iewToRenameDelay); 2182727Sktlim@umich.edu 2192727Sktlim@umich.edu // Setup wire to read infromation from time buffer, from commit stage. 2202727Sktlim@umich.edu fromCommit = timeBuffer->getWire(-commitToRenameDelay); 2212727Sktlim@umich.edu 2222727Sktlim@umich.edu // Setup wire to write information to previous stages. 2232727Sktlim@umich.edu toDecode = timeBuffer->getWire(0); 2242727Sktlim@umich.edu} 2252727Sktlim@umich.edu 2262727Sktlim@umich.edutemplate <class Impl> 2272301SN/Avoid 2282301SN/ADefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 2296221Snate@binkert.org{ 2302301SN/A renameQueue = rq_ptr; 2312301SN/A 2322727Sktlim@umich.edu // Setup wire to write information to future stages. 2332301SN/A toIEW = renameQueue->getWire(0); 2342326SN/A} 2356221Snate@binkert.org 2362301SN/Atemplate <class Impl> 2372301SN/Avoid 2382727Sktlim@umich.eduDefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) 2392301SN/A{ 2402326SN/A decodeQueue = dq_ptr; 2416221Snate@binkert.org 2422301SN/A // Setup wire to get information from decode. 2432301SN/A fromDecode = decodeQueue->getWire(-decodeToRenameDelay); 2442727Sktlim@umich.edu} 2452301SN/A 2462326SN/Atemplate <class Impl> 2476221Snate@binkert.orgvoid 2482301SN/ADefaultRename<Impl>::startupStage() 2492301SN/A{ 2502727Sktlim@umich.edu resetStage(); 2512301SN/A} 2522326SN/A 2536221Snate@binkert.orgtemplate <class Impl> 2542301SN/Avoid 2552301SN/ADefaultRename<Impl>::resetStage() 2562727Sktlim@umich.edu{ 2572301SN/A _status = Inactive; 2582326SN/A 2592301SN/A resumeSerialize = false; 2602301SN/A resumeUnblocking = false; 2612727Sktlim@umich.edu 2622301SN/A // Grab the number of free entries directly from the stages. 2632326SN/A for (ThreadID tid = 0; tid < numThreads; tid++) { 2642301SN/A renameStatus[tid] = Idle; 2652326SN/A 2662301SN/A freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid); 2672301SN/A freeEntries[tid].lqEntries = iew_ptr->ldstQueue.numFreeLoadEntries(tid); 2682727Sktlim@umich.edu freeEntries[tid].sqEntries = iew_ptr->ldstQueue.numFreeStoreEntries(tid); 2692301SN/A freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid); 2702326SN/A emptyROB[tid] = true; 2712301SN/A 2722326SN/A stalls[tid].iew = false; 2732301SN/A serializeInst[tid] = NULL; 2742301SN/A 2752727Sktlim@umich.edu instsInProgress[tid] = 0; 2762326SN/A loadsInProgress[tid] = 0; 2771062SN/A storesInProgress[tid] = 0; 2781062SN/A 2791681SN/A serializeOnNextInst[tid] = false; 2801060SN/A } 2812292SN/A} 2821060SN/A 2836221Snate@binkert.orgtemplate<class Impl> 2842292SN/Avoid 2852292SN/ADefaultRename<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 2862292SN/A{ 2872292SN/A activeThreads = at_ptr; 2882292SN/A} 2892292SN/A 2902292SN/A 2912292SN/Atemplate <class Impl> 2922292SN/Avoid 2932733Sktlim@umich.eduDefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[]) 2941060SN/A{ 2951060SN/A for (ThreadID tid = 0; tid < numThreads; tid++) 2961681SN/A renameMap[tid] = &rm_ptr[tid]; 2971060SN/A} 2982292SN/A 2991060SN/Atemplate <class Impl> 3001060SN/Avoid 3011060SN/ADefaultRename<Impl>::setFreeList(FreeList *fl_ptr) 3021060SN/A{ 3031060SN/A freeList = fl_ptr; 3041060SN/A} 3051060SN/A 3061060SN/Atemplate<class Impl> 3071060SN/Avoid 3082292SN/ADefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard) 3092292SN/A{ 3101060SN/A scoreboard = _scoreboard; 3111060SN/A} 3121060SN/A 3131060SN/Atemplate <class Impl> 3141681SN/Abool 3151060SN/ADefaultRename<Impl>::isDrained() const 3162292SN/A{ 3171060SN/A for (ThreadID tid = 0; tid < numThreads; tid++) { 3181060SN/A if (instsInProgress[tid] != 0 || 3191060SN/A !historyBuffer[tid].empty() || 3201060SN/A !skidBuffer[tid].empty() || 3211060SN/A !insts[tid].empty() || 3221060SN/A (renameStatus[tid] != Idle && renameStatus[tid] != Running)) 3231060SN/A return false; 3241681SN/A } 3251060SN/A return true; 3262292SN/A} 3271060SN/A 3281060SN/Atemplate <class Impl> 3291060SN/Avoid 3301060SN/ADefaultRename<Impl>::takeOverFrom() 3311060SN/A{ 3321060SN/A resetStage(); 3331060SN/A} 3341681SN/A 3351060SN/Atemplate <class Impl> 3366221Snate@binkert.orgvoid 3371060SN/ADefaultRename<Impl>::drainSanityCheck() const 3382292SN/A{ 3392292SN/A for (ThreadID tid = 0; tid < numThreads; tid++) { 3402292SN/A assert(historyBuffer[tid].empty()); 3412292SN/A assert(insts[tid].empty()); 3421060SN/A assert(skidBuffer[tid].empty()); 3431060SN/A assert(instsInProgress[tid] == 0); 3441681SN/A } 3451060SN/A} 3462292SN/A 3471060SN/Atemplate <class Impl> 3482292SN/Avoid 3491060SN/ADefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, ThreadID tid) 3501060SN/A{ 3512307SN/A DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid); 3522863Sktlim@umich.edu 3532843Sktlim@umich.edu // Clear the stall signal if rename was blocked or unblocking before. 3542307SN/A // If it still needs to block, the blocking should happen the next 3552843Sktlim@umich.edu // cycle and there should be space to hold everything due to the squash. 3562843Sktlim@umich.edu if (renameStatus[tid] == Blocked || 3572863Sktlim@umich.edu renameStatus[tid] == Unblocking) { 3581681SN/A toDecode->renameUnblock[tid] = 1; 3591681SN/A 3602316SN/A resumeSerialize = false; 3611681SN/A serializeInst[tid] = NULL; 3622843Sktlim@umich.edu } else if (renameStatus[tid] == SerializeStall) { 3632843Sktlim@umich.edu if (serializeInst[tid]->seqNum <= squash_seq_num) { 3642843Sktlim@umich.edu DPRINTF(Rename, "Rename will resume serializing after squash\n"); 3652843Sktlim@umich.edu resumeSerialize = true; 3662843Sktlim@umich.edu assert(serializeInst[tid]); 3672843Sktlim@umich.edu } else { 3682843Sktlim@umich.edu resumeSerialize = false; 3691681SN/A toDecode->renameUnblock[tid] = 1; 3702348SN/A 3712307SN/A serializeInst[tid] = NULL; 3722367SN/A } 3732367SN/A } 3741681SN/A 3752307SN/A // Set the status to Squashing. 3762307SN/A renameStatus[tid] = Squashing; 3772307SN/A 3782307SN/A // Squash any instructions from decode. 3796221Snate@binkert.org for (int i=0; i<fromDecode->size; i++) { 3806221Snate@binkert.org if (fromDecode->insts[i]->threadNumber == tid && 3816221Snate@binkert.org fromDecode->insts[i]->seqNum > squash_seq_num) { 3826221Snate@binkert.org fromDecode->insts[i]->setSquashed(); 3836221Snate@binkert.org wroteToTimeBuffer = true; 3842307SN/A } 3851681SN/A 3861681SN/A } 3872307SN/A 3881681SN/A // Clear the instruction list and skid buffer in case they have any 3892307SN/A // insts in them. 3901060SN/A insts[tid].clear(); 3912348SN/A 3922307SN/A // Clear the skid buffer in case it has any data in it. 3932307SN/A skidBuffer[tid].clear(); 3942307SN/A 3952307SN/A doSquash(squash_seq_num, tid); 3961060SN/A} 3972307SN/A 3982307SN/Atemplate <class Impl> 3992307SN/Avoid 4001060SN/ADefaultRename<Impl>::tick() 4012307SN/A{ 4022307SN/A wroteToTimeBuffer = false; 4031060SN/A 4046221Snate@binkert.org blockThisCycle = false; 4056221Snate@binkert.org 4066221Snate@binkert.org bool status_change = false; 4076221Snate@binkert.org 4082307SN/A toIEWIndex = 0; 4091060SN/A 4102307SN/A sortInsts(); 4112307SN/A 4122873Sktlim@umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4132307SN/A list<ThreadID>::iterator end = activeThreads->end(); 4141060SN/A 4151060SN/A // Check stall and squash signals. 4161060SN/A while (threads != end) { 4171681SN/A ThreadID tid = *threads++; 4181060SN/A 4196221Snate@binkert.org DPRINTF(Rename, "Processing [tid:%i]\n", tid); 4202107SN/A 4216221Snate@binkert.org status_change = checkSignalsAndUpdate(tid) || status_change; 4222107SN/A 4232292SN/A rename(status_change, tid); 4242292SN/A } 4252107SN/A 4262292SN/A if (status_change) { 4272326SN/A updateStatus(); 4282292SN/A } 4292107SN/A 4302292SN/A if (wroteToTimeBuffer) { 4312935Sksewell@umich.edu DPRINTF(Activity, "Activity this cycle.\n"); 4324632Sgblack@eecs.umich.edu cpu->activityThisCycle(); 4332935Sksewell@umich.edu } 4342292SN/A 4352292SN/A threads = activeThreads->begin(); 4362292SN/A 4372292SN/A while (threads != end) { 4382292SN/A ThreadID tid = *threads++; 4392107SN/A 4402292SN/A // If we committed this cycle then doneSeqNum will be > 0 4412107SN/A if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 4422292SN/A !fromCommit->commitInfo[tid].squash && 4432292SN/A renameStatus[tid] != Squashing) { 4442107SN/A 4452702Sktlim@umich.edu removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum, 4462107SN/A tid); 4472107SN/A } 4482107SN/A } 4492107SN/A 4506221Snate@binkert.org // @todo: make into updateProgress function 4512292SN/A for (ThreadID tid = 0; tid < numThreads; tid++) { 4527720Sgblack@eecs.umich.edu instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched; 4537720Sgblack@eecs.umich.edu loadsInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToLQ; 4542292SN/A storesInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToSQ; 4557852SMatt.Horsnell@arm.com assert(loadsInProgress[tid] >= 0); 4567852SMatt.Horsnell@arm.com assert(storesInProgress[tid] >= 0); 4577852SMatt.Horsnell@arm.com assert(instsInProgress[tid] >=0); 4587852SMatt.Horsnell@arm.com } 4597852SMatt.Horsnell@arm.com 4602935Sksewell@umich.edu} 4617852SMatt.Horsnell@arm.com 4627852SMatt.Horsnell@arm.comtemplate<class Impl> 4632292SN/Avoid 4647852SMatt.Horsnell@arm.comDefaultRename<Impl>::rename(bool &status_change, ThreadID tid) 4657852SMatt.Horsnell@arm.com{ 4667852SMatt.Horsnell@arm.com // If status is Running or idle, 4672292SN/A // call renameInsts() 4687852SMatt.Horsnell@arm.com // If status is Unblocking, 4697852SMatt.Horsnell@arm.com // buffer any instructions coming from decode 4707852SMatt.Horsnell@arm.com // continue trying to empty skid buffer 4712292SN/A // check if stall conditions have passed 4722292SN/A 4732292SN/A if (renameStatus[tid] == Blocked) { 4742292SN/A ++renameBlockCycles; 4756221Snate@binkert.org } else if (renameStatus[tid] == Squashing) { 4762292SN/A ++renameSquashCycles; 4772292SN/A } else if (renameStatus[tid] == SerializeStall) { 4787720Sgblack@eecs.umich.edu ++renameSerializeStallCycles; 4792292SN/A // If we are currently in SerializeStall and resumeSerialize 4807852SMatt.Horsnell@arm.com // was set, then that means that we are resuming serializing 4817852SMatt.Horsnell@arm.com // this cycle. Tell the previous stages to block. 4827852SMatt.Horsnell@arm.com if (resumeSerialize) { 4837852SMatt.Horsnell@arm.com resumeSerialize = false; 4847852SMatt.Horsnell@arm.com block(tid); 4857852SMatt.Horsnell@arm.com toDecode->renameUnblock[tid] = false; 4867852SMatt.Horsnell@arm.com } 4878137SAli.Saidi@ARM.com } else if (renameStatus[tid] == Unblocking) { 4882292SN/A if (resumeUnblocking) { 4897852SMatt.Horsnell@arm.com block(tid); 4902292SN/A resumeUnblocking = false; 4917852SMatt.Horsnell@arm.com toDecode->renameUnblock[tid] = false; 4927852SMatt.Horsnell@arm.com } 4932292SN/A } 4942292SN/A 4952292SN/A if (renameStatus[tid] == Running || 4962292SN/A renameStatus[tid] == Idle) { 4976221Snate@binkert.org DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run " 4982292SN/A "stage.\n", tid); 4992292SN/A 5007720Sgblack@eecs.umich.edu renameInsts(tid); 5017852SMatt.Horsnell@arm.com } else if (renameStatus[tid] == Unblocking) { 5027852SMatt.Horsnell@arm.com renameInsts(tid); 5037852SMatt.Horsnell@arm.com 5042292SN/A if (validInsts()) { 5057852SMatt.Horsnell@arm.com // Add the current inputs to the skid buffer so they can be 5067852SMatt.Horsnell@arm.com // reprocessed when this stage unblocks. 5078137SAli.Saidi@ARM.com skidInsert(tid); 5082292SN/A } 5097852SMatt.Horsnell@arm.com 5107852SMatt.Horsnell@arm.com // If we switched over to blocking, then there's a potential for 5112292SN/A // an overall status change. 5127852SMatt.Horsnell@arm.com status_change = unblock(tid) || status_change || blockThisCycle; 5132292SN/A } 5147852SMatt.Horsnell@arm.com} 5157852SMatt.Horsnell@arm.com 5162292SN/Atemplate <class Impl> 5172292SN/Avoid 5182292SN/ADefaultRename<Impl>::renameInsts(ThreadID tid) 5192292SN/A{ 5206221Snate@binkert.org // Instructions can be either in the skid buffer or the queue of 5212292SN/A // instructions coming from decode, depending on the status. 5222292SN/A int insts_available = renameStatus[tid] == Unblocking ? 5232292SN/A skidBuffer[tid].size() : insts[tid].size(); 5242292SN/A 5252292SN/A // Check the decode queue to see if instructions are available. 5262292SN/A // If there are no available instructions to rename, then do nothing. 5272292SN/A if (insts_available == 0) { 5282292SN/A DPRINTF(Rename, "[tid:%u]: Nothing to do, breaking out early.\n", 5292292SN/A tid); 5302292SN/A // Should I change status to idle? 5312292SN/A ++renameIdleCycles; 5322292SN/A return; 5332292SN/A } else if (renameStatus[tid] == Unblocking) { 5342292SN/A ++renameUnblockCycles; 5352292SN/A } else if (renameStatus[tid] == Running) { 5362292SN/A ++renameRunCycles; 5372292SN/A } 5382292SN/A 5396221Snate@binkert.org // Will have to do a different calculation for the number of free 5402292SN/A // entries. 5412292SN/A int free_rob_entries = calcFreeROBEntries(tid); 5422292SN/A int free_iq_entries = calcFreeIQEntries(tid); 5432292SN/A int min_free_entries = free_rob_entries; 5442292SN/A 5452292SN/A FullSource source = ROB; 5462292SN/A 5472292SN/A if (free_iq_entries < min_free_entries) { 5482292SN/A min_free_entries = free_iq_entries; 5492292SN/A source = IQ; 5502292SN/A } 5512292SN/A 5522292SN/A // Check if there's any space left. 5532292SN/A if (min_free_entries <= 0) { 5542292SN/A DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/ " 5552292SN/A "entries.\n" 5562292SN/A "ROB has %i free entries.\n" 5571060SN/A "IQ has %i free entries.\n", 5581681SN/A tid, 5591060SN/A free_rob_entries, 5601060SN/A free_iq_entries); 5612292SN/A 5622292SN/A blockThisCycle = true; 5632292SN/A 5642292SN/A block(tid); 5652292SN/A 5662292SN/A incrFullStat(source); 5671681SN/A 5681681SN/A return; 5691060SN/A } else if (min_free_entries < insts_available) { 5702292SN/A DPRINTF(Rename, "[tid:%u]: Will have to block this cycle." 5711060SN/A "%i insts available, but only %i insts can be " 5722292SN/A "renamed due to ROB/IQ/LSQ limits.\n", 5732292SN/A tid, insts_available, min_free_entries); 5741060SN/A 5752292SN/A insts_available = min_free_entries; 5762292SN/A 5772292SN/A blockThisCycle = true; 5782292SN/A 5793221Sktlim@umich.edu incrFullStat(source); 5803221Sktlim@umich.edu } 5813221Sktlim@umich.edu 5823221Sktlim@umich.edu InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ? 5833221Sktlim@umich.edu skidBuffer[tid] : insts[tid]; 5842292SN/A 5852292SN/A DPRINTF(Rename, "[tid:%u]: %i available instructions to " 5862292SN/A "send iew.\n", tid, insts_available); 5872292SN/A 5882326SN/A DPRINTF(Rename, "[tid:%u]: %i insts pipelining from Rename | %i insts " 5892292SN/A "dispatched to IQ last cycle.\n", 5902292SN/A tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched); 5912820Sktlim@umich.edu 5922292SN/A // Handle serializing the next instruction if necessary. 5932292SN/A if (serializeOnNextInst[tid]) { 5942292SN/A if (emptyROB[tid] && instsInProgress[tid] == 0) { 5952292SN/A // ROB already empty; no need to serialize. 5962353SN/A serializeOnNextInst[tid] = false; 5972292SN/A } else if (!insts_to_rename.empty()) { 5982292SN/A insts_to_rename.front()->setSerializeBefore(); 5992353SN/A } 6002353SN/A } 6012292SN/A 6022292SN/A int renamed_insts = 0; 6032292SN/A 6042292SN/A while (insts_available > 0 && toIEWIndex < renameWidth) { 6052292SN/A DPRINTF(Rename, "[tid:%u]: Sending instructions to IEW.\n", tid); 6062292SN/A 6072292SN/A assert(!insts_to_rename.empty()); 6082292SN/A 6092292SN/A DynInstPtr inst = insts_to_rename.front(); 6102292SN/A 6112292SN/A //For all kind of instructions, check ROB and IQ first 6122292SN/A //For load instruction, check LQ size and take into account the inflight loads 6132731Sktlim@umich.edu //For store instruction, check SQ size and take into account the inflight stores 6142292SN/A 6152292SN/A if (inst->isLoad()) { 6162292SN/A if (calcFreeLQEntries(tid) <= 0) { 6172292SN/A DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free LQ\n"); 6182292SN/A source = LQ; 6192292SN/A incrFullStat(source); 6202292SN/A break; 6212292SN/A } 6226221Snate@binkert.org } 6232292SN/A 6242292SN/A if (inst->isStore()) { 6252292SN/A if (calcFreeSQEntries(tid) <= 0) { 6262292SN/A DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free SQ\n"); 6272292SN/A source = SQ; 6282292SN/A incrFullStat(source); 6292292SN/A break; 6302292SN/A } 6317720Sgblack@eecs.umich.edu } 6322292SN/A 6337720Sgblack@eecs.umich.edu insts_to_rename.pop_front(); 6342292SN/A 6352292SN/A if (renameStatus[tid] == Unblocking) { 6362292SN/A DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%s from rename " 6372292SN/A "skidBuffer\n", tid, inst->seqNum, inst->pcState()); 6382292SN/A } 6392292SN/A 6402292SN/A if (inst->isSquashed()) { 6412292SN/A DPRINTF(Rename, "[tid:%u]: instruction %i with PC %s is " 6422292SN/A "squashed, skipping.\n", tid, inst->seqNum, 6432292SN/A inst->pcState()); 6442292SN/A 6452292SN/A ++renameSquashedInsts; 6462292SN/A 6472292SN/A // Decrement how many instructions are available. 6486221Snate@binkert.org --insts_available; 6496221Snate@binkert.org 6502292SN/A continue; 6513867Sbinkertn@umich.edu } 6526221Snate@binkert.org 6533867Sbinkertn@umich.edu DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with " 6542292SN/A "PC %s.\n", tid, inst->seqNum, inst->pcState()); 6552292SN/A 6562292SN/A // Check here to make sure there are enough destination registers 6572292SN/A // to rename to. Otherwise block. 6582292SN/A if (!renameMap[tid]->canRename(inst->numIntDestRegs(), 6592292SN/A inst->numFPDestRegs(), 6602292SN/A inst->numVecDestRegs(), 6612292SN/A inst->numVecElemDestRegs(), 6622292SN/A inst->numCCDestRegs())) { 6632292SN/A DPRINTF(Rename, "Blocking due to lack of free " 6642292SN/A "physical registers to rename to.\n"); 6656221Snate@binkert.org blockThisCycle = true; 6666221Snate@binkert.org insts_to_rename.push_front(inst); 6672292SN/A ++renameFullRegistersEvents; 6683867Sbinkertn@umich.edu 6696221Snate@binkert.org break; 6703867Sbinkertn@umich.edu } 6713867Sbinkertn@umich.edu 6722292SN/A // Handle serializeAfter/serializeBefore instructions. 6732292SN/A // serializeAfter marks the next instruction as serializeBefore. 6742292SN/A // serializeBefore makes the instruction wait in rename until the ROB 6752292SN/A // is empty. 6761062SN/A 6771062SN/A // In this model, IPR accesses are serialize before 6781681SN/A // instructions, and store conditionals are serialize after 6791062SN/A // instructions. This is mainly due to lack of support for 6802292SN/A // out-of-order operations of either of those classes of 6811062SN/A // instructions. 6822292SN/A if ((inst->isIprAccess() || inst->isSerializeBefore()) && 6831062SN/A !inst->isSerializeHandled()) { 6846221Snate@binkert.org DPRINTF(Rename, "Serialize before instruction encountered.\n"); 6856221Snate@binkert.org 6861062SN/A if (!inst->isTempSerializeBefore()) { 6873867Sbinkertn@umich.edu renamedSerializing++; 6886221Snate@binkert.org inst->setSerializeHandled(); 6891062SN/A } else { 6902292SN/A renamedTempSerializing++; 6912292SN/A } 6922292SN/A 6932292SN/A // Change status over to SerializeStall so that other stages know 6942292SN/A // what this is blocked on. 6951062SN/A renameStatus[tid] = SerializeStall; 6962292SN/A 6972292SN/A serializeInst[tid] = inst; 6982292SN/A 6997897Shestness@cs.utexas.edu blockThisCycle = true; 7002292SN/A 7012292SN/A break; 7022292SN/A } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) && 7031062SN/A !inst->isSerializeHandled()) { 7042292SN/A DPRINTF(Rename, "Serialize after instruction encountered.\n"); 7051062SN/A 7062292SN/A renamedSerializing++; 7072292SN/A 7082292SN/A inst->setSerializeHandled(); 7092292SN/A 7102292SN/A serializeAfter(insts_to_rename, tid); 7112292SN/A } 7121062SN/A 7132292SN/A renameSrcRegs(inst, inst->threadNumber); 7141062SN/A 7152292SN/A renameDestRegs(inst, inst->threadNumber); 7161062SN/A 7171062SN/A if (inst->isLoad()) { 7181062SN/A loadsInProgress[tid]++; 7191681SN/A } 7201062SN/A if (inst->isStore()) { 7212292SN/A storesInProgress[tid]++; 7221062SN/A } 7232292SN/A ++renamed_insts; 7242292SN/A // Notify potential listeners that source and destination registers for 7252292SN/A // this instruction have been renamed. 7261062SN/A ppRename->notify(inst); 7272292SN/A 7282292SN/A // Put instruction in rename queue. 7296221Snate@binkert.org toIEW->insts[toIEWIndex] = inst; 7302292SN/A ++(toIEW->size); 7312292SN/A 7322292SN/A // Increment which instruction we're on. 7332292SN/A ++toIEWIndex; 7341062SN/A 7352292SN/A // Decrement how many instructions are available. 7362292SN/A --insts_available; 7372292SN/A } 7382292SN/A 7392292SN/A instsInProgress[tid] += renamed_insts; 7402292SN/A renameRenamedInsts += renamed_insts; 7412292SN/A 7422292SN/A // If we wrote to the time buffer, record this. 7436221Snate@binkert.org if (toIEWIndex) { 7442292SN/A wroteToTimeBuffer = true; 7452292SN/A } 7462292SN/A 7472292SN/A // Check if there's any instructions left that haven't yet been renamed. 7482292SN/A // If so then block. 7492292SN/A if (insts_available) { 7502292SN/A blockThisCycle = true; 7512292SN/A } 7522292SN/A 7532292SN/A if (blockThisCycle) { 7542292SN/A block(tid); 7552292SN/A toDecode->renameUnblock[tid] = false; 7562292SN/A } 7572292SN/A} 7582292SN/A 7592292SN/Atemplate<class Impl> 7602292SN/Avoid 7612292SN/ADefaultRename<Impl>::skidInsert(ThreadID tid) 7622292SN/A{ 7632292SN/A DynInstPtr inst = NULL; 7642292SN/A 7652292SN/A while (!insts[tid].empty()) { 7662292SN/A inst = insts[tid].front(); 7672292SN/A 7682292SN/A insts[tid].pop_front(); 7692292SN/A 7702292SN/A assert(tid == inst->threadNumber); 7712292SN/A 7722292SN/A DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC: %s into Rename " 7732292SN/A "skidBuffer\n", tid, inst->seqNum, inst->pcState()); 7742292SN/A 7752292SN/A ++renameSkidInsts; 7762292SN/A 7772292SN/A skidBuffer[tid].push_back(inst); 7782292SN/A } 7796221Snate@binkert.org 7802292SN/A if (skidBuffer[tid].size() > skidBufferMax) 7812292SN/A { 7822292SN/A typename InstQueue::iterator it; 7832292SN/A warn("Skidbuffer contents:\n"); 7842292SN/A for (it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++) 7852292SN/A { 7862292SN/A warn("[tid:%u]: %s [sn:%i].\n", tid, 7872292SN/A (*it)->staticInst->disassemble(inst->instAddr()), 7882292SN/A (*it)->seqNum); 7892292SN/A } 7902292SN/A panic("Skidbuffer Exceeded Max Size"); 7912292SN/A } 7922292SN/A} 7932292SN/A 7942292SN/Atemplate <class Impl> 7952292SN/Avoid 7962292SN/ADefaultRename<Impl>::sortInsts() 7972292SN/A{ 7982292SN/A int insts_from_decode = fromDecode->size; 7992292SN/A for (int i = 0; i < insts_from_decode; ++i) { 8002292SN/A const DynInstPtr &inst = fromDecode->insts[i]; 8012292SN/A insts[inst->threadNumber].push_back(inst); 8022292SN/A#if TRACING_ON 8032292SN/A if (DTRACE(O3PipeView)) { 8042292SN/A inst->renameTick = curTick() - inst->fetchTick; 8052702Sktlim@umich.edu } 8062292SN/A#endif 8072292SN/A } 8082702Sktlim@umich.edu} 8092702Sktlim@umich.edu 8102292SN/Atemplate<class Impl> 8112292SN/Abool 8122292SN/ADefaultRename<Impl>::skidsEmpty() 8132292SN/A{ 8142292SN/A list<ThreadID>::iterator threads = activeThreads->begin(); 8152292SN/A list<ThreadID>::iterator end = activeThreads->end(); 8162292SN/A 8172292SN/A while (threads != end) { 8182292SN/A ThreadID tid = *threads++; 8192292SN/A 8202292SN/A if (!skidBuffer[tid].empty()) 8212292SN/A return false; 8222292SN/A } 8232292SN/A 8242292SN/A return true; 8252292SN/A} 8262292SN/A 8272292SN/Atemplate<class Impl> 8282292SN/Avoid 8292292SN/ADefaultRename<Impl>::updateStatus() 8302292SN/A{ 8312292SN/A bool any_unblocking = false; 8322292SN/A 8332292SN/A list<ThreadID>::iterator threads = activeThreads->begin(); 8342292SN/A list<ThreadID>::iterator end = activeThreads->end(); 8352292SN/A 8362292SN/A while (threads != end) { 8372292SN/A ThreadID tid = *threads++; 8382292SN/A 8392292SN/A if (renameStatus[tid] == Unblocking) { 8402292SN/A any_unblocking = true; 8412292SN/A break; 8422292SN/A } 8432292SN/A } 8442292SN/A 8452292SN/A // Rename will have activity if it's unblocking. 8462292SN/A if (any_unblocking) { 8472292SN/A if (_status == Inactive) { 8482292SN/A _status = Active; 8492326SN/A 8506221Snate@binkert.org DPRINTF(Activity, "Activating stage.\n"); 8516221Snate@binkert.org 8522326SN/A cpu->activateStage(O3CPU::RenameIdx); 8532292SN/A } 8542292SN/A } else { 8552292SN/A // If it's not unblocking, then rename will not have any internal 8562292SN/A // activity. Switch it to inactive. 8572292SN/A if (_status == Active) { 8582292SN/A _status = Inactive; 8592292SN/A DPRINTF(Activity, "Deactivating stage.\n"); 8606221Snate@binkert.org 8612702Sktlim@umich.edu cpu->deactivateStage(O3CPU::RenameIdx); 8624632Sgblack@eecs.umich.edu } 8632935Sksewell@umich.edu } 8642702Sktlim@umich.edu} 8652935Sksewell@umich.edu 8662702Sktlim@umich.edutemplate <class Impl> 8672702Sktlim@umich.edubool 8682702Sktlim@umich.eduDefaultRename<Impl>::block(ThreadID tid) 8692702Sktlim@umich.edu{ 8702702Sktlim@umich.edu DPRINTF(Rename, "[tid:%u]: Blocking.\n", tid); 8712702Sktlim@umich.edu 8722702Sktlim@umich.edu // Add the current inputs onto the skid buffer, so they can be 8732702Sktlim@umich.edu // reprocessed when this stage unblocks. 8742702Sktlim@umich.edu skidInsert(tid); 8752702Sktlim@umich.edu 8762702Sktlim@umich.edu // Only signal backwards to block if the previous stages do not think 8772702Sktlim@umich.edu // rename is already blocked. 8782702Sktlim@umich.edu if (renameStatus[tid] != Blocked) { 8792292SN/A // If resumeUnblocking is set, we unblocked during the squash, 8802292SN/A // but now we're have unblocking status. We need to tell earlier 8812292SN/A // stages to block. 8822292SN/A if (resumeUnblocking || renameStatus[tid] != Unblocking) { 8832292SN/A toDecode->renameBlock[tid] = true; 8842292SN/A toDecode->renameUnblock[tid] = false; 8852292SN/A wroteToTimeBuffer = true; 8862292SN/A } 8872292SN/A 8882292SN/A // Rename can not go from SerializeStall to Blocked, otherwise 8892292SN/A // it would not know to complete the serialize stall. 8902292SN/A if (renameStatus[tid] != SerializeStall) { 8912292SN/A // Set status to Blocked. 8922292SN/A renameStatus[tid] = Blocked; 8932292SN/A return true; 8942292SN/A } 8952292SN/A } 8962292SN/A 8972733Sktlim@umich.edu return false; 8982292SN/A} 8992292SN/A 9002292SN/Atemplate <class Impl> 9012292SN/Abool 9022292SN/ADefaultRename<Impl>::unblock(ThreadID tid) 9032292SN/A{ 9042292SN/A DPRINTF(Rename, "[tid:%u]: Trying to unblock.\n", tid); 9052733Sktlim@umich.edu 9062292SN/A // Rename is done unblocking if the skid buffer is empty. 9072292SN/A if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) { 9082292SN/A 9092292SN/A DPRINTF(Rename, "[tid:%u]: Done unblocking.\n", tid); 9106221Snate@binkert.org 9112292SN/A toDecode->renameUnblock[tid] = true; 9122292SN/A wroteToTimeBuffer = true; 9132292SN/A 9142292SN/A renameStatus[tid] = Running; 9152292SN/A return true; 9162292SN/A } 9172292SN/A 9182292SN/A return false; 9192292SN/A} 9202292SN/A 9212292SN/Atemplate <class Impl> 9222292SN/Avoid 9232292SN/ADefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid) 9242292SN/A{ 9252292SN/A typename std::list<RenameHistory>::iterator hb_it = 9262292SN/A historyBuffer[tid].begin(); 9272292SN/A 9282292SN/A // After a syscall squashes everything, the history buffer may be empty 9292292SN/A // but the ROB may still be squashing instructions. 9302292SN/A if (historyBuffer[tid].empty()) { 9312292SN/A return; 9322292SN/A } 9332292SN/A 9342292SN/A // Go through the most recent instructions, undoing the mappings 9352292SN/A // they did and freeing up the registers. 9362292SN/A while (!historyBuffer[tid].empty() && 9372292SN/A hb_it->instSeqNum > squashed_seq_num) { 9382292SN/A assert(hb_it != historyBuffer[tid].end()); 9392292SN/A 9402292SN/A DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence " 9412292SN/A "number %i.\n", tid, hb_it->instSeqNum); 9422292SN/A 9432292SN/A // Undo the rename mapping only if it was really a change. 9442292SN/A // Special regs that are not really renamed (like misc regs 9452292SN/A // and the zero reg) can be recognized because the new mapping 9465215Sgblack@eecs.umich.edu // is the same as the old one. While it would be merely a 9472292SN/A // waste of time to update the rename table, we definitely 9482292SN/A // don't want to put these on the free list. 9492292SN/A if (hb_it->newPhysReg != hb_it->prevPhysReg) { 9502292SN/A // Tell the rename map to set the architected register to the 9512292SN/A // previous physical register that it was renamed to. 9522292SN/A renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg); 9532292SN/A 9542292SN/A // Put the renamed physical register back on the free list. 9552292SN/A freeList->addReg(hb_it->newPhysReg); 9562292SN/A } 9572292SN/A 9586221Snate@binkert.org // Notify potential listeners that the register mapping needs to be 9592292SN/A // removed because the instruction it was mapped to got squashed. Note 9602292SN/A // that this is done before hb_it is incremented. 9612292SN/A ppSquashInRename->notify(std::make_pair(hb_it->instSeqNum, 9622292SN/A hb_it->newPhysReg)); 9632292SN/A 9642292SN/A historyBuffer[tid].erase(hb_it++); 9652292SN/A 9662292SN/A ++renameUndoneMaps; 9672292SN/A } 9682292SN/A} 9692292SN/A 9702292SN/Atemplate<class Impl> 9712292SN/Avoid 9722292SN/ADefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid) 9732292SN/A{ 9742292SN/A DPRINTF(Rename, "[tid:%u]: Removing a committed instruction from the " 9752820Sktlim@umich.edu "history buffer %u (size=%i), until [sn:%lli].\n", 9762292SN/A tid, tid, historyBuffer[tid].size(), inst_seq_num); 9772292SN/A 9782292SN/A typename std::list<RenameHistory>::iterator hb_it = 9792292SN/A historyBuffer[tid].end(); 9802292SN/A 9812292SN/A --hb_it; 9822292SN/A 9832292SN/A if (historyBuffer[tid].empty()) { 9842292SN/A DPRINTF(Rename, "[tid:%u]: History buffer is empty.\n", tid); 9852292SN/A return; 9862292SN/A } else if (hb_it->instSeqNum > inst_seq_num) { 9872292SN/A DPRINTF(Rename, "[tid:%u]: Old sequence number encountered. Ensure " 9887720Sgblack@eecs.umich.edu "that a syscall happened recently.\n", tid); 9892292SN/A return; 9907720Sgblack@eecs.umich.edu } 9912292SN/A 9922292SN/A // Commit all the renames up until (and including) the committed sequence 9932292SN/A // number. Some or even all of the committed instructions may not have 9942292SN/A // rename histories if they did not have destination registers that were 9952292SN/A // renamed. 9962292SN/A while (!historyBuffer[tid].empty() && 9972292SN/A hb_it != historyBuffer[tid].end() && 9982292SN/A hb_it->instSeqNum <= inst_seq_num) { 9992292SN/A 10002292SN/A DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i (%s), " 10012292SN/A "[sn:%lli].\n", 10022292SN/A tid, hb_it->prevPhysReg->index(), 10032292SN/A hb_it->prevPhysReg->className(), 10042292SN/A hb_it->instSeqNum); 10052292SN/A 10062292SN/A // Don't free special phys regs like misc and zero regs, which 10072292SN/A // can be recognized because the new mapping is the same as 10082292SN/A // the old one. 10092292SN/A if (hb_it->newPhysReg != hb_it->prevPhysReg) { 10102292SN/A freeList->addReg(hb_it->prevPhysReg); 10112292SN/A } 10122292SN/A 10132292SN/A ++renameCommittedMaps; 10142292SN/A 10152292SN/A historyBuffer[tid].erase(hb_it--); 10162292SN/A } 10172292SN/A} 10182292SN/A 10192292SN/Atemplate <class Impl> 10202292SN/Ainline void 10212292SN/ADefaultRename<Impl>::renameSrcRegs(const DynInstPtr &inst, ThreadID tid) 10222292SN/A{ 10232292SN/A ThreadContext *tc = inst->tcBase(); 10242292SN/A RenameMap *map = renameMap[tid]; 10252292SN/A unsigned num_src_regs = inst->numSrcRegs(); 10262292SN/A 10272292SN/A // Get the architectual register numbers from the source and 10282292SN/A // operands, and redirect them to the right physical register. 10292292SN/A for (int src_idx = 0; src_idx < num_src_regs; src_idx++) { 10302292SN/A const RegId& src_reg = inst->srcRegIdx(src_idx); 10312292SN/A PhysRegIdPtr renamed_reg; 10322292SN/A 10332292SN/A renamed_reg = map->lookup(tc->flattenRegId(src_reg)); 10342292SN/A switch (src_reg.classValue()) { 10352292SN/A case IntRegClass: 10362292SN/A intRenameLookups++; 10372292SN/A break; 10382292SN/A case FloatRegClass: 10392292SN/A fpRenameLookups++; 10402292SN/A break; 10412292SN/A case VecRegClass: 10422292SN/A case VecElemClass: 10432292SN/A vecRenameLookups++; 10442292SN/A break; 10452292SN/A case CCRegClass: 10462292SN/A case MiscRegClass: 10472292SN/A break; 10482292SN/A 10492292SN/A default: 10502292SN/A panic("Invalid register class: %d.", src_reg.classValue()); 10512292SN/A } 10522292SN/A 10532292SN/A DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i" 10542292SN/A ", got phys reg %i (%s)\n", tid, 10552292SN/A src_reg.className(), src_reg.index(), 10562292SN/A renamed_reg->index(), 10572292SN/A renamed_reg->className()); 10582292SN/A 10592292SN/A inst->renameSrcReg(src_idx, renamed_reg); 10602292SN/A 10612292SN/A // See if the register is ready or not. 10622292SN/A if (scoreboard->getReg(renamed_reg)) { 10632292SN/A DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)" 10642292SN/A " is ready.\n", tid, renamed_reg->index(), 10652336SN/A renamed_reg->flatIndex(), 10662336SN/A renamed_reg->className()); 10672336SN/A 10682336SN/A inst->markSrcRegReady(src_idx); 10692348SN/A } else { 10702292SN/A DPRINTF(Rename, "[tid:%u]: Register %d (flat: %d) (%s)" 10712292SN/A " is not ready.\n", tid, renamed_reg->index(), 10722292SN/A renamed_reg->flatIndex(), 10732292SN/A renamed_reg->className()); 10742292SN/A } 10752292SN/A 10762292SN/A ++renameRenameLookups; 10772292SN/A } 10782292SN/A} 10792292SN/A 10802292SN/Atemplate <class Impl> 10812326SN/Ainline void 10822292SN/ADefaultRename<Impl>::renameDestRegs(const DynInstPtr &inst, ThreadID tid) 10832292SN/A{ 10842292SN/A ThreadContext *tc = inst->tcBase(); 10852292SN/A RenameMap *map = renameMap[tid]; 10862292SN/A unsigned num_dest_regs = inst->numDestRegs(); 10872292SN/A 10882292SN/A // Rename the destination registers. 10892292SN/A for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) { 10902292SN/A const RegId& dest_reg = inst->destRegIdx(dest_idx); 10912292SN/A typename RenameMap::RenameInfo rename_result; 10922292SN/A 10932326SN/A RegId flat_dest_regid = tc->flattenRegId(dest_reg); 10942292SN/A 10952727Sktlim@umich.edu rename_result = map->rename(flat_dest_regid); 10962301SN/A 10972292SN/A inst->flattenDestReg(dest_idx, flat_dest_regid); 10982292SN/A 10992292SN/A // Mark Scoreboard entry as not ready 11002292SN/A scoreboard->unsetReg(rename_result.first); 11012292SN/A 11022292SN/A DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i (%s) to physical " 11032292SN/A "reg %i (%i).\n", tid, dest_reg.index(), 11042292SN/A dest_reg.className(), 11052292SN/A rename_result.first->index(), 11062326SN/A rename_result.first->flatIndex()); 11072292SN/A 11082292SN/A // Record the rename information so that a history can be kept. 11092292SN/A RenameHistory hb_entry(inst->seqNum, flat_dest_regid, 11102292SN/A rename_result.first, 11112292SN/A rename_result.second); 11124033Sktlim@umich.edu 11134033Sktlim@umich.edu historyBuffer[tid].push_front(hb_entry); 11144033Sktlim@umich.edu 11154033Sktlim@umich.edu DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer " 11164033Sktlim@umich.edu "(size=%i), [sn:%lli].\n",tid, 11174033Sktlim@umich.edu historyBuffer[tid].size(), 11184033Sktlim@umich.edu (*historyBuffer[tid].begin()).instSeqNum); 11194033Sktlim@umich.edu 11204033Sktlim@umich.edu // Tell the instruction to rename the appropriate destination 11214033Sktlim@umich.edu // register (dest_idx) to the new physical register 11224033Sktlim@umich.edu // (rename_result.first), and record the previous physical 11234033Sktlim@umich.edu // register that the same logical register was renamed to 11244033Sktlim@umich.edu // (rename_result.second). 11254033Sktlim@umich.edu inst->renameDestReg(dest_idx, 11262292SN/A rename_result.first, 11272292SN/A rename_result.second); 11282292SN/A 11292292SN/A ++renameRenamedOperands; 11302292SN/A } 11312292SN/A} 11322292SN/A 11332292SN/Atemplate <class Impl> 11342292SN/Ainline int 11352292SN/ADefaultRename<Impl>::calcFreeROBEntries(ThreadID tid) 11362292SN/A{ 11372292SN/A int num_free = freeEntries[tid].robEntries - 11382292SN/A (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched); 11392292SN/A 11402292SN/A //DPRINTF(Rename,"[tid:%i]: %i rob free\n",tid,num_free); 11412935Sksewell@umich.edu 11422292SN/A return num_free; 11432292SN/A} 11442292SN/A 11452292SN/Atemplate <class Impl> 11462292SN/Ainline int 11472292SN/ADefaultRename<Impl>::calcFreeIQEntries(ThreadID tid) 11482292SN/A{ 11492292SN/A int num_free = freeEntries[tid].iqEntries - 11502292SN/A (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched); 11512292SN/A 11522292SN/A //DPRINTF(Rename,"[tid:%i]: %i iq free\n",tid,num_free); 11532292SN/A 11542292SN/A return num_free; 11552292SN/A} 11562292SN/A 11572292SN/Atemplate <class Impl> 11582292SN/Ainline int 11592292SN/ADefaultRename<Impl>::calcFreeLQEntries(ThreadID tid) 11602292SN/A{ 11612980Sgblack@eecs.umich.edu int num_free = freeEntries[tid].lqEntries - 11622292SN/A (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ); 11632292SN/A DPRINTF(Rename, "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, " 11642292SN/A "loads dispatchedToLQ: %d\n", freeEntries[tid].lqEntries, 11652980Sgblack@eecs.umich.edu loadsInProgress[tid], fromIEW->iewInfo[tid].dispatchedToLQ); 11662292SN/A return num_free; 11677720Sgblack@eecs.umich.edu} 11682292SN/A 11692292SN/Atemplate <class Impl> 11702292SN/Ainline int 11712292SN/ADefaultRename<Impl>::calcFreeSQEntries(ThreadID tid) 11722292SN/A{ 11732292SN/A int num_free = freeEntries[tid].sqEntries - 11742292SN/A (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ); 11752980Sgblack@eecs.umich.edu DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, storesInProgress: %d, " 11762292SN/A "stores dispatchedToSQ: %d\n", freeEntries[tid].sqEntries, 11772292SN/A storesInProgress[tid], fromIEW->iewInfo[tid].dispatchedToSQ); 11782292SN/A return num_free; 11792292SN/A} 11802292SN/A 11812292SN/Atemplate <class Impl> 11822292SN/Aunsigned 11832292SN/ADefaultRename<Impl>::validInsts() 11842292SN/A{ 11856221Snate@binkert.org unsigned inst_count = 0; 11866221Snate@binkert.org 11872292SN/A for (int i=0; i<fromDecode->size; i++) { 11883867Sbinkertn@umich.edu if (!fromDecode->insts[i]->isSquashed()) 11896221Snate@binkert.org inst_count++; 11902292SN/A } 11912292SN/A 11922292SN/A return inst_count; 11932698Sktlim@umich.edu} 11947599Sminkyu.jeong@arm.com 11952698Sktlim@umich.edutemplate <class Impl> 11961062SN/Avoid 11971062SN/ADefaultRename<Impl>::readStallSignals(ThreadID tid) 11982333SN/A{ 11992292SN/A if (fromIEW->iewBlock[tid]) { 12002333SN/A stalls[tid].iew = true; 12012326SN/A } 12021062SN/A 12032292SN/A if (fromIEW->iewUnblock[tid]) { 12041062SN/A assert(stalls[tid].iew); 12052333SN/A stalls[tid].iew = false; 12061062SN/A } 12077720Sgblack@eecs.umich.edu} 12087720Sgblack@eecs.umich.edu 12091062SN/Atemplate <class Impl> 12101062SN/Abool 12111062SN/ADefaultRename<Impl>::checkStall(ThreadID tid) 12122292SN/A{ 12131062SN/A bool ret_val = false; 12141062SN/A 12151062SN/A if (stalls[tid].iew) { 12161062SN/A DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid); 12171062SN/A ret_val = true; 12182292SN/A } else if (calcFreeROBEntries(tid) <= 0) { 12192292SN/A DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid); 12202292SN/A ret_val = true; 12211062SN/A } else if (calcFreeIQEntries(tid) <= 0) { 12221062SN/A DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid); 12231062SN/A ret_val = true; 12242820Sktlim@umich.edu } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) { 12251062SN/A DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid); 12261062SN/A ret_val = true; 12271062SN/A } else if (renameMap[tid]->numFreeEntries() <= 0) { 12282292SN/A DPRINTF(Rename,"[tid:%i]: Stall: RenameMap has 0 free entries.\n", tid); 12291062SN/A ret_val = true; 12301062SN/A } else if (renameStatus[tid] == SerializeStall && 12311062SN/A (!emptyROB[tid] || instsInProgress[tid])) { 12321062SN/A DPRINTF(Rename,"[tid:%i]: Stall: Serialize stall and ROB is not " 12337850SMatt.Horsnell@arm.com "empty.\n", 12342292SN/A tid); 12351062SN/A ret_val = true; 12361062SN/A } 12371062SN/A 12381062SN/A return ret_val; 12392292SN/A} 12402292SN/A 12412292SN/Atemplate <class Impl> 12427944SGiacomo.Gabrielli@arm.comvoid 12437944SGiacomo.Gabrielli@arm.comDefaultRename<Impl>::readFreeEntries(ThreadID tid) 12447944SGiacomo.Gabrielli@arm.com{ 12457944SGiacomo.Gabrielli@arm.com if (fromIEW->iewInfo[tid].usedIQ) 12467944SGiacomo.Gabrielli@arm.com freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries; 12477944SGiacomo.Gabrielli@arm.com 12487944SGiacomo.Gabrielli@arm.com if (fromIEW->iewInfo[tid].usedLSQ) { 12497944SGiacomo.Gabrielli@arm.com freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries; 12507944SGiacomo.Gabrielli@arm.com freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries; 12517944SGiacomo.Gabrielli@arm.com } 12527944SGiacomo.Gabrielli@arm.com 12537850SMatt.Horsnell@arm.com if (fromCommit->commitInfo[tid].usedROB) { 12548073SAli.Saidi@ARM.com freeEntries[tid].robEntries = 12557850SMatt.Horsnell@arm.com fromCommit->commitInfo[tid].freeROBEntries; 12561062SN/A emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB; 12572367SN/A } 12581062SN/A 12597944SGiacomo.Gabrielli@arm.com DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, " 12607944SGiacomo.Gabrielli@arm.com "Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i)\n", 12617944SGiacomo.Gabrielli@arm.com tid, 12627944SGiacomo.Gabrielli@arm.com freeEntries[tid].iqEntries, 12637944SGiacomo.Gabrielli@arm.com freeEntries[tid].robEntries, 12647944SGiacomo.Gabrielli@arm.com freeEntries[tid].lqEntries, 12657944SGiacomo.Gabrielli@arm.com freeEntries[tid].sqEntries, 12667944SGiacomo.Gabrielli@arm.com renameMap[tid]->numFreeEntries(), 12677944SGiacomo.Gabrielli@arm.com renameMap[tid]->numFreeIntEntries(), 12687944SGiacomo.Gabrielli@arm.com renameMap[tid]->numFreeFloatEntries(), 12692292SN/A renameMap[tid]->numFreeVecEntries(), 12707782Sminkyu.jeong@arm.com renameMap[tid]->numFreeCCEntries()); 12717782Sminkyu.jeong@arm.com 12727782Sminkyu.jeong@arm.com DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n", 12737782Sminkyu.jeong@arm.com tid, instsInProgress[tid]); 12742367SN/A} 12752367SN/A 12762367SN/Atemplate <class Impl> 12772367SN/Abool 12782367SN/ADefaultRename<Impl>::checkSignalsAndUpdate(ThreadID tid) 12792292SN/A{ 12802326SN/A // Check if there's a squash signal, squash if there is 12812326SN/A // Check stall signals, block if necessary. 12822326SN/A // If status was blocked 12832326SN/A // check if stall conditions have passed 12841062SN/A // if so then go to unblocking 12852292SN/A // If status was Squashing 12861062SN/A // check if squashing is not high. Switch to running this cycle. 12871062SN/A // If status was serialize stall 12881062SN/A // check if ROB is empty and no insts are in flight to the ROB 12897847Sminkyu.jeong@arm.com 12907847Sminkyu.jeong@arm.com readFreeEntries(tid); 12917847Sminkyu.jeong@arm.com readStallSignals(tid); 12927847Sminkyu.jeong@arm.com 12937847Sminkyu.jeong@arm.com if (fromCommit->commitInfo[tid].squash) { 12947847Sminkyu.jeong@arm.com DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from " 12957848SAli.Saidi@ARM.com "commit.\n", tid); 12967848SAli.Saidi@ARM.com 12977847Sminkyu.jeong@arm.com squash(fromCommit->commitInfo[tid].doneSeqNum, tid); 12981062SN/A 12992292SN/A return true; 13002292SN/A } 13012292SN/A 13021062SN/A if (checkStall(tid)) { 13031062SN/A return block(tid); 13042301SN/A } 13051681SN/A 13062326SN/A if (renameStatus[tid] == Blocked) { 13072326SN/A DPRINTF(Rename, "[tid:%u]: Done blocking, switching to unblocking.\n", 13082326SN/A tid); 13092107SN/A 13101681SN/A renameStatus[tid] = Unblocking; 13112292SN/A 13122292SN/A unblock(tid); 13132292SN/A 13146221Snate@binkert.org return true; 13151062SN/A } 13163732Sktlim@umich.edu 13177852SMatt.Horsnell@arm.com if (renameStatus[tid] == Squashing) { 13183732Sktlim@umich.edu // Switch status to running if rename isn't being told to block or 13191062SN/A // squash this cycle. 13207856SMatt.Horsnell@arm.com if (resumeSerialize) { 13217856SMatt.Horsnell@arm.com DPRINTF(Rename, "[tid:%u]: Done squashing, switching to serialize.\n", 13227856SMatt.Horsnell@arm.com tid); 13237856SMatt.Horsnell@arm.com 13247856SMatt.Horsnell@arm.com renameStatus[tid] = SerializeStall; 13252292SN/A return true; 13261062SN/A } else if (resumeUnblocking) { 13272292SN/A DPRINTF(Rename, "[tid:%u]: Done squashing, switching to unblocking.\n", 13286036Sksewell@umich.edu tid); 13297720Sgblack@eecs.umich.edu renameStatus[tid] = Unblocking; 13307720Sgblack@eecs.umich.edu return true; 13317720Sgblack@eecs.umich.edu } else { 13321062SN/A DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n", 13332292SN/A tid); 13341062SN/A 13353795Sgblack@eecs.umich.edu renameStatus[tid] = Running; 13361062SN/A return false; 13372292SN/A } 13382292SN/A } 13391062SN/A 13402292SN/A if (renameStatus[tid] == SerializeStall) { 13414033Sktlim@umich.edu // Stall ends once the ROB is free. 13422326SN/A DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to " 13432326SN/A "unblocking.\n", tid); 13442292SN/A 13452292SN/A DynInstPtr serial_inst = serializeInst[tid]; 13462292SN/A 13471062SN/A renameStatus[tid] = Unblocking; 13487720Sgblack@eecs.umich.edu 13497720Sgblack@eecs.umich.edu unblock(tid); 13507720Sgblack@eecs.umich.edu 13517720Sgblack@eecs.umich.edu DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with " 13527720Sgblack@eecs.umich.edu "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState()); 13533732Sktlim@umich.edu 13543732Sktlim@umich.edu // Put instruction into queue here. 13551062SN/A serial_inst->clearSerializeBefore(); 13561062SN/A 13571062SN/A if (!skidBuffer[tid].empty()) { 13581062SN/A skidBuffer[tid].push_front(serial_inst); 13592292SN/A } else { 13601062SN/A insts[tid].push_front(serial_inst); 13611062SN/A } 13622292SN/A 13632292SN/A DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename." 13642292SN/A " Adding to front of list.\n", tid); 13652292SN/A 13662292SN/A serializeInst[tid] = NULL; 13677720Sgblack@eecs.umich.edu 13687720Sgblack@eecs.umich.edu return true; 13692292SN/A } 13702292SN/A 13711062SN/A // If we've reached this point, we have not gotten any signals that 13724033Sktlim@umich.edu // cause rename to change its status. Rename remains the same as before. 13734033Sktlim@umich.edu return false; 13744033Sktlim@umich.edu} 13754033Sktlim@umich.edu 13764033Sktlim@umich.edutemplate<class Impl> 13774033Sktlim@umich.eduvoid 13784033Sktlim@umich.eduDefaultRename<Impl>::serializeAfter(InstQueue &inst_list, ThreadID tid) 13794033Sktlim@umich.edu{ 13804033Sktlim@umich.edu if (inst_list.empty()) { 13817720Sgblack@eecs.umich.edu // Mark a bit to say that I must serialize on the next instruction. 13827720Sgblack@eecs.umich.edu serializeOnNextInst[tid] = true; 13837720Sgblack@eecs.umich.edu return; 13844033Sktlim@umich.edu } 13854033Sktlim@umich.edu 13864033Sktlim@umich.edu // Set the next instruction as serializing. 13874033Sktlim@umich.edu inst_list.front()->setSerializeBefore(); 13884033Sktlim@umich.edu} 13894033Sktlim@umich.edu 13904033Sktlim@umich.edutemplate <class Impl> 13914033Sktlim@umich.eduinline void 13927720Sgblack@eecs.umich.eduDefaultRename<Impl>::incrFullStat(const FullSource &source) 13937720Sgblack@eecs.umich.edu{ 13944033Sktlim@umich.edu switch (source) { 13954033Sktlim@umich.edu case ROB: 13964033Sktlim@umich.edu ++renameROBFullEvents; 13974033Sktlim@umich.edu break; 13984033Sktlim@umich.edu case IQ: 13994033Sktlim@umich.edu ++renameIQFullEvents; 14001062SN/A break; 14011062SN/A case LQ: 14022292SN/A ++renameLQFullEvents; 14032348SN/A break; 14042292SN/A case SQ: 14052292SN/A ++renameSQFullEvents; 14062292SN/A break; 14072292SN/A default: 14082292SN/A panic("Rename full stall stat should be incremented for a reason!"); 14092292SN/A break; 14102292SN/A } 14112292SN/A} 14122292SN/A 14132292SN/Atemplate <class Impl> 14142292SN/Avoid 14152292SN/ADefaultRename<Impl>::dumpHistory() 14162292SN/A{ 14172292SN/A typename std::list<RenameHistory>::iterator buf_it; 14187852SMatt.Horsnell@arm.com 14192107SN/A for (ThreadID tid = 0; tid < numThreads; tid++) { 14202107SN/A 14212292SN/A buf_it = historyBuffer[tid].begin(); 14222107SN/A 14232292SN/A while (buf_it != historyBuffer[tid].end()) { 14242107SN/A cprintf("Seq num: %i\nArch reg[%s]: %i New phys reg:" 14252326SN/A " %i[%s] Old phys reg: %i[%s]\n", 14262326SN/A (*buf_it).instSeqNum, 14272326SN/A (*buf_it).archReg.className(), 14282326SN/A (*buf_it).archReg.index(), 14292326SN/A (*buf_it).newPhysReg->index(), 14303958Sgblack@eecs.umich.edu (*buf_it).newPhysReg->className(), 14312292SN/A (*buf_it).prevPhysReg->index(), 14322107SN/A (*buf_it).prevPhysReg->className()); 14336221Snate@binkert.org 14342107SN/A buf_it++; 14357720Sgblack@eecs.umich.edu } 14367720Sgblack@eecs.umich.edu } 14372107SN/A} 14382301SN/A 14392301SN/A#endif//__CPU_O3_RENAME_IMPL_HH__ 14402292SN/A