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