inst_queue_impl.hh revision 1689
11689SN/A/* 22326SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292831Sksewell@umich.edu// Todo: 301689SN/A// Current ordering allows for 0 cycle added-to-scheduled. Could maybe fake 311689SN/A// it; either do in reverse order, or have added instructions put into a 322064SN/A// different ready queue that, in scheduleRreadyInsts(), gets put onto the 331060SN/A// normal ready queue. This would however give only a one cycle delay, 341060SN/A// but probably is more flexible to actually add in a delay parameter than 351696SN/A// just running it backwards. 361689SN/A 372292SN/A#include <vector> 381717SN/A 391060SN/A#include "sim/universe.hh" 401061SN/A 412292SN/A#include "cpu/beta_cpu/inst_queue.hh" 422292SN/A 432292SN/A// Either compile error or max int due to sign extension. 442292SN/A// Hack to avoid compile warnings. 452326SN/Aconst InstSeqNum MaxInstSeqNum = 0 - 1; 461060SN/A 472292SN/Atemplate <class Impl> 482292SN/AInstructionQueue<Impl>::InstructionQueue(Params ¶ms) 492292SN/A : memDepUnit(params), 502292SN/A numEntries(params.numIQEntries), 512292SN/A intWidth(params.executeIntWidth), 522292SN/A floatWidth(params.executeFloatWidth), 532292SN/A branchWidth(params.executeBranchWidth), 542326SN/A memoryWidth(params.executeMemoryWidth), 552292SN/A totalWidth(params.issueWidth), 562292SN/A numPhysIntRegs(params.numPhysIntRegs), 572292SN/A numPhysFloatRegs(params.numPhysFloatRegs), 582292SN/A commitToIEWDelay(params.commitToIEWDelay) 592292SN/A{ 602292SN/A // Initialize the number of free IQ entries. 612292SN/A freeEntries = numEntries; 622292SN/A 632292SN/A // Set the number of physical registers as the number of int + float 642292SN/A numPhysRegs = numPhysIntRegs + numPhysFloatRegs; 652292SN/A 662292SN/A DPRINTF(IQ, "IQ: There are %i physical registers.\n", numPhysRegs); 672292SN/A 682669Sktlim@umich.edu //Create an entry for each physical register within the 692292SN/A //dependency graph. 702292SN/A dependGraph = new DependencyEntry[numPhysRegs]; 712292SN/A 722292SN/A // Resize the register scoreboard. 732292SN/A regScoreboard.resize(numPhysRegs); 742292SN/A 752292SN/A // Initialize all the head pointers to point to NULL, and all the 762292SN/A // entries as unready. 772307SN/A // Note that in actuality, the registers corresponding to the logical 782307SN/A // registers start off as ready. However this doesn't matter for the 792292SN/A // IQ as the instruction should have been correctly told if those 801060SN/A // registers are ready in rename. Thus it can all be initialized as 811060SN/A // unready. 821060SN/A for (int i = 0; i < numPhysRegs; ++i) 831060SN/A { 842292SN/A dependGraph[i].next = NULL; 851060SN/A dependGraph[i].inst = NULL; 861060SN/A regScoreboard[i] = false; 871060SN/A } 882326SN/A 891060SN/A} 901060SN/A 911060SN/Atemplate <class Impl> 921060SN/Avoid 932292SN/AInstructionQueue<Impl>::regStats() 942292SN/A{ 952292SN/A iqInstsAdded 962292SN/A .name(name() + ".iqInstsAdded") 971060SN/A .desc("Number of instructions added to the IQ (excludes non-spec)") 981060SN/A .prereq(iqInstsAdded); 992307SN/A 1002292SN/A iqNonSpecInstsAdded 1012980Sgblack@eecs.umich.edu .name(name() + ".iqNonSpecInstsAdded") 1022292SN/A .desc("Number of non-speculative instructions added to the IQ") 1032292SN/A .prereq(iqNonSpecInstsAdded); 1042292SN/A 1052292SN/A// iqIntInstsAdded; 1062292SN/A 1072292SN/A iqIntInstsIssued 1082292SN/A .name(name() + ".iqIntInstsIssued") 1092292SN/A .desc("Number of integer instructions issued") 1102292SN/A .prereq(iqIntInstsIssued); 1112292SN/A 1122292SN/A// iqFloatInstsAdded; 1132292SN/A 1142292SN/A iqFloatInstsIssued 1152292SN/A .name(name() + ".iqFloatInstsIssued") 1162292SN/A .desc("Number of float instructions issued") 1172292SN/A .prereq(iqFloatInstsIssued); 1182292SN/A 1192292SN/A// iqBranchInstsAdded; 1202292SN/A 1212292SN/A iqBranchInstsIssued 1222292SN/A .name(name() + ".iqBranchInstsIssued") 1232292SN/A .desc("Number of branch instructions issued") 1242292SN/A .prereq(iqBranchInstsIssued); 1252292SN/A 1262292SN/A// iqMemInstsAdded; 1272831Sksewell@umich.edu 1282292SN/A iqMemInstsIssued 1292292SN/A .name(name() + ".iqMemInstsIssued") 1302292SN/A .desc("Number of memory instructions issued") 1312292SN/A .prereq(iqMemInstsIssued); 1322292SN/A 1332292SN/A// iqMiscInstsAdded; 1342292SN/A 1352292SN/A iqMiscInstsIssued 1362292SN/A .name(name() + ".iqMiscInstsIssued") 1372292SN/A .desc("Number of miscellaneous instructions issued") 1382292SN/A .prereq(iqMiscInstsIssued); 1392292SN/A 1402292SN/A iqSquashedInstsIssued 1412292SN/A .name(name() + ".iqSquashedInstsIssued") 1422831Sksewell@umich.edu .desc("Number of squashed instructions issued") 1432292SN/A .prereq(iqSquashedInstsIssued); 1442292SN/A 1452292SN/A iqLoopSquashStalls 1462292SN/A .name(name() + ".iqLoopSquashStalls") 1472292SN/A .desc("Number of times issue loop had to restart due to squashed " 1482292SN/A "inst; mainly for profiling") 1492292SN/A .prereq(iqLoopSquashStalls); 1502292SN/A 1512292SN/A iqSquashedInstsExamined 1522292SN/A .name(name() + ".iqSquashedInstsExamined") 1532326SN/A .desc("Number of squashed instructions iterated over during squash;" 1542348SN/A " mainly for profiling") 1552326SN/A .prereq(iqSquashedInstsExamined); 1562326SN/A 1572348SN/A iqSquashedOperandsExamined 1582292SN/A .name(name() + ".iqSquashedOperandsExamined") 1592292SN/A .desc("Number of squashed operands that are examined and possibly " 1602292SN/A "removed from graph") 1612292SN/A .prereq(iqSquashedOperandsExamined); 1622292SN/A 1632292SN/A iqSquashedNonSpecRemoved 1642292SN/A .name(name() + ".iqSquashedNonSpecRemoved") 1651060SN/A .desc("Number of squashed non-spec instructions that were removed") 1661060SN/A .prereq(iqSquashedNonSpecRemoved); 1671061SN/A 1681060SN/A // Tell mem dependence unit to reg stats as well. 1691062SN/A memDepUnit.regStats(); 1701062SN/A} 1712301SN/A 1721062SN/Atemplate <class Impl> 1731062SN/Avoid 1741062SN/AInstructionQueue<Impl>::setCPU(FullCPU *cpu_ptr) 1751062SN/A{ 1761062SN/A cpu = cpu_ptr; 1771062SN/A 1781062SN/A tail = cpu->instList.begin(); 1791062SN/A} 1801062SN/A 1811062SN/Atemplate <class Impl> 1822301SN/Avoid 1832301SN/AInstructionQueue<Impl>::setIssueToExecuteQueue( 1842301SN/A TimeBuffer<IssueStruct> *i2e_ptr) 1852301SN/A{ 1861062SN/A DPRINTF(IQ, "IQ: Set the issue to execute queue.\n"); 1871062SN/A issueToExecuteQueue = i2e_ptr; 1881062SN/A} 1891062SN/A 1901062SN/Atemplate <class Impl> 1911062SN/Avoid 1921062SN/AInstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 1931062SN/A{ 1941062SN/A DPRINTF(IQ, "IQ: Set the time buffer.\n"); 1951062SN/A timeBuffer = tb_ptr; 1961062SN/A 1971062SN/A fromCommit = timeBuffer->getWire(-commitToIEWDelay); 1981062SN/A} 1991062SN/A 2001062SN/Atemplate <class Impl> 2011062SN/Aunsigned 2021062SN/AInstructionQueue<Impl>::numFreeEntries() 2031062SN/A{ 2041062SN/A return freeEntries; 2051062SN/A} 2061062SN/A 2071062SN/A// Might want to do something more complex if it knows how many instructions 2081062SN/A// will be issued this cycle. 2091062SN/Atemplate <class Impl> 2101062SN/Abool 2111062SN/AInstructionQueue<Impl>::isFull() 2121062SN/A{ 2131062SN/A if (freeEntries == 0) { 2141062SN/A return(true); 2151062SN/A } else { 2161062SN/A return(false); 2171062SN/A } 2181062SN/A} 2191062SN/A 2201062SN/Atemplate <class Impl> 2211062SN/Avoid 2221062SN/AInstructionQueue<Impl>::insert(DynInstPtr &new_inst) 2231062SN/A{ 2241062SN/A // Make sure the instruction is valid 2251062SN/A assert(new_inst); 2261062SN/A 2271062SN/A DPRINTF(IQ, "IQ: Adding instruction PC %#x to the IQ.\n", 2281062SN/A new_inst->readPC()); 2291062SN/A 2301062SN/A // Check if there are any free entries. Panic if there are none. 2311062SN/A // Might want to have this return a fault in the future instead of 2321062SN/A // panicing. 2331062SN/A assert(freeEntries != 0); 2342326SN/A 2352301SN/A // If the IQ currently has nothing in it, then there's a possibility 2362301SN/A // that the tail iterator is invalid (might have been pointing at an 2372301SN/A // instruction that was retired). Reset the tail iterator. 2382301SN/A if (freeEntries == numEntries) { 2392301SN/A tail = cpu->instList.begin(); 2402301SN/A } 2412326SN/A 2422301SN/A // Move the tail iterator. Instructions may not have been issued 2432326SN/A // to the IQ, so we may have to increment the iterator more than once. 2442307SN/A while ((*tail) != new_inst) { 2452301SN/A tail++; 2462301SN/A 2472307SN/A // Make sure the tail iterator points at something legal. 2482301SN/A assert(tail != cpu->instList.end()); 2492301SN/A } 2502301SN/A 2512301SN/A 2522301SN/A // Decrease the number of free entries. 2532301SN/A --freeEntries; 2542301SN/A 2552301SN/A // Look through its source registers (physical regs), and mark any 2562301SN/A // dependencies. 2572301SN/A addToDependents(new_inst); 2582301SN/A 2592301SN/A // Have this instruction set itself as the producer of its destination 2602326SN/A // register(s). 2612301SN/A createDependency(new_inst); 2622301SN/A 2632301SN/A // If it's a memory instruction, add it to the memory dependency 2642301SN/A // unit. 2652301SN/A if (new_inst->isMemRef()) { 2662326SN/A memDepUnit.insert(new_inst); 2672301SN/A // Uh..forgot to look it up and put it on the proper dependency list 2682301SN/A // if the instruction should not go yet. 2692301SN/A } else { 2702301SN/A // If the instruction is ready then add it to the ready list. 2712301SN/A addIfReady(new_inst); 2722326SN/A } 2732301SN/A 2742301SN/A ++iqInstsAdded; 2752301SN/A 2762301SN/A assert(freeEntries == (numEntries - countInsts())); 2772301SN/A} 2782301SN/A 2792301SN/Atemplate <class Impl> 2802980Sgblack@eecs.umich.eduvoid 2812301SN/AInstructionQueue<Impl>::insertNonSpec(DynInstPtr &inst) 2822326SN/A{ 2832301SN/A nonSpecInsts[inst->seqNum] = inst; 2842301SN/A 2852326SN/A // @todo: Clean up this code; can do it by setting inst as unable 2862301SN/A // to issue, then calling normal insert on the inst. 2872301SN/A 2882301SN/A // Make sure the instruction is valid 2892301SN/A assert(inst); 2902326SN/A 2912727Sktlim@umich.edu DPRINTF(IQ, "IQ: Adding instruction PC %#x to the IQ.\n", 2922326SN/A inst->readPC()); 2932301SN/A 2942301SN/A // Check if there are any free entries. Panic if there are none. 2952301SN/A // Might want to have this return a fault in the future instead of 2962301SN/A // panicing. 2972301SN/A assert(freeEntries != 0); 2982301SN/A 2992326SN/A // If the IQ currently has nothing in it, then there's a possibility 3002301SN/A // that the tail iterator is invalid (might have been pointing at an 3012301SN/A // instruction that was retired). Reset the tail iterator. 3022326SN/A if (freeEntries == numEntries) { 3032301SN/A tail = cpu->instList.begin(); 3042301SN/A } 3052301SN/A 3062301SN/A // Move the tail iterator. Instructions may not have been issued 3072301SN/A // to the IQ, so we may have to increment the iterator more than once. 3082301SN/A while ((*tail) != inst) { 3092326SN/A tail++; 3102301SN/A 3112301SN/A // Make sure the tail iterator points at something legal. 3122301SN/A assert(tail != cpu->instList.end()); 3132301SN/A } 3142326SN/A 3152301SN/A // Decrease the number of free entries. 3162292SN/A --freeEntries; 3172292SN/A 3182292SN/A // Have this instruction set itself as the producer of its destination 3192292SN/A // register(s). 3201062SN/A createDependency(inst); 3211062SN/A 3221062SN/A // If it's a memory instruction, add it to the memory dependency 3231062SN/A // unit. 3242307SN/A if (inst->isMemRef()) { 3251060SN/A memDepUnit.insertNonSpec(inst); 3262307SN/A } 3272307SN/A 3282307SN/A ++iqNonSpecInstsAdded; 3292307SN/A} 3302307SN/A 3311060SN/A// Slightly hack function to advance the tail iterator in the case that 3322307SN/A// the IEW stage issues an instruction that is not added to the IQ. This 3332307SN/A// is needed in case a long chain of such instructions occurs. 3342307SN/A// I don't think this is used anymore. 3352307SN/Atemplate <class Impl> 3362307SN/Avoid 3372307SN/AInstructionQueue<Impl>::advanceTail(DynInstPtr &inst) 3382307SN/A{ 3392307SN/A // Make sure the instruction is valid 3402307SN/A assert(inst); 3412307SN/A 3422307SN/A DPRINTF(IQ, "IQ: Adding instruction PC %#x to the IQ.\n", 3432307SN/A inst->readPC()); 3442307SN/A 3452307SN/A // Check if there are any free entries. Panic if there are none. 3462307SN/A // Might want to have this return a fault in the future instead of 3472307SN/A // panicing. 3482307SN/A assert(freeEntries != 0); 3492307SN/A 3502307SN/A // If the IQ currently has nothing in it, then there's a possibility 3512307SN/A // that the tail iterator is invalid (might have been pointing at an 3522307SN/A // instruction that was retired). Reset the tail iterator. 3532307SN/A if (freeEntries == numEntries) { 3542307SN/A tail = cpu->instList.begin(); 3552307SN/A } 3561060SN/A 3571060SN/A // Move the tail iterator. Instructions may not have been issued 3581061SN/A // to the IQ, so we may have to increment the iterator more than once. 3591060SN/A while ((*tail) != inst) { 3602980Sgblack@eecs.umich.edu tail++; 3611060SN/A 3622292SN/A // Make sure the tail iterator points at something legal. 3632292SN/A assert(tail != cpu->instList.end()); 3642064SN/A } 3652064SN/A 3662064SN/A assert(freeEntries <= numEntries); 3672064SN/A 3682292SN/A // Have this instruction set itself as the producer of its destination 3692064SN/A // register(s). 3702292SN/A createDependency(inst); 3711060SN/A} 3721060SN/A 3731060SN/A// Need to make sure the number of float and integer instructions 3741061SN/A// issued does not exceed the total issue bandwidth. 3751060SN/A// @todo: Figure out a better way to remove the squashed items from the 3761060SN/A// lists. Checking the top item of each list to see if it's squashed 3771060SN/A// wastes time and forces jumps. 3782292SN/Atemplate <class Impl> 3791060SN/Avoid 3801060SN/AInstructionQueue<Impl>::scheduleReadyInsts() 3811060SN/A{ 3821060SN/A DPRINTF(IQ, "IQ: Attempting to schedule ready instructions from " 3831060SN/A "the IQ.\n"); 3841684SN/A 3852307SN/A int int_issued = 0; 3862307SN/A int float_issued = 0; 3872307SN/A int branch_issued = 0; 3882307SN/A int memory_issued = 0; 3892326SN/A int squashed_issued = 0; 3902307SN/A int total_issued = 0; 3912307SN/A 3922307SN/A IssueStruct *i2e_info = issueToExecuteQueue->access(0); 3932307SN/A 3942307SN/A bool insts_available = !readyBranchInsts.empty() || 3952307SN/A !readyIntInsts.empty() || 3962307SN/A !readyFloatInsts.empty() || 3972307SN/A !memDepUnit.empty() || 3982307SN/A !readyMiscInsts.empty() || 3992307SN/A !squashedInsts.empty(); 4002307SN/A 4012307SN/A // Note: Requires a globally defined constant. 4022307SN/A InstSeqNum oldest_inst = MaxInstSeqNum; 4032307SN/A InstList list_with_oldest = None; 4042292SN/A 4052292SN/A // Temporary values. 4062292SN/A DynInstPtr int_head_inst; 4072292SN/A DynInstPtr float_head_inst; 4082292SN/A DynInstPtr branch_head_inst; 4092292SN/A DynInstPtr mem_head_inst; 4102292SN/A DynInstPtr misc_head_inst; 4112292SN/A DynInstPtr squashed_head_inst; 4122292SN/A 4132292SN/A // Somewhat nasty code to look at all of the lists where issuable 4142292SN/A // instructions are located, and choose the oldest instruction among 4152292SN/A // those lists. Consider a rewrite in the future. 4162292SN/A while (insts_available && total_issued < totalWidth) 4172292SN/A { 4182292SN/A // Set this to false. Each if-block is required to set it to true 4192292SN/A // if there were instructions available this check. This will cause 4202292SN/A // this loop to run once more than necessary, but avoids extra calls. 4212292SN/A insts_available = false; 4222980Sgblack@eecs.umich.edu 4232980Sgblack@eecs.umich.edu oldest_inst = MaxInstSeqNum; 4242292SN/A 4252292SN/A list_with_oldest = None; 4262292SN/A 4272292SN/A if (!readyIntInsts.empty() && 4282292SN/A int_issued < intWidth) { 4292292SN/A 4302292SN/A insts_available = true; 4312292SN/A 4322292SN/A int_head_inst = readyIntInsts.top(); 4332292SN/A 4342292SN/A if (int_head_inst->isSquashed()) { 4352292SN/A readyIntInsts.pop(); 4361684SN/A 4371684SN/A ++iqLoopSquashStalls; 4381684SN/A 4391684SN/A continue; 4401684SN/A } 4411684SN/A 4422292SN/A oldest_inst = int_head_inst->seqNum; 4432292SN/A 4442292SN/A list_with_oldest = Int; 4452292SN/A } 4462292SN/A 4472292SN/A if (!readyFloatInsts.empty() && 4482292SN/A float_issued < floatWidth) { 4491060SN/A 4501060SN/A insts_available = true; 4511061SN/A 4521060SN/A float_head_inst = readyFloatInsts.top(); 4531060SN/A 4541060SN/A if (float_head_inst->isSquashed()) { 4551060SN/A readyFloatInsts.pop(); 4561060SN/A 4571060SN/A ++iqLoopSquashStalls; 4581060SN/A 4591060SN/A continue; 4601060SN/A } else if (float_head_inst->seqNum < oldest_inst) { 4611060SN/A oldest_inst = float_head_inst->seqNum; 4621061SN/A 4632292SN/A list_with_oldest = Float; 4642292SN/A } 4652292SN/A } 4662292SN/A 4672292SN/A if (!readyBranchInsts.empty() && 4682292SN/A branch_issued < branchWidth) { 4692292SN/A 4702292SN/A insts_available = true; 4712292SN/A 4722292SN/A branch_head_inst = readyBranchInsts.top(); 4732292SN/A 4742292SN/A if (branch_head_inst->isSquashed()) { 4752292SN/A readyBranchInsts.pop(); 4762292SN/A 4772292SN/A ++iqLoopSquashStalls; 4782292SN/A 4792292SN/A continue; 4802292SN/A } else if (branch_head_inst->seqNum < oldest_inst) { 4812292SN/A oldest_inst = branch_head_inst->seqNum; 4822292SN/A 4832292SN/A list_with_oldest = Branch; 4842292SN/A } 4852292SN/A 4862292SN/A } 4872292SN/A 4882292SN/A if (!memDepUnit.empty() && 4892292SN/A memory_issued < memoryWidth) { 4902292SN/A 4911060SN/A insts_available = true; 4921061SN/A 4931060SN/A mem_head_inst = memDepUnit.top(); 4941060SN/A 4951060SN/A if (mem_head_inst->isSquashed()) { 4961060SN/A memDepUnit.pop(); 4972326SN/A 4982326SN/A ++iqLoopSquashStalls; 4991060SN/A 5001060SN/A continue; 5011060SN/A } else if (mem_head_inst->seqNum < oldest_inst) { 5022292SN/A oldest_inst = mem_head_inst->seqNum; 5031060SN/A 5042064SN/A list_with_oldest = Memory; 5051060SN/A } 5062292SN/A } 5071060SN/A 5081060SN/A if (!readyMiscInsts.empty()) { 5091060SN/A 5101060SN/A insts_available = true; 5111060SN/A 5121060SN/A misc_head_inst = readyMiscInsts.top(); 5131060SN/A 5142326SN/A if (misc_head_inst->isSquashed()) { 5151060SN/A readyMiscInsts.pop(); 5161061SN/A 5172292SN/A ++iqLoopSquashStalls; 5181062SN/A 5191062SN/A continue; 5201061SN/A } else if (misc_head_inst->seqNum < oldest_inst) { 5211061SN/A oldest_inst = misc_head_inst->seqNum; 5221062SN/A 5231060SN/A list_with_oldest = Misc; 5242292SN/A } 5252292SN/A } 5261060SN/A 5271060SN/A if (!squashedInsts.empty()) { 5281060SN/A 5291061SN/A insts_available = true; 5301061SN/A 5312292SN/A squashed_head_inst = squashedInsts.top(); 5321061SN/A 5331061SN/A if (squashed_head_inst->seqNum < oldest_inst) { 5341061SN/A list_with_oldest = Squashed; 5351061SN/A } 5362292SN/A 5371061SN/A } 5382292SN/A 5391061SN/A DynInstPtr issuing_inst = NULL; 5402326SN/A 5412326SN/A switch (list_with_oldest) { 5422326SN/A case None: 5432064SN/A DPRINTF(IQ, "IQ: Not able to schedule any instructions. Issuing " 5441061SN/A "inst is %#x.\n", issuing_inst); 5451061SN/A break; 5462292SN/A 5471061SN/A case Int: 5482064SN/A issuing_inst = int_head_inst; 5491061SN/A readyIntInsts.pop(); 5502292SN/A ++int_issued; 5511061SN/A DPRINTF(IQ, "IQ: Issuing integer instruction PC %#x.\n", 5521061SN/A issuing_inst->readPC()); 5531061SN/A break; 5542326SN/A 5551061SN/A case Float: 5561061SN/A issuing_inst = float_head_inst; 5571061SN/A readyFloatInsts.pop(); 5582292SN/A ++float_issued; 5592292SN/A DPRINTF(IQ, "IQ: Issuing float instruction PC %#x.\n", 5601061SN/A issuing_inst->readPC()); 5611062SN/A break; 5621062SN/A 5632292SN/A case Branch: 5642292SN/A issuing_inst = branch_head_inst; 5652292SN/A readyBranchInsts.pop(); 5662292SN/A ++branch_issued; 5671061SN/A DPRINTF(IQ, "IQ: Issuing branch instruction PC %#x.\n", 5681061SN/A issuing_inst->readPC()); 5691061SN/A break; 5701060SN/A 5712292SN/A case Memory: 5721060SN/A issuing_inst = mem_head_inst; 5732292SN/A 5741060SN/A memDepUnit.pop(); 5752292SN/A ++memory_issued; 5762292SN/A DPRINTF(IQ, "IQ: Issuing memory instruction PC %#x.\n", 5771060SN/A issuing_inst->readPC()); 5782064SN/A break; 5792333SN/A 5802333SN/A case Misc: 5812333SN/A issuing_inst = misc_head_inst; 5822333SN/A readyMiscInsts.pop(); 5832333SN/A 5842333SN/A ++iqMiscInstsIssued; 5852333SN/A 5862333SN/A DPRINTF(IQ, "IQ: Issuing a miscellaneous instruction PC %#x.\n", 5871060SN/A issuing_inst->readPC()); 5882333SN/A break; 5892064SN/A 5902292SN/A case Squashed: 5912292SN/A assert(0 && "Squashed insts should not issue any more!"); 5922292SN/A squashedInsts.pop(); 5932292SN/A // Set the squashed instruction as able to commit so that commit 5942292SN/A // can just drop it from the ROB. This is a bit faked. 5952292SN/A ++squashed_issued; 5962292SN/A ++freeEntries; 5972292SN/A 5982292SN/A DPRINTF(IQ, "IQ: Issuing squashed instruction PC %#x.\n", 5992292SN/A squashed_head_inst->readPC()); 6002292SN/A break; 6012292SN/A } 6022292SN/A 6032292SN/A if (list_with_oldest != None && list_with_oldest != Squashed) { 6042292SN/A i2e_info->insts[total_issued] = issuing_inst; 6052292SN/A i2e_info->size++; 6062292SN/A 6072292SN/A issuing_inst->setIssued(); 6082292SN/A 6091060SN/A ++freeEntries; 6101060SN/A ++total_issued; 6112292SN/A } 6122292SN/A 6132292SN/A assert(freeEntries == (numEntries - countInsts())); 6141060SN/A } 6152292SN/A 6162292SN/A iqIntInstsIssued += int_issued; 6172292SN/A iqFloatInstsIssued += float_issued; 6182292SN/A iqBranchInstsIssued += branch_issued; 6192292SN/A iqMemInstsIssued += memory_issued; 6202292SN/A iqSquashedInstsIssued += squashed_issued; 6212292SN/A} 6222292SN/A 6232292SN/Atemplate <class Impl> 6242292SN/Avoid 6252292SN/AInstructionQueue<Impl>::scheduleNonSpec(const InstSeqNum &inst) 6262292SN/A{ 6272292SN/A DPRINTF(IQ, "IQ: Marking nonspeculative instruction with sequence " 6282292SN/A "number %i as ready to execute.\n", inst); 6292292SN/A 6302292SN/A non_spec_it_t inst_it = nonSpecInsts.find(inst); 6312292SN/A 6322292SN/A assert(inst_it != nonSpecInsts.end()); 6332292SN/A 6342292SN/A // Mark this instruction as ready to issue. 6352292SN/A (*inst_it).second->setCanIssue(); 6361060SN/A 6371060SN/A // Now schedule the instruction. 6382292SN/A if (!(*inst_it).second->isMemRef()) { 6391060SN/A addIfReady((*inst_it).second); 6401060SN/A } else { 6412292SN/A memDepUnit.nonSpecInstReady((*inst_it).second); 6422292SN/A } 6432292SN/A 6442292SN/A nonSpecInsts.erase(inst_it); 6452292SN/A} 6462292SN/A 6472307SN/Atemplate <class Impl> 6482307SN/Avoid 6492307SN/AInstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst) 6502307SN/A{ 6512292SN/A DPRINTF(IQ, "IQ: Waking dependents of completed instruction.\n"); 6522292SN/A //Look at the physical destination register of the DynInst 6532326SN/A //and look it up on the dependency graph. Then mark as ready 6542326SN/A //any instructions within the instruction queue. 6552292SN/A DependencyEntry *curr; 6562326SN/A 6572326SN/A // Tell the memory dependence unit to wake any dependents on this 6582326SN/A // instruction if it is a memory instruction. 6592333SN/A 6602333SN/A if (completed_inst->isMemRef()) { 6612292SN/A memDepUnit.wakeDependents(completed_inst); 6622292SN/A } 6631061SN/A 6641061SN/A for (int dest_reg_idx = 0; 6651061SN/A dest_reg_idx < completed_inst->numDestRegs(); 6661061SN/A dest_reg_idx++) 6671060SN/A { 6681060SN/A PhysRegIndex dest_reg = 6691060SN/A completed_inst->renamedDestRegIdx(dest_reg_idx); 6702292SN/A 6712292SN/A // Special case of uniq or control registers. They are not 6721060SN/A // handled by the IQ and thus have no dependency graph entry. 6731060SN/A // @todo Figure out a cleaner way to handle this. 6741060SN/A if (dest_reg >= numPhysRegs) { 6752292SN/A continue; 6762292SN/A } 6772292SN/A 6782292SN/A DPRINTF(IQ, "IQ: Waking any dependents on register %i.\n", 6792292SN/A (int) dest_reg); 6802292SN/A 6812292SN/A //Maybe abstract this part into a function. 6822292SN/A //Go through the dependency chain, marking the registers as ready 6832292SN/A //within the waiting instructions. 6842292SN/A while (dependGraph[dest_reg].next) { 6852292SN/A 6861060SN/A curr = dependGraph[dest_reg].next; 6872333SN/A 6882820Sktlim@umich.edu DPRINTF(IQ, "IQ: Waking up a dependent instruction, PC%#x.\n", 6892326SN/A curr->inst->readPC()); 6902292SN/A 6911060SN/A // Might want to give more information to the instruction 6922292SN/A // so that it knows which of its source registers is ready. 6931060SN/A // However that would mean that the dependency graph entries 6942292SN/A // would need to hold the src_reg_idx. 6951060SN/A curr->inst->markSrcRegReady(); 6962292SN/A 6971060SN/A addIfReady(curr->inst); 6982292SN/A 6992292SN/A dependGraph[dest_reg].next = curr->next; 7001060SN/A 7012292SN/A DependencyEntry::mem_alloc_counter--; 7022292SN/A 7032292SN/A curr->inst = NULL; 7042292SN/A 7052292SN/A delete curr; 7061060SN/A } 7071060SN/A 7082292SN/A // Reset the head node now that all of its dependents have been woken 7091060SN/A // up. 7102292SN/A dependGraph[dest_reg].next = NULL; 7112292SN/A dependGraph[dest_reg].inst = NULL; 7122292SN/A 7131060SN/A // Mark the scoreboard as having that register ready. 7141060SN/A regScoreboard[dest_reg] = true; 7152326SN/A } 7162326SN/A} 7172301SN/A 7181060SN/Atemplate <class Impl> 7192326SN/Avoid 7202326SN/AInstructionQueue<Impl>::violation(DynInstPtr &store, 7211060SN/A DynInstPtr &faulting_load) 7222326SN/A{ 7232326SN/A memDepUnit.violation(store, faulting_load); 7241060SN/A} 7251060SN/A 7261060SN/Atemplate <class Impl> 7272348SN/Avoid 7282348SN/AInstructionQueue<Impl>::squash() 7292326SN/A{ 7302292SN/A DPRINTF(IQ, "IQ: Starting to squash instructions in the IQ.\n"); 7312292SN/A 7322333SN/A // Read instruction sequence number of last instruction out of the 7331060SN/A // time buffer. 7342326SN/A squashedSeqNum = fromCommit->commitInfo.doneSeqNum; 7352326SN/A 7362326SN/A // Setup the squash iterator to point to the tail. 7372326SN/A squashIt = tail; 7382292SN/A 7392292SN/A // Call doSquash if there are insts in the IQ 7402326SN/A if (freeEntries != numEntries) { 7412326SN/A doSquash(); 7422326SN/A } 7431060SN/A 7442326SN/A // Also tell the memory dependence unit to squash. 7451060SN/A memDepUnit.squash(squashedSeqNum); 7462326SN/A} 7472292SN/A 7482348SN/Atemplate <class Impl> 7492348SN/Avoid 7502326SN/AInstructionQueue<Impl>::doSquash() 7512292SN/A{ 7522292SN/A // Make sure the squash iterator isn't pointing to nothing. 7532326SN/A assert(squashIt != cpu->instList.end()); 7542292SN/A // Make sure the squashed sequence number is valid. 7551060SN/A assert(squashedSeqNum != 0); 7561060SN/A 7572292SN/A DPRINTF(IQ, "IQ: Squashing instructions in the IQ.\n"); 7582292SN/A 7592301SN/A // Squash any instructions younger than the squashed sequence number 7602292SN/A // given. 7611060SN/A while ((*squashIt)->seqNum > squashedSeqNum) { 7622292SN/A DynInstPtr squashed_inst = (*squashIt); 7631061SN/A 7642292SN/A // Only handle the instruction if it actually is in the IQ and 7652292SN/A // hasn't already been squashed in the IQ. 7662292SN/A if (!squashed_inst->isIssued() && 7672292SN/A !squashed_inst->isSquashedInIQ()) { 7682292SN/A 7691060SN/A // Remove the instruction from the dependency list. 7701060SN/A // Hack for now: These below don't add themselves to the 7712064SN/A // dependency list, so don't try to remove them. 7722292SN/A if (!squashed_inst->isNonSpeculative()/* && 7732064SN/A !squashed_inst->isStore()*/ 7742292SN/A ) { 7752292SN/A 7762292SN/A for (int src_reg_idx = 0; 7772292SN/A src_reg_idx < squashed_inst->numSrcRegs(); 7782301SN/A src_reg_idx++) 7792731Sktlim@umich.edu { 7802292SN/A PhysRegIndex src_reg = 7812301SN/A squashed_inst->renamedSrcRegIdx(src_reg_idx); 7822292SN/A 7832292SN/A // Only remove it from the dependency graph if it was 7842292SN/A // placed there in the first place. 7852326SN/A // HACK: This assumes that instructions woken up from the 7862820Sktlim@umich.edu // dependency chain aren't informed that a specific src 7872292SN/A // register has become ready. This may not always be true 7882326SN/A // in the future. 7892326SN/A if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) && 7902292SN/A src_reg < numPhysRegs) { 7911060SN/A dependGraph[src_reg].remove(squashed_inst); 7921060SN/A } 7931062SN/A 7942326SN/A ++iqSquashedOperandsExamined; 7952326SN/A } 7962307SN/A 7972348SN/A // Might want to remove producers as well. 7982292SN/A } else { 7992292SN/A nonSpecInsts[squashed_inst->seqNum] = NULL; 8002292SN/A 8012292SN/A nonSpecInsts.erase(squashed_inst->seqNum); 8022292SN/A 8031060SN/A ++iqSquashedNonSpecRemoved; 8041060SN/A } 8051061SN/A 8061060SN/A // Might want to also clear out the head of the dependency graph. 8071061SN/A 8081060SN/A // Mark it as squashed within the IQ. 8092292SN/A squashed_inst->setSquashedInIQ(); 8102292SN/A 8111062SN/A// squashedInsts.push(squashed_inst); 8122292SN/A squashed_inst->setIssued(); 8131060SN/A squashed_inst->setCanCommit(); 8141061SN/A 8151060SN/A ++freeEntries; 8162292SN/A 8172292SN/A DPRINTF(IQ, "IQ: Instruction PC %#x squashed.\n", 8181061SN/A squashed_inst->readPC()); 8191060SN/A } 8201062SN/A 8211062SN/A --squashIt; 8221062SN/A ++iqSquashedInstsExamined; 8232292SN/A } 8241062SN/A 8251060SN/A assert(freeEntries <= numEntries); 8262292SN/A 8272292SN/A if (freeEntries == numEntries) { 8281061SN/A tail = cpu->instList.end(); 8291060SN/A } 8301060SN/A 8311061SN/A} 8321061SN/A 8332292SN/Atemplate <class Impl> 8342292SN/Avoid 8352292SN/AInstructionQueue<Impl>::stopSquash() 8362292SN/A{ 8372292SN/A // Clear up the squash variables to ensure that squashing doesn't 8382292SN/A // get called improperly. 8392292SN/A squashedSeqNum = 0; 8402292SN/A 8412292SN/A squashIt = cpu->instList.end(); 8422292SN/A} 8432292SN/A 8442292SN/Atemplate <class Impl> 8452292SN/Avoid 8462292SN/AInstructionQueue<Impl>::DependencyEntry::insert(DynInstPtr &new_inst) 8472292SN/A{ 8482292SN/A //Add this new, dependent instruction at the head of the dependency 8492292SN/A //chain. 8502301SN/A 8511684SN/A // First create the entry that will be added to the head of the 8521684SN/A // dependency chain. 8532301SN/A DependencyEntry *new_entry = new DependencyEntry; 8542301SN/A new_entry->next = this->next; 8552292SN/A new_entry->inst = new_inst; 8562292SN/A 8572292SN/A // Then actually add it to the chain. 8581684SN/A this->next = new_entry; 8591684SN/A 8602292SN/A ++mem_alloc_counter; 8612326SN/A} 8622326SN/A 8632326SN/Atemplate <class Impl> 8642326SN/Avoid 8651684SN/AInstructionQueue<Impl>::DependencyEntry::remove(DynInstPtr &inst_to_remove) 8662292SN/A{ 8672292SN/A DependencyEntry *prev = this; 8682292SN/A DependencyEntry *curr = this->next; 8692292SN/A 8702292SN/A // Make sure curr isn't NULL. Because this instruction is being 8711684SN/A // removed from a dependency list, it must have been placed there at 8721684SN/A // an earlier time. The dependency chain should not be empty, 8731684SN/A // unless the instruction dependent upon it is already ready. 8741684SN/A if (curr == NULL) { 8751684SN/A return; 8761684SN/A } 8771684SN/A 8781684SN/A // Find the instruction to remove within the dependency linked list. 8791684SN/A while(curr->inst != inst_to_remove) 8801684SN/A { 8811684SN/A prev = curr; 8821684SN/A curr = curr->next; 8831684SN/A 8841684SN/A assert(curr != NULL); 8851684SN/A } 8861684SN/A 8872292SN/A // Now remove this instruction from the list. 8881684SN/A prev->next = curr->next; 8891684SN/A 8902326SN/A --mem_alloc_counter; 8912326SN/A 8922326SN/A // Could push this off to the destructor of DependencyEntry 8931684SN/A curr->inst = NULL; 8942326SN/A 8952292SN/A delete curr; 8962326SN/A} 8971684SN/A 8981684SN/Atemplate <class Impl> 8992326SN/Abool 9002326SN/AInstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst) 9012326SN/A{ 9022326SN/A // Loop through the instruction's source registers, adding 9031684SN/A // them to the dependency list if they are not ready. 9042326SN/A int8_t total_src_regs = new_inst->numSrcRegs(); 9051684SN/A bool return_val = false; 9062326SN/A 9071684SN/A for (int src_reg_idx = 0; 9082301SN/A src_reg_idx < total_src_regs; 9091684SN/A src_reg_idx++) 9101684SN/A { 9112326SN/A // Only add it to the dependency graph if it's not ready. 9122326SN/A if (!new_inst->isReadySrcRegIdx(src_reg_idx)) { 9132326SN/A PhysRegIndex src_reg = new_inst->renamedSrcRegIdx(src_reg_idx); 9142326SN/A 9151684SN/A // Check the IQ's scoreboard to make sure the register 9161684SN/A // hasn't become ready while the instruction was in flight 9171684SN/A // between stages. Only if it really isn't ready should 9181684SN/A // it be added to the dependency graph. 9192301SN/A if (src_reg >= numPhysRegs) { 9202064SN/A continue; 9212064SN/A } else if (regScoreboard[src_reg] == false) { 9222064SN/A DPRINTF(IQ, "IQ: Instruction PC %#x has src reg %i that " 9232064SN/A "is being added to the dependency chain.\n", 9242292SN/A new_inst->readPC(), src_reg); 9252064SN/A 9262292SN/A dependGraph[src_reg].insert(new_inst); 9272292SN/A 9282292SN/A // Change the return value to indicate that something 9292292SN/A // was added to the dependency graph. 9302326SN/A return_val = true; 9312326SN/A } else { 9322326SN/A DPRINTF(IQ, "IQ: Instruction PC %#x has src reg %i that " 9332326SN/A "became ready before it reached the IQ.\n", 9342326SN/A new_inst->readPC(), src_reg); 9352326SN/A // Mark a register ready within the instruction. 9362326SN/A new_inst->markSrcRegReady(); 9372326SN/A } 9382326SN/A } 9392326SN/A } 9402292SN/A 9412292SN/A return return_val; 9422292SN/A} 9432064SN/A 9442064SN/Atemplate <class Impl> 9452064SN/Avoid 9462064SN/AInstructionQueue<Impl>::createDependency(DynInstPtr &new_inst) 9472292SN/A{ 9482064SN/A //Actually nothing really needs to be marked when an 9492292SN/A //instruction becomes the producer of a register's value, 9502064SN/A //but for convenience a ptr to the producing instruction will 9512064SN/A //be placed in the head node of the dependency links. 9522064SN/A int8_t total_dest_regs = new_inst->numDestRegs(); 9532064SN/A 9542292SN/A for (int dest_reg_idx = 0; 9552064SN/A dest_reg_idx < total_dest_regs; 9562292SN/A dest_reg_idx++) 9572292SN/A { 9582292SN/A PhysRegIndex dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx); 9592292SN/A 9602292SN/A // Instructions that use the misc regs will have a reg number 9612292SN/A // higher than the normal physical registers. In this case these 9622292SN/A // registers are not renamed, and there is no need to track 9632292SN/A // dependencies as these instructions must be executed at commit. 9642292SN/A if (dest_reg >= numPhysRegs) { 9652292SN/A continue; 9662292SN/A } 9672292SN/A 9682292SN/A dependGraph[dest_reg].inst = new_inst; 9692292SN/A 9702292SN/A if (dependGraph[dest_reg].next) { 9712292SN/A dumpDependGraph(); 9722292SN/A panic("IQ: Dependency graph not empty!"); 9732292SN/A } 9742292SN/A 9751684SN/A // Mark the scoreboard to say it's not yet ready. 9761684SN/A regScoreboard[dest_reg] = false; 9771684SN/A } 9781684SN/A} 9791061SN/A 9801061SN/Atemplate <class Impl> 9811061SN/Avoid 9822292SN/AInstructionQueue<Impl>::addIfReady(DynInstPtr &inst) 9831061SN/A{ 9841061SN/A //If the instruction now has all of its source registers 9851061SN/A // available, then add it to the list of ready instructions. 9861060SN/A if (inst->readyToIssue()) { 9872292SN/A 9881060SN/A //Add the instruction to the proper ready list. 9892292SN/A if (inst->isControl()) { 9902292SN/A 9911060SN/A DPRINTF(IQ, "IQ: Branch instruction is ready to issue, " 9921060SN/A "putting it onto the ready list, PC %#x.\n", 9931060SN/A inst->readPC()); 9943093Sksewell@umich.edu readyBranchInsts.push(inst); 9953093Sksewell@umich.edu 9963093Sksewell@umich.edu } else if (inst->isMemRef()) { 9972292SN/A 9982935Sksewell@umich.edu DPRINTF(IQ, "IQ: Checking if memory instruction can issue.\n"); 9991060SN/A 10001681SN/A // Message to the mem dependence unit that this instruction has 10012292SN/A // its registers ready. 10022292SN/A 10031681SN/A memDepUnit.regsReady(inst); 10041061SN/A 10051061SN/A#if 0 10062292SN/A if (memDepUnit.readyToIssue(inst)) { 10071060SN/A DPRINTF(IQ, "IQ: Memory instruction is ready to issue, " 10081060SN/A "putting it onto the ready list, PC %#x.\n", 10091061SN/A inst->readPC()); 10101061SN/A readyMemInsts.push(inst); 10112292SN/A } else { 10121061SN/A // Make dependent on the store. 10132326SN/A // Will need some way to get the store instruction it should 10142326SN/A // be dependent upon; then when the store issues it can 10152326SN/A // put the instruction on the ready list. 10161061SN/A // Yet another tree? 10172292SN/A assert(0 && "Instruction has no way to actually issue"); 10182292SN/A } 10191061SN/A#endif 10201061SN/A 10211061SN/A } else if (inst->isInteger()) { 10222326SN/A 10232326SN/A DPRINTF(IQ, "IQ: Integer instruction is ready to issue, " 10242292SN/A "putting it onto the ready list, PC %#x.\n", 10252326SN/A inst->readPC()); 10261061SN/A readyIntInsts.push(inst); 10271061SN/A 10281061SN/A } else if (inst->isFloating()) { 10292292SN/A 10302292SN/A DPRINTF(IQ, "IQ: Floating instruction is ready to issue, " 10312326SN/A "putting it onto the ready list, PC %#x.\n", 10322292SN/A inst->readPC()); 10332292SN/A readyFloatInsts.push(inst); 10342292SN/A 10352292SN/A } else { 10362292SN/A DPRINTF(IQ, "IQ: Miscellaneous instruction is ready to issue, " 10372292SN/A "putting it onto the ready list, PC %#x..\n", 10381062SN/A inst->readPC()); 10391061SN/A 10402292SN/A readyMiscInsts.push(inst); 10412336SN/A } 10422292SN/A } 10432292SN/A} 10441061SN/A 10451061SN/A/* 10461681SN/A * Caution, this function must not be called prior to tail being updated at 10471061SN/A * least once, otherwise it will fail the assertion. This is because 10481061SN/A * instList.begin() actually changes upon the insertion of an element into the 10491061SN/A * list when the list is empty. 10501061SN/A */ 10511061SN/Atemplate <class Impl> 10522326SN/Aint 10532326SN/AInstructionQueue<Impl>::countInsts() 10542326SN/A{ 10552326SN/A ListIt count_it = cpu->instList.begin(); 10562326SN/A int total_insts = 0; 10572326SN/A 10582326SN/A if (tail == cpu->instList.end()) 10592326SN/A return 0; 10602292SN/A 10611061SN/A while (count_it != tail) { 10621061SN/A if (!(*count_it)->isIssued()) { 10632326SN/A ++total_insts; 10641061SN/A } 10651062SN/A 10662292SN/A ++count_it; 10671062SN/A 10681061SN/A assert(count_it != cpu->instList.end()); 10692064SN/A } 10702292SN/A 10712292SN/A // Need to count the tail iterator as well. 10722292SN/A if (count_it != cpu->instList.end() && 10731062SN/A (*count_it) && 10742292SN/A !(*count_it)->isIssued()) { 10751681SN/A ++total_insts; 10762292SN/A } 10771062SN/A 10781062SN/A return total_insts; 10791061SN/A} 10801061SN/A 10811061SN/Atemplate <class Impl> 10821061SN/Avoid 10831061SN/AInstructionQueue<Impl>::dumpDependGraph() 10841061SN/A{ 10851061SN/A DependencyEntry *curr; 10862292SN/A 10872292SN/A for (int i = 0; i < numPhysRegs; ++i) 10881681SN/A { 10891681SN/A curr = &dependGraph[i]; 10902731Sktlim@umich.edu 10912292SN/A if (curr->inst) { 10922292SN/A cprintf("dependGraph[%i]: producer: %#x consumer: ", i, 10932292SN/A curr->inst->readPC()); 10941681SN/A } else { 10951681SN/A cprintf("dependGraph[%i]: No producer. consumer: ", i); 10961061SN/A } 10972326SN/A 10982326SN/A while (curr->next != NULL) { 10992326SN/A curr = curr->next; 11001061SN/A 11011061SN/A cprintf("%#x ", curr->inst->readPC()); 11022326SN/A } 11031062SN/A 11041061SN/A cprintf("\n"); 11051060SN/A } 11061060SN/A} 11071061SN/A 11081060SN/Atemplate <class Impl> 11091061SN/Avoid 11101060SN/AInstructionQueue<Impl>::dumpLists() 11111060SN/A{ 11121060SN/A cprintf("Ready integer list size: %i\n", readyIntInsts.size()); 11131060SN/A 11141060SN/A cprintf("Ready float list size: %i\n", readyFloatInsts.size()); 11151060SN/A 11161060SN/A cprintf("Ready branch list size: %i\n", readyBranchInsts.size()); 11171060SN/A 11181060SN/A cprintf("Ready misc list size: %i\n", readyMiscInsts.size()); 11191060SN/A 11201060SN/A cprintf("Squashed list size: %i\n", squashedInsts.size()); 11211060SN/A 11221060SN/A cprintf("Non speculative list size: %i\n", nonSpecInsts.size()); 11231060SN/A 11241060SN/A non_spec_it_t non_spec_it = nonSpecInsts.begin(); 11251060SN/A 11261060SN/A cprintf("Non speculative list: "); 11271060SN/A 11281061SN/A while (non_spec_it != nonSpecInsts.end()) { 11291061SN/A cprintf("%#x ", (*non_spec_it).second->readPC()); 11301061SN/A ++non_spec_it; 11312292SN/A } 11321060SN/A 11331060SN/A cprintf("\n"); 11341060SN/A 11352326SN/A} 11361060SN/A