inst_queue_impl.hh revision 2348
17639Sgblack@eecs.umich.edu/* 27639Sgblack@eecs.umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan 37639Sgblack@eecs.umich.edu * All rights reserved. 47639Sgblack@eecs.umich.edu * 57639Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67639Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77639Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87639Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97639Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107639Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117639Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127639Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137639Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147639Sgblack@eecs.umich.edu * this software without specific prior written permission. 157639Sgblack@eecs.umich.edu * 167639Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177639Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187639Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197639Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207639Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217639Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227639Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237639Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247639Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257639Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267639Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277639Sgblack@eecs.umich.edu */ 287639Sgblack@eecs.umich.edu 297639Sgblack@eecs.umich.edu#include <limits> 307639Sgblack@eecs.umich.edu#include <vector> 317639Sgblack@eecs.umich.edu 327639Sgblack@eecs.umich.edu#include "sim/root.hh" 337639Sgblack@eecs.umich.edu 347639Sgblack@eecs.umich.edu#include "cpu/o3/fu_pool.hh" 357639Sgblack@eecs.umich.edu#include "cpu/o3/inst_queue.hh" 367639Sgblack@eecs.umich.edu 377639Sgblack@eecs.umich.eduusing namespace std; 387639Sgblack@eecs.umich.edu 397639Sgblack@eecs.umich.edutemplate <class Impl> 407639Sgblack@eecs.umich.eduInstructionQueue<Impl>::FUCompletion::FUCompletion(DynInstPtr &_inst, 417639Sgblack@eecs.umich.edu int fu_idx, 427639Sgblack@eecs.umich.edu InstructionQueue<Impl> *iq_ptr) 437639Sgblack@eecs.umich.edu : Event(&mainEventQueue, Stat_Event_Pri), 447639Sgblack@eecs.umich.edu inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false) 457639Sgblack@eecs.umich.edu{ 467639Sgblack@eecs.umich.edu this->setFlags(Event::AutoDelete); 477639Sgblack@eecs.umich.edu} 487639Sgblack@eecs.umich.edu 497639Sgblack@eecs.umich.edutemplate <class Impl> 507639Sgblack@eecs.umich.eduvoid 517639Sgblack@eecs.umich.eduInstructionQueue<Impl>::FUCompletion::process() 527639Sgblack@eecs.umich.edu{ 537639Sgblack@eecs.umich.edu iqPtr->processFUCompletion(inst, freeFU ? fuIdx : -1); 547639Sgblack@eecs.umich.edu inst = NULL; 557639Sgblack@eecs.umich.edu} 567639Sgblack@eecs.umich.edu 577639Sgblack@eecs.umich.edu 587639Sgblack@eecs.umich.edutemplate <class Impl> 597639Sgblack@eecs.umich.educonst char * 607639Sgblack@eecs.umich.eduInstructionQueue<Impl>::FUCompletion::description() 617639Sgblack@eecs.umich.edu{ 627639Sgblack@eecs.umich.edu return "Functional unit completion event"; 637639Sgblack@eecs.umich.edu} 647639Sgblack@eecs.umich.edu 657639Sgblack@eecs.umich.edutemplate <class Impl> 667639Sgblack@eecs.umich.eduInstructionQueue<Impl>::InstructionQueue(Params *params) 677639Sgblack@eecs.umich.edu : dcacheInterface(params->dcacheInterface), 687639Sgblack@eecs.umich.edu fuPool(params->fuPool), 697639Sgblack@eecs.umich.edu numEntries(params->numIQEntries), 707639Sgblack@eecs.umich.edu totalWidth(params->issueWidth), 717639Sgblack@eecs.umich.edu numPhysIntRegs(params->numPhysIntRegs), 727639Sgblack@eecs.umich.edu numPhysFloatRegs(params->numPhysFloatRegs), 737639Sgblack@eecs.umich.edu commitToIEWDelay(params->commitToIEWDelay) 747639Sgblack@eecs.umich.edu{ 757639Sgblack@eecs.umich.edu assert(fuPool); 767639Sgblack@eecs.umich.edu 777639Sgblack@eecs.umich.edu switchedOut = false; 787639Sgblack@eecs.umich.edu 797639Sgblack@eecs.umich.edu numThreads = params->numberOfThreads; 807639Sgblack@eecs.umich.edu 817639Sgblack@eecs.umich.edu // Set the number of physical registers as the number of int + float 827639Sgblack@eecs.umich.edu numPhysRegs = numPhysIntRegs + numPhysFloatRegs; 837639Sgblack@eecs.umich.edu 847639Sgblack@eecs.umich.edu DPRINTF(IQ, "There are %i physical registers.\n", numPhysRegs); 857639Sgblack@eecs.umich.edu 867639Sgblack@eecs.umich.edu //Create an entry for each physical register within the 877639Sgblack@eecs.umich.edu //dependency graph. 887639Sgblack@eecs.umich.edu dependGraph.resize(numPhysRegs); 897639Sgblack@eecs.umich.edu 907639Sgblack@eecs.umich.edu // Resize the register scoreboard. 917639Sgblack@eecs.umich.edu regScoreboard.resize(numPhysRegs); 927639Sgblack@eecs.umich.edu 937639Sgblack@eecs.umich.edu //Initialize Mem Dependence Units 947639Sgblack@eecs.umich.edu for (int i = 0; i < numThreads; i++) { 957639Sgblack@eecs.umich.edu memDepUnit[i].init(params,i); 967639Sgblack@eecs.umich.edu memDepUnit[i].setIQ(this); 977639Sgblack@eecs.umich.edu } 987639Sgblack@eecs.umich.edu 997639Sgblack@eecs.umich.edu resetState(); 1007639Sgblack@eecs.umich.edu 1017639Sgblack@eecs.umich.edu string policy = params->smtIQPolicy; 1027639Sgblack@eecs.umich.edu 1037639Sgblack@eecs.umich.edu //Convert string to lowercase 1047639Sgblack@eecs.umich.edu std::transform(policy.begin(), policy.end(), policy.begin(), 1057639Sgblack@eecs.umich.edu (int(*)(int)) tolower); 1067639Sgblack@eecs.umich.edu 1077639Sgblack@eecs.umich.edu //Figure out resource sharing policy 1087639Sgblack@eecs.umich.edu if (policy == "dynamic") { 1097639Sgblack@eecs.umich.edu iqPolicy = Dynamic; 1107639Sgblack@eecs.umich.edu 1117639Sgblack@eecs.umich.edu //Set Max Entries to Total ROB Capacity 1127639Sgblack@eecs.umich.edu for (int i = 0; i < numThreads; i++) { 1137639Sgblack@eecs.umich.edu maxEntries[i] = numEntries; 1147639Sgblack@eecs.umich.edu } 1157639Sgblack@eecs.umich.edu 1167639Sgblack@eecs.umich.edu } else if (policy == "partitioned") { 1177639Sgblack@eecs.umich.edu iqPolicy = Partitioned; 1187639Sgblack@eecs.umich.edu 1197639Sgblack@eecs.umich.edu //@todo:make work if part_amt doesnt divide evenly. 1207639Sgblack@eecs.umich.edu int part_amt = numEntries / numThreads; 1217639Sgblack@eecs.umich.edu 1227639Sgblack@eecs.umich.edu //Divide ROB up evenly 1237639Sgblack@eecs.umich.edu for (int i = 0; i < numThreads; i++) { 1247639Sgblack@eecs.umich.edu maxEntries[i] = part_amt; 1257639Sgblack@eecs.umich.edu } 1267639Sgblack@eecs.umich.edu 1277639Sgblack@eecs.umich.edu DPRINTF(Fetch, "IQ sharing policy set to Partitioned:" 1287639Sgblack@eecs.umich.edu "%i entries per thread.\n",part_amt); 1297639Sgblack@eecs.umich.edu 1307639Sgblack@eecs.umich.edu } else if (policy == "threshold") { 1317639Sgblack@eecs.umich.edu iqPolicy = Threshold; 1327639Sgblack@eecs.umich.edu 1337639Sgblack@eecs.umich.edu double threshold = (double)params->smtIQThreshold / 100; 1347639Sgblack@eecs.umich.edu 1357639Sgblack@eecs.umich.edu int thresholdIQ = (int)((double)threshold * numEntries); 1367639Sgblack@eecs.umich.edu 1377639Sgblack@eecs.umich.edu //Divide up by threshold amount 1387639Sgblack@eecs.umich.edu for (int i = 0; i < numThreads; i++) { 1397639Sgblack@eecs.umich.edu maxEntries[i] = thresholdIQ; 1407639Sgblack@eecs.umich.edu } 1417639Sgblack@eecs.umich.edu 1427639Sgblack@eecs.umich.edu DPRINTF(Fetch, "IQ sharing policy set to Threshold:" 1437639Sgblack@eecs.umich.edu "%i entries per thread.\n",thresholdIQ); 1447639Sgblack@eecs.umich.edu } else { 1457639Sgblack@eecs.umich.edu assert(0 && "Invalid IQ Sharing Policy.Options Are:{Dynamic," 1467639Sgblack@eecs.umich.edu "Partitioned, Threshold}"); 1477639Sgblack@eecs.umich.edu } 1487639Sgblack@eecs.umich.edu} 1497639Sgblack@eecs.umich.edu 1507639Sgblack@eecs.umich.edutemplate <class Impl> 1517639Sgblack@eecs.umich.eduInstructionQueue<Impl>::~InstructionQueue() 1527639Sgblack@eecs.umich.edu{ 1537639Sgblack@eecs.umich.edu dependGraph.reset(); 1547639Sgblack@eecs.umich.edu#ifdef DEBUG 1557639Sgblack@eecs.umich.edu cprintf("Nodes traversed: %i, removed: %i\n", 1567639Sgblack@eecs.umich.edu dependGraph.nodesTraversed, dependGraph.nodesRemoved); 1577639Sgblack@eecs.umich.edu#endif 1587639Sgblack@eecs.umich.edu} 1597639Sgblack@eecs.umich.edu 1607639Sgblack@eecs.umich.edutemplate <class Impl> 1617639Sgblack@eecs.umich.edustd::string 1627639Sgblack@eecs.umich.eduInstructionQueue<Impl>::name() const 1637639Sgblack@eecs.umich.edu{ 1647639Sgblack@eecs.umich.edu return cpu->name() + ".iq"; 1657639Sgblack@eecs.umich.edu} 1667639Sgblack@eecs.umich.edu 1677639Sgblack@eecs.umich.edutemplate <class Impl> 1687639Sgblack@eecs.umich.eduvoid 1697639Sgblack@eecs.umich.eduInstructionQueue<Impl>::regStats() 1707639Sgblack@eecs.umich.edu{ 1717639Sgblack@eecs.umich.edu using namespace Stats; 1727639Sgblack@eecs.umich.edu iqInstsAdded 1737639Sgblack@eecs.umich.edu .name(name() + ".iqInstsAdded") 1747639Sgblack@eecs.umich.edu .desc("Number of instructions added to the IQ (excludes non-spec)") 1757639Sgblack@eecs.umich.edu .prereq(iqInstsAdded); 1767639Sgblack@eecs.umich.edu 1777639Sgblack@eecs.umich.edu iqNonSpecInstsAdded 1787639Sgblack@eecs.umich.edu .name(name() + ".iqNonSpecInstsAdded") 1797639Sgblack@eecs.umich.edu .desc("Number of non-speculative instructions added to the IQ") 1807639Sgblack@eecs.umich.edu .prereq(iqNonSpecInstsAdded); 1817639Sgblack@eecs.umich.edu 1827639Sgblack@eecs.umich.edu iqInstsIssued 1837639Sgblack@eecs.umich.edu .name(name() + ".iqInstsIssued") 1847639Sgblack@eecs.umich.edu .desc("Number of instructions issued") 1857639Sgblack@eecs.umich.edu .prereq(iqInstsIssued); 1867639Sgblack@eecs.umich.edu 1877639Sgblack@eecs.umich.edu iqIntInstsIssued 1887639Sgblack@eecs.umich.edu .name(name() + ".iqIntInstsIssued") 1897639Sgblack@eecs.umich.edu .desc("Number of integer instructions issued") 1907639Sgblack@eecs.umich.edu .prereq(iqIntInstsIssued); 1917639Sgblack@eecs.umich.edu 1927639Sgblack@eecs.umich.edu iqFloatInstsIssued 1937639Sgblack@eecs.umich.edu .name(name() + ".iqFloatInstsIssued") 1947639Sgblack@eecs.umich.edu .desc("Number of float instructions issued") 1957639Sgblack@eecs.umich.edu .prereq(iqFloatInstsIssued); 1967639Sgblack@eecs.umich.edu 1977639Sgblack@eecs.umich.edu iqBranchInstsIssued 1987639Sgblack@eecs.umich.edu .name(name() + ".iqBranchInstsIssued") 1997639Sgblack@eecs.umich.edu .desc("Number of branch instructions issued") 2007639Sgblack@eecs.umich.edu .prereq(iqBranchInstsIssued); 2017639Sgblack@eecs.umich.edu 2027639Sgblack@eecs.umich.edu iqMemInstsIssued 2037639Sgblack@eecs.umich.edu .name(name() + ".iqMemInstsIssued") 2047639Sgblack@eecs.umich.edu .desc("Number of memory instructions issued") 2057639Sgblack@eecs.umich.edu .prereq(iqMemInstsIssued); 2067639Sgblack@eecs.umich.edu 2077639Sgblack@eecs.umich.edu iqMiscInstsIssued 2087639Sgblack@eecs.umich.edu .name(name() + ".iqMiscInstsIssued") 2097639Sgblack@eecs.umich.edu .desc("Number of miscellaneous instructions issued") 2107639Sgblack@eecs.umich.edu .prereq(iqMiscInstsIssued); 2117639Sgblack@eecs.umich.edu 2127639Sgblack@eecs.umich.edu iqSquashedInstsIssued 2137639Sgblack@eecs.umich.edu .name(name() + ".iqSquashedInstsIssued") 2147639Sgblack@eecs.umich.edu .desc("Number of squashed instructions issued") 2157639Sgblack@eecs.umich.edu .prereq(iqSquashedInstsIssued); 2167639Sgblack@eecs.umich.edu 2177639Sgblack@eecs.umich.edu iqSquashedInstsExamined 2187639Sgblack@eecs.umich.edu .name(name() + ".iqSquashedInstsExamined") 2197639Sgblack@eecs.umich.edu .desc("Number of squashed instructions iterated over during squash;" 2207639Sgblack@eecs.umich.edu " mainly for profiling") 2217639Sgblack@eecs.umich.edu .prereq(iqSquashedInstsExamined); 2227639Sgblack@eecs.umich.edu 2237639Sgblack@eecs.umich.edu iqSquashedOperandsExamined 2247639Sgblack@eecs.umich.edu .name(name() + ".iqSquashedOperandsExamined") 2257639Sgblack@eecs.umich.edu .desc("Number of squashed operands that are examined and possibly " 2267639Sgblack@eecs.umich.edu "removed from graph") 2277639Sgblack@eecs.umich.edu .prereq(iqSquashedOperandsExamined); 2287639Sgblack@eecs.umich.edu 2297639Sgblack@eecs.umich.edu iqSquashedNonSpecRemoved 2307639Sgblack@eecs.umich.edu .name(name() + ".iqSquashedNonSpecRemoved") 2317639Sgblack@eecs.umich.edu .desc("Number of squashed non-spec instructions that were removed") 2327639Sgblack@eecs.umich.edu .prereq(iqSquashedNonSpecRemoved); 2337639Sgblack@eecs.umich.edu 2347639Sgblack@eecs.umich.edu queueResDist 2357639Sgblack@eecs.umich.edu .init(Num_OpClasses, 0, 99, 2) 2367639Sgblack@eecs.umich.edu .name(name() + ".IQ:residence:") 2377639Sgblack@eecs.umich.edu .desc("cycles from dispatch to issue") 2387639Sgblack@eecs.umich.edu .flags(total | pdf | cdf ) 2397639Sgblack@eecs.umich.edu ; 2407639Sgblack@eecs.umich.edu for (int i = 0; i < Num_OpClasses; ++i) { 2417639Sgblack@eecs.umich.edu queueResDist.subname(i, opClassStrings[i]); 2427639Sgblack@eecs.umich.edu } 2437639Sgblack@eecs.umich.edu numIssuedDist 2447639Sgblack@eecs.umich.edu .init(0,totalWidth,1) 2457639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:issued_per_cycle") 2467639Sgblack@eecs.umich.edu .desc("Number of insts issued each cycle") 2477639Sgblack@eecs.umich.edu .flags(pdf) 2487639Sgblack@eecs.umich.edu ; 2497639Sgblack@eecs.umich.edu/* 2507639Sgblack@eecs.umich.edu dist_unissued 2517639Sgblack@eecs.umich.edu .init(Num_OpClasses+2) 2527639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:unissued_cause") 2537639Sgblack@eecs.umich.edu .desc("Reason ready instruction not issued") 2547639Sgblack@eecs.umich.edu .flags(pdf | dist) 2557639Sgblack@eecs.umich.edu ; 2567639Sgblack@eecs.umich.edu for (int i=0; i < (Num_OpClasses + 2); ++i) { 2577639Sgblack@eecs.umich.edu dist_unissued.subname(i, unissued_names[i]); 2587639Sgblack@eecs.umich.edu } 2597639Sgblack@eecs.umich.edu*/ 2607639Sgblack@eecs.umich.edu statIssuedInstType 2617639Sgblack@eecs.umich.edu .init(numThreads,Num_OpClasses) 2627639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:FU_type") 2637639Sgblack@eecs.umich.edu .desc("Type of FU issued") 2647639Sgblack@eecs.umich.edu .flags(total | pdf | dist) 2657639Sgblack@eecs.umich.edu ; 2667639Sgblack@eecs.umich.edu statIssuedInstType.ysubnames(opClassStrings); 2677639Sgblack@eecs.umich.edu 2687639Sgblack@eecs.umich.edu // 2697639Sgblack@eecs.umich.edu // How long did instructions for a particular FU type wait prior to issue 2707639Sgblack@eecs.umich.edu // 2717639Sgblack@eecs.umich.edu 2727639Sgblack@eecs.umich.edu issueDelayDist 2737639Sgblack@eecs.umich.edu .init(Num_OpClasses,0,99,2) 2747639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:") 2757639Sgblack@eecs.umich.edu .desc("cycles from operands ready to issue") 2767639Sgblack@eecs.umich.edu .flags(pdf | cdf) 2777639Sgblack@eecs.umich.edu ; 2787639Sgblack@eecs.umich.edu 2797639Sgblack@eecs.umich.edu for (int i=0; i<Num_OpClasses; ++i) { 2807639Sgblack@eecs.umich.edu stringstream subname; 2817639Sgblack@eecs.umich.edu subname << opClassStrings[i] << "_delay"; 2827639Sgblack@eecs.umich.edu issueDelayDist.subname(i, subname.str()); 2837639Sgblack@eecs.umich.edu } 2847639Sgblack@eecs.umich.edu 2857639Sgblack@eecs.umich.edu issueRate 2867639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:rate") 2877639Sgblack@eecs.umich.edu .desc("Inst issue rate") 2887639Sgblack@eecs.umich.edu .flags(total) 2897639Sgblack@eecs.umich.edu ; 2907639Sgblack@eecs.umich.edu issueRate = iqInstsIssued / cpu->numCycles; 2917639Sgblack@eecs.umich.edu/* 2927639Sgblack@eecs.umich.edu issue_stores 2937639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:stores") 2947639Sgblack@eecs.umich.edu .desc("Number of stores issued") 2957639Sgblack@eecs.umich.edu .flags(total) 2967639Sgblack@eecs.umich.edu ; 2977639Sgblack@eecs.umich.edu issue_stores = exe_refs - exe_loads; 2987639Sgblack@eecs.umich.edu*/ 2997639Sgblack@eecs.umich.edu/* 3007639Sgblack@eecs.umich.edu issue_op_rate 3017639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:op_rate") 3027639Sgblack@eecs.umich.edu .desc("Operation issue rate") 3037639Sgblack@eecs.umich.edu .flags(total) 3047639Sgblack@eecs.umich.edu ; 3057639Sgblack@eecs.umich.edu issue_op_rate = issued_ops / numCycles; 3067639Sgblack@eecs.umich.edu*/ 3077639Sgblack@eecs.umich.edu statFuBusy 3087639Sgblack@eecs.umich.edu .init(Num_OpClasses) 3097639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:fu_full") 3107639Sgblack@eecs.umich.edu .desc("attempts to use FU when none available") 3117639Sgblack@eecs.umich.edu .flags(pdf | dist) 3127639Sgblack@eecs.umich.edu ; 3137639Sgblack@eecs.umich.edu for (int i=0; i < Num_OpClasses; ++i) { 3147639Sgblack@eecs.umich.edu statFuBusy.subname(i, opClassStrings[i]); 3157639Sgblack@eecs.umich.edu } 3167639Sgblack@eecs.umich.edu 3177639Sgblack@eecs.umich.edu fuBusy 3187639Sgblack@eecs.umich.edu .init(numThreads) 3197639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:fu_busy_cnt") 3207639Sgblack@eecs.umich.edu .desc("FU busy when requested") 3217639Sgblack@eecs.umich.edu .flags(total) 3227639Sgblack@eecs.umich.edu ; 3237639Sgblack@eecs.umich.edu 3247639Sgblack@eecs.umich.edu fuBusyRate 3257639Sgblack@eecs.umich.edu .name(name() + ".ISSUE:fu_busy_rate") 3267639Sgblack@eecs.umich.edu .desc("FU busy rate (busy events/executed inst)") 3277639Sgblack@eecs.umich.edu .flags(total) 3287639Sgblack@eecs.umich.edu ; 3297639Sgblack@eecs.umich.edu fuBusyRate = fuBusy / iqInstsIssued; 3307639Sgblack@eecs.umich.edu 3317639Sgblack@eecs.umich.edu for ( int i=0; i < numThreads; i++) { 3327639Sgblack@eecs.umich.edu // Tell mem dependence unit to reg stats as well. 3337639Sgblack@eecs.umich.edu memDepUnit[i].regStats(); 3347639Sgblack@eecs.umich.edu } 3357639Sgblack@eecs.umich.edu} 3367639Sgblack@eecs.umich.edu 3377639Sgblack@eecs.umich.edutemplate <class Impl> 3387639Sgblack@eecs.umich.eduvoid 3397639Sgblack@eecs.umich.eduInstructionQueue<Impl>::resetState() 3407639Sgblack@eecs.umich.edu{ 3417639Sgblack@eecs.umich.edu //Initialize thread IQ counts 3427639Sgblack@eecs.umich.edu for (int i = 0; i <numThreads; i++) { 3437639Sgblack@eecs.umich.edu count[i] = 0; 3447639Sgblack@eecs.umich.edu instList[i].clear(); 3457639Sgblack@eecs.umich.edu } 3467639Sgblack@eecs.umich.edu 3477639Sgblack@eecs.umich.edu // Initialize the number of free IQ entries. 3487639Sgblack@eecs.umich.edu freeEntries = numEntries; 3497639Sgblack@eecs.umich.edu 3507639Sgblack@eecs.umich.edu // Note that in actuality, the registers corresponding to the logical 3517639Sgblack@eecs.umich.edu // registers start off as ready. However this doesn't matter for the 3527639Sgblack@eecs.umich.edu // IQ as the instruction should have been correctly told if those 3537639Sgblack@eecs.umich.edu // registers are ready in rename. Thus it can all be initialized as 3547639Sgblack@eecs.umich.edu // unready. 3557639Sgblack@eecs.umich.edu for (int i = 0; i < numPhysRegs; ++i) { 3567639Sgblack@eecs.umich.edu regScoreboard[i] = false; 3577639Sgblack@eecs.umich.edu } 3587639Sgblack@eecs.umich.edu 3597639Sgblack@eecs.umich.edu for (int i = 0; i < numThreads; ++i) { 3607639Sgblack@eecs.umich.edu squashedSeqNum[i] = 0; 3617639Sgblack@eecs.umich.edu } 3627639Sgblack@eecs.umich.edu 3637639Sgblack@eecs.umich.edu for (int i = 0; i < Num_OpClasses; ++i) { 3647639Sgblack@eecs.umich.edu while (!readyInsts[i].empty()) 3657639Sgblack@eecs.umich.edu readyInsts[i].pop(); 3667639Sgblack@eecs.umich.edu queueOnList[i] = false; 3677639Sgblack@eecs.umich.edu readyIt[i] = listOrder.end(); 3687639Sgblack@eecs.umich.edu } 3697639Sgblack@eecs.umich.edu nonSpecInsts.clear(); 3707639Sgblack@eecs.umich.edu listOrder.clear(); 3717639Sgblack@eecs.umich.edu} 3727639Sgblack@eecs.umich.edu 3737639Sgblack@eecs.umich.edutemplate <class Impl> 3747639Sgblack@eecs.umich.eduvoid 3757639Sgblack@eecs.umich.eduInstructionQueue<Impl>::setActiveThreads(list<unsigned> *at_ptr) 3767639Sgblack@eecs.umich.edu{ 3777639Sgblack@eecs.umich.edu DPRINTF(IQ, "Setting active threads list pointer.\n"); 3787639Sgblack@eecs.umich.edu activeThreads = at_ptr; 3797639Sgblack@eecs.umich.edu} 3807639Sgblack@eecs.umich.edu 3817639Sgblack@eecs.umich.edutemplate <class Impl> 3827639Sgblack@eecs.umich.eduvoid 3837639Sgblack@eecs.umich.eduInstructionQueue<Impl>::setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2e_ptr) 3847639Sgblack@eecs.umich.edu{ 3857639Sgblack@eecs.umich.edu DPRINTF(IQ, "Set the issue to execute queue.\n"); 3867639Sgblack@eecs.umich.edu issueToExecuteQueue = i2e_ptr; 3877639Sgblack@eecs.umich.edu} 3887639Sgblack@eecs.umich.edu 3897639Sgblack@eecs.umich.edutemplate <class Impl> 3907639Sgblack@eecs.umich.eduvoid 3917639Sgblack@eecs.umich.eduInstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 3927639Sgblack@eecs.umich.edu{ 3937639Sgblack@eecs.umich.edu DPRINTF(IQ, "Set the time buffer.\n"); 3947639Sgblack@eecs.umich.edu timeBuffer = tb_ptr; 3957639Sgblack@eecs.umich.edu 3967639Sgblack@eecs.umich.edu fromCommit = timeBuffer->getWire(-commitToIEWDelay); 3977639Sgblack@eecs.umich.edu} 3987639Sgblack@eecs.umich.edu 3997639Sgblack@eecs.umich.edutemplate <class Impl> 4007639Sgblack@eecs.umich.eduvoid 4017639Sgblack@eecs.umich.eduInstructionQueue<Impl>::switchOut() 4027639Sgblack@eecs.umich.edu{ 4037639Sgblack@eecs.umich.edu resetState(); 4047639Sgblack@eecs.umich.edu dependGraph.reset(); 4057639Sgblack@eecs.umich.edu switchedOut = true; 4067639Sgblack@eecs.umich.edu for (int i = 0; i < numThreads; ++i) { 4077639Sgblack@eecs.umich.edu memDepUnit[i].switchOut(); 4087639Sgblack@eecs.umich.edu } 4097639Sgblack@eecs.umich.edu} 4107639Sgblack@eecs.umich.edu 4117639Sgblack@eecs.umich.edutemplate <class Impl> 4127639Sgblack@eecs.umich.eduvoid 4137639Sgblack@eecs.umich.eduInstructionQueue<Impl>::takeOverFrom() 4147639Sgblack@eecs.umich.edu{ 4157639Sgblack@eecs.umich.edu switchedOut = false; 4167639Sgblack@eecs.umich.edu} 4177639Sgblack@eecs.umich.edu 4187639Sgblack@eecs.umich.edutemplate <class Impl> 4197639Sgblack@eecs.umich.eduint 4207639Sgblack@eecs.umich.eduInstructionQueue<Impl>::entryAmount(int num_threads) 4217639Sgblack@eecs.umich.edu{ 4227639Sgblack@eecs.umich.edu if (iqPolicy == Partitioned) { 4237639Sgblack@eecs.umich.edu return numEntries / num_threads; 4247639Sgblack@eecs.umich.edu } else { 4257639Sgblack@eecs.umich.edu return 0; 4267639Sgblack@eecs.umich.edu } 4277639Sgblack@eecs.umich.edu} 4287639Sgblack@eecs.umich.edu 4297639Sgblack@eecs.umich.edu 4307639Sgblack@eecs.umich.edutemplate <class Impl> 4317639Sgblack@eecs.umich.eduvoid 4327639Sgblack@eecs.umich.eduInstructionQueue<Impl>::resetEntries() 4337639Sgblack@eecs.umich.edu{ 4347639Sgblack@eecs.umich.edu if (iqPolicy != Dynamic || numThreads > 1) { 4357639Sgblack@eecs.umich.edu int active_threads = (*activeThreads).size(); 4367639Sgblack@eecs.umich.edu 4377639Sgblack@eecs.umich.edu list<unsigned>::iterator threads = (*activeThreads).begin(); 4387639Sgblack@eecs.umich.edu list<unsigned>::iterator list_end = (*activeThreads).end(); 4397639Sgblack@eecs.umich.edu 4407639Sgblack@eecs.umich.edu while (threads != list_end) { 4417639Sgblack@eecs.umich.edu if (iqPolicy == Partitioned) { 4427639Sgblack@eecs.umich.edu maxEntries[*threads++] = numEntries / active_threads; 4437639Sgblack@eecs.umich.edu } else if(iqPolicy == Threshold && active_threads == 1) { 4447639Sgblack@eecs.umich.edu maxEntries[*threads++] = numEntries; 4457639Sgblack@eecs.umich.edu } 4467639Sgblack@eecs.umich.edu } 4477639Sgblack@eecs.umich.edu } 4487639Sgblack@eecs.umich.edu} 4497639Sgblack@eecs.umich.edu 4507639Sgblack@eecs.umich.edutemplate <class Impl> 4517639Sgblack@eecs.umich.eduunsigned 4527639Sgblack@eecs.umich.eduInstructionQueue<Impl>::numFreeEntries() 4537639Sgblack@eecs.umich.edu{ 4547639Sgblack@eecs.umich.edu return freeEntries; 4557639Sgblack@eecs.umich.edu} 4567639Sgblack@eecs.umich.edu 4577639Sgblack@eecs.umich.edutemplate <class Impl> 4587639Sgblack@eecs.umich.eduunsigned 4597639Sgblack@eecs.umich.eduInstructionQueue<Impl>::numFreeEntries(unsigned tid) 4607639Sgblack@eecs.umich.edu{ 4617639Sgblack@eecs.umich.edu return maxEntries[tid] - count[tid]; 4627639Sgblack@eecs.umich.edu} 4637639Sgblack@eecs.umich.edu 4647639Sgblack@eecs.umich.edu// Might want to do something more complex if it knows how many instructions 4657639Sgblack@eecs.umich.edu// will be issued this cycle. 4667639Sgblack@eecs.umich.edutemplate <class Impl> 4677639Sgblack@eecs.umich.edubool 4687639Sgblack@eecs.umich.eduInstructionQueue<Impl>::isFull() 4697639Sgblack@eecs.umich.edu{ 4707639Sgblack@eecs.umich.edu if (freeEntries == 0) { 4717639Sgblack@eecs.umich.edu return(true); 4727639Sgblack@eecs.umich.edu } else { 4737639Sgblack@eecs.umich.edu return(false); 4747639Sgblack@eecs.umich.edu } 4757639Sgblack@eecs.umich.edu} 4767639Sgblack@eecs.umich.edu 4777639Sgblack@eecs.umich.edutemplate <class Impl> 4787639Sgblack@eecs.umich.edubool 4797639Sgblack@eecs.umich.eduInstructionQueue<Impl>::isFull(unsigned tid) 4807639Sgblack@eecs.umich.edu{ 4817639Sgblack@eecs.umich.edu if (numFreeEntries(tid) == 0) { 4827639Sgblack@eecs.umich.edu return(true); 4837639Sgblack@eecs.umich.edu } else { 4847639Sgblack@eecs.umich.edu return(false); 4857639Sgblack@eecs.umich.edu } 4867639Sgblack@eecs.umich.edu} 4877639Sgblack@eecs.umich.edu 4887639Sgblack@eecs.umich.edutemplate <class Impl> 4897639Sgblack@eecs.umich.edubool 4907639Sgblack@eecs.umich.eduInstructionQueue<Impl>::hasReadyInsts() 4917639Sgblack@eecs.umich.edu{ 4927639Sgblack@eecs.umich.edu if (!listOrder.empty()) { 4937639Sgblack@eecs.umich.edu return true; 4947639Sgblack@eecs.umich.edu } 4957639Sgblack@eecs.umich.edu 4967639Sgblack@eecs.umich.edu for (int i = 0; i < Num_OpClasses; ++i) { 4977639Sgblack@eecs.umich.edu if (!readyInsts[i].empty()) { 4987639Sgblack@eecs.umich.edu return true; 4997639Sgblack@eecs.umich.edu } 5007639Sgblack@eecs.umich.edu } 5017639Sgblack@eecs.umich.edu 5027639Sgblack@eecs.umich.edu return false; 5037639Sgblack@eecs.umich.edu} 5047639Sgblack@eecs.umich.edu 5057639Sgblack@eecs.umich.edutemplate <class Impl> 5067639Sgblack@eecs.umich.eduvoid 5077639Sgblack@eecs.umich.eduInstructionQueue<Impl>::insert(DynInstPtr &new_inst) 5087639Sgblack@eecs.umich.edu{ 5097639Sgblack@eecs.umich.edu // Make sure the instruction is valid 5107639Sgblack@eecs.umich.edu assert(new_inst); 5117639Sgblack@eecs.umich.edu 5127639Sgblack@eecs.umich.edu DPRINTF(IQ, "Adding instruction [sn:%lli] PC %#x to the IQ.\n", 5137639Sgblack@eecs.umich.edu new_inst->seqNum, new_inst->readPC()); 5147639Sgblack@eecs.umich.edu 5157639Sgblack@eecs.umich.edu assert(freeEntries != 0); 5167639Sgblack@eecs.umich.edu 5177639Sgblack@eecs.umich.edu instList[new_inst->threadNumber].push_back(new_inst); 5187639Sgblack@eecs.umich.edu 5197639Sgblack@eecs.umich.edu --freeEntries; 5207639Sgblack@eecs.umich.edu 5217639Sgblack@eecs.umich.edu new_inst->setInIQ(); 5227639Sgblack@eecs.umich.edu 5237639Sgblack@eecs.umich.edu // Look through its source registers (physical regs), and mark any 5247639Sgblack@eecs.umich.edu // dependencies. 5257639Sgblack@eecs.umich.edu addToDependents(new_inst); 5267639Sgblack@eecs.umich.edu 5277639Sgblack@eecs.umich.edu // Have this instruction set itself as the producer of its destination 5287639Sgblack@eecs.umich.edu // register(s). 5297639Sgblack@eecs.umich.edu addToProducers(new_inst); 5307639Sgblack@eecs.umich.edu 5317639Sgblack@eecs.umich.edu if (new_inst->isMemRef()) { 5327639Sgblack@eecs.umich.edu memDepUnit[new_inst->threadNumber].insert(new_inst); 5337639Sgblack@eecs.umich.edu } else { 5347639Sgblack@eecs.umich.edu addIfReady(new_inst); 5357639Sgblack@eecs.umich.edu } 5367639Sgblack@eecs.umich.edu 5377639Sgblack@eecs.umich.edu ++iqInstsAdded; 5387639Sgblack@eecs.umich.edu 5397639Sgblack@eecs.umich.edu count[new_inst->threadNumber]++; 5407639Sgblack@eecs.umich.edu 5417639Sgblack@eecs.umich.edu assert(freeEntries == (numEntries - countInsts())); 5427639Sgblack@eecs.umich.edu} 5437639Sgblack@eecs.umich.edu 5447639Sgblack@eecs.umich.edutemplate <class Impl> 5457639Sgblack@eecs.umich.eduvoid 5467639Sgblack@eecs.umich.eduInstructionQueue<Impl>::insertNonSpec(DynInstPtr &new_inst) 5477639Sgblack@eecs.umich.edu{ 5487639Sgblack@eecs.umich.edu // @todo: Clean up this code; can do it by setting inst as unable 5497639Sgblack@eecs.umich.edu // to issue, then calling normal insert on the inst. 5507639Sgblack@eecs.umich.edu 5517639Sgblack@eecs.umich.edu assert(new_inst); 5527639Sgblack@eecs.umich.edu 5537639Sgblack@eecs.umich.edu nonSpecInsts[new_inst->seqNum] = new_inst; 5547639Sgblack@eecs.umich.edu 5557639Sgblack@eecs.umich.edu DPRINTF(IQ, "Adding non-speculative instruction [sn:%lli] PC %#x " 5567639Sgblack@eecs.umich.edu "to the IQ.\n", 5577639Sgblack@eecs.umich.edu new_inst->seqNum, new_inst->readPC()); 5587639Sgblack@eecs.umich.edu 5597639Sgblack@eecs.umich.edu assert(freeEntries != 0); 5607639Sgblack@eecs.umich.edu 5617639Sgblack@eecs.umich.edu instList[new_inst->threadNumber].push_back(new_inst); 5627639Sgblack@eecs.umich.edu 5637639Sgblack@eecs.umich.edu --freeEntries; 5647639Sgblack@eecs.umich.edu 5657639Sgblack@eecs.umich.edu new_inst->setInIQ(); 5667639Sgblack@eecs.umich.edu 5677639Sgblack@eecs.umich.edu // Have this instruction set itself as the producer of its destination 5687639Sgblack@eecs.umich.edu // register(s). 5697639Sgblack@eecs.umich.edu addToProducers(new_inst); 5707639Sgblack@eecs.umich.edu 5717639Sgblack@eecs.umich.edu // If it's a memory instruction, add it to the memory dependency 5727639Sgblack@eecs.umich.edu // unit. 5737639Sgblack@eecs.umich.edu if (new_inst->isMemRef()) { 5747639Sgblack@eecs.umich.edu memDepUnit[new_inst->threadNumber].insertNonSpec(new_inst); 5757639Sgblack@eecs.umich.edu } 5767639Sgblack@eecs.umich.edu 5777639Sgblack@eecs.umich.edu ++iqNonSpecInstsAdded; 5787639Sgblack@eecs.umich.edu 5797639Sgblack@eecs.umich.edu count[new_inst->threadNumber]++; 5807639Sgblack@eecs.umich.edu 5817639Sgblack@eecs.umich.edu assert(freeEntries == (numEntries - countInsts())); 5827639Sgblack@eecs.umich.edu} 5837639Sgblack@eecs.umich.edu 5847639Sgblack@eecs.umich.edutemplate <class Impl> 5857639Sgblack@eecs.umich.eduvoid 5867639Sgblack@eecs.umich.eduInstructionQueue<Impl>::insertBarrier(DynInstPtr &barr_inst) 5877639Sgblack@eecs.umich.edu{ 5887639Sgblack@eecs.umich.edu memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst); 5897639Sgblack@eecs.umich.edu 5907639Sgblack@eecs.umich.edu insertNonSpec(barr_inst); 5917639Sgblack@eecs.umich.edu} 5927639Sgblack@eecs.umich.edu 5937639Sgblack@eecs.umich.edutemplate <class Impl> 5947639Sgblack@eecs.umich.edutypename Impl::DynInstPtr 5957639Sgblack@eecs.umich.eduInstructionQueue<Impl>::getInstToExecute() 5967639Sgblack@eecs.umich.edu{ 5977639Sgblack@eecs.umich.edu assert(!instsToExecute.empty()); 5987639Sgblack@eecs.umich.edu DynInstPtr inst = instsToExecute.front(); 5997639Sgblack@eecs.umich.edu instsToExecute.pop_front(); 6007639Sgblack@eecs.umich.edu return inst; 6017639Sgblack@eecs.umich.edu} 6027639Sgblack@eecs.umich.edu 6037639Sgblack@eecs.umich.edutemplate <class Impl> 6047639Sgblack@eecs.umich.eduvoid 6057639Sgblack@eecs.umich.eduInstructionQueue<Impl>::addToOrderList(OpClass op_class) 6067639Sgblack@eecs.umich.edu{ 6077639Sgblack@eecs.umich.edu assert(!readyInsts[op_class].empty()); 6087639Sgblack@eecs.umich.edu 6097639Sgblack@eecs.umich.edu ListOrderEntry queue_entry; 6107639Sgblack@eecs.umich.edu 6117639Sgblack@eecs.umich.edu queue_entry.queueType = op_class; 6127639Sgblack@eecs.umich.edu 6137639Sgblack@eecs.umich.edu queue_entry.oldestInst = readyInsts[op_class].top()->seqNum; 6147639Sgblack@eecs.umich.edu 6157639Sgblack@eecs.umich.edu ListOrderIt list_it = listOrder.begin(); 6167639Sgblack@eecs.umich.edu ListOrderIt list_end_it = listOrder.end(); 6177639Sgblack@eecs.umich.edu 6187639Sgblack@eecs.umich.edu while (list_it != list_end_it) { 6197639Sgblack@eecs.umich.edu if ((*list_it).oldestInst > queue_entry.oldestInst) { 6207639Sgblack@eecs.umich.edu break; 6217639Sgblack@eecs.umich.edu } 6227639Sgblack@eecs.umich.edu 6237639Sgblack@eecs.umich.edu list_it++; 6247639Sgblack@eecs.umich.edu } 6257639Sgblack@eecs.umich.edu 6267639Sgblack@eecs.umich.edu readyIt[op_class] = listOrder.insert(list_it, queue_entry); 6277639Sgblack@eecs.umich.edu queueOnList[op_class] = true; 6287639Sgblack@eecs.umich.edu} 6297639Sgblack@eecs.umich.edu 6307639Sgblack@eecs.umich.edutemplate <class Impl> 6317639Sgblack@eecs.umich.eduvoid 6327639Sgblack@eecs.umich.eduInstructionQueue<Impl>::moveToYoungerInst(ListOrderIt list_order_it) 6337639Sgblack@eecs.umich.edu{ 6347639Sgblack@eecs.umich.edu // Get iterator of next item on the list 6357639Sgblack@eecs.umich.edu // Delete the original iterator 6367639Sgblack@eecs.umich.edu // Determine if the next item is either the end of the list or younger 6377639Sgblack@eecs.umich.edu // than the new instruction. If so, then add in a new iterator right here. 6387639Sgblack@eecs.umich.edu // If not, then move along. 6397639Sgblack@eecs.umich.edu ListOrderEntry queue_entry; 6407639Sgblack@eecs.umich.edu OpClass op_class = (*list_order_it).queueType; 6417639Sgblack@eecs.umich.edu ListOrderIt next_it = list_order_it; 6427639Sgblack@eecs.umich.edu 6437639Sgblack@eecs.umich.edu ++next_it; 6447639Sgblack@eecs.umich.edu 6457639Sgblack@eecs.umich.edu queue_entry.queueType = op_class; 6467639Sgblack@eecs.umich.edu queue_entry.oldestInst = readyInsts[op_class].top()->seqNum; 6477639Sgblack@eecs.umich.edu 6487639Sgblack@eecs.umich.edu while (next_it != listOrder.end() && 6497639Sgblack@eecs.umich.edu (*next_it).oldestInst < queue_entry.oldestInst) { 6507639Sgblack@eecs.umich.edu ++next_it; 6517639Sgblack@eecs.umich.edu } 6527639Sgblack@eecs.umich.edu 6537639Sgblack@eecs.umich.edu readyIt[op_class] = listOrder.insert(next_it, queue_entry); 6547639Sgblack@eecs.umich.edu} 6557639Sgblack@eecs.umich.edu 6567639Sgblack@eecs.umich.edutemplate <class Impl> 6577639Sgblack@eecs.umich.eduvoid 6587639Sgblack@eecs.umich.eduInstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx) 6597639Sgblack@eecs.umich.edu{ 6607639Sgblack@eecs.umich.edu // The CPU could have been sleeping until this op completed (*extremely* 6617639Sgblack@eecs.umich.edu // long latency op). Wake it if it was. This may be overkill. 6627639Sgblack@eecs.umich.edu if (isSwitchedOut()) { 6637639Sgblack@eecs.umich.edu return; 6647639Sgblack@eecs.umich.edu } 6657639Sgblack@eecs.umich.edu 6667639Sgblack@eecs.umich.edu iewStage->wakeCPU(); 6677639Sgblack@eecs.umich.edu 6687639Sgblack@eecs.umich.edu if (fu_idx > -1) 6697639Sgblack@eecs.umich.edu fuPool->freeUnitNextCycle(fu_idx); 6707639Sgblack@eecs.umich.edu 6717639Sgblack@eecs.umich.edu // @todo: Ensure that these FU Completions happen at the beginning 6727639Sgblack@eecs.umich.edu // of a cycle, otherwise they could add too many instructions to 6737639Sgblack@eecs.umich.edu // the queue. 6747639Sgblack@eecs.umich.edu issueToExecuteQueue->access(0)->size++; 6757639Sgblack@eecs.umich.edu instsToExecute.push_back(inst); 6767639Sgblack@eecs.umich.edu} 6777639Sgblack@eecs.umich.edu 6787639Sgblack@eecs.umich.edu// @todo: Figure out a better way to remove the squashed items from the 6797639Sgblack@eecs.umich.edu// lists. Checking the top item of each list to see if it's squashed 6807639Sgblack@eecs.umich.edu// wastes time and forces jumps. 6817639Sgblack@eecs.umich.edutemplate <class Impl> 6827639Sgblack@eecs.umich.eduvoid 6837639Sgblack@eecs.umich.eduInstructionQueue<Impl>::scheduleReadyInsts() 6847639Sgblack@eecs.umich.edu{ 6857639Sgblack@eecs.umich.edu DPRINTF(IQ, "Attempting to schedule ready instructions from " 6867639Sgblack@eecs.umich.edu "the IQ.\n"); 6877639Sgblack@eecs.umich.edu 6887639Sgblack@eecs.umich.edu IssueStruct *i2e_info = issueToExecuteQueue->access(0); 6897639Sgblack@eecs.umich.edu 6907639Sgblack@eecs.umich.edu // Have iterator to head of the list 6917639Sgblack@eecs.umich.edu // While I haven't exceeded bandwidth or reached the end of the list, 6927639Sgblack@eecs.umich.edu // Try to get a FU that can do what this op needs. 6937639Sgblack@eecs.umich.edu // If successful, change the oldestInst to the new top of the list, put 6947639Sgblack@eecs.umich.edu // the queue in the proper place in the list. 6957639Sgblack@eecs.umich.edu // Increment the iterator. 6967639Sgblack@eecs.umich.edu // This will avoid trying to schedule a certain op class if there are no 6977639Sgblack@eecs.umich.edu // FUs that handle it. 6987639Sgblack@eecs.umich.edu ListOrderIt order_it = listOrder.begin(); 6997639Sgblack@eecs.umich.edu ListOrderIt order_end_it = listOrder.end(); 7007639Sgblack@eecs.umich.edu int total_issued = 0; 7017639Sgblack@eecs.umich.edu 7027639Sgblack@eecs.umich.edu while (total_issued < totalWidth && 7037639Sgblack@eecs.umich.edu order_it != order_end_it) { 7047639Sgblack@eecs.umich.edu OpClass op_class = (*order_it).queueType; 7057639Sgblack@eecs.umich.edu 7067639Sgblack@eecs.umich.edu assert(!readyInsts[op_class].empty()); 7077639Sgblack@eecs.umich.edu 7087639Sgblack@eecs.umich.edu DynInstPtr issuing_inst = readyInsts[op_class].top(); 7097639Sgblack@eecs.umich.edu 7107639Sgblack@eecs.umich.edu assert(issuing_inst->seqNum == (*order_it).oldestInst); 7117639Sgblack@eecs.umich.edu 7127639Sgblack@eecs.umich.edu if (issuing_inst->isSquashed()) { 7137639Sgblack@eecs.umich.edu readyInsts[op_class].pop(); 7147639Sgblack@eecs.umich.edu 7157639Sgblack@eecs.umich.edu if (!readyInsts[op_class].empty()) { 7167639Sgblack@eecs.umich.edu moveToYoungerInst(order_it); 7177639Sgblack@eecs.umich.edu } else { 7187639Sgblack@eecs.umich.edu readyIt[op_class] = listOrder.end(); 7197639Sgblack@eecs.umich.edu queueOnList[op_class] = false; 7207639Sgblack@eecs.umich.edu } 7217639Sgblack@eecs.umich.edu 7227639Sgblack@eecs.umich.edu listOrder.erase(order_it++); 7237639Sgblack@eecs.umich.edu 7247639Sgblack@eecs.umich.edu ++iqSquashedInstsIssued; 7257639Sgblack@eecs.umich.edu 7267639Sgblack@eecs.umich.edu continue; 7277639Sgblack@eecs.umich.edu } 7287639Sgblack@eecs.umich.edu 7297639Sgblack@eecs.umich.edu int idx = -2; 7307639Sgblack@eecs.umich.edu int op_latency = 1; 7317639Sgblack@eecs.umich.edu int tid = issuing_inst->threadNumber; 7327639Sgblack@eecs.umich.edu 7337639Sgblack@eecs.umich.edu if (op_class != No_OpClass) { 7347639Sgblack@eecs.umich.edu idx = fuPool->getUnit(op_class); 7357639Sgblack@eecs.umich.edu 7367639Sgblack@eecs.umich.edu if (idx > -1) { 7377639Sgblack@eecs.umich.edu op_latency = fuPool->getOpLatency(op_class); 7387639Sgblack@eecs.umich.edu } 7397639Sgblack@eecs.umich.edu } 7407639Sgblack@eecs.umich.edu 7417639Sgblack@eecs.umich.edu // If we have an instruction that doesn't require a FU, or a 7427639Sgblack@eecs.umich.edu // valid FU, then schedule for execution. 7437639Sgblack@eecs.umich.edu if (idx == -2 || idx != -1) { 7447639Sgblack@eecs.umich.edu if (op_latency == 1) { 7457639Sgblack@eecs.umich.edu i2e_info->size++; 7467639Sgblack@eecs.umich.edu instsToExecute.push_back(issuing_inst); 7477639Sgblack@eecs.umich.edu 7487639Sgblack@eecs.umich.edu // Add the FU onto the list of FU's to be freed next 7497639Sgblack@eecs.umich.edu // cycle if we used one. 7507639Sgblack@eecs.umich.edu if (idx >= 0) 7517639Sgblack@eecs.umich.edu fuPool->freeUnitNextCycle(idx); 7527639Sgblack@eecs.umich.edu } else { 7537639Sgblack@eecs.umich.edu int issue_latency = fuPool->getIssueLatency(op_class); 7547639Sgblack@eecs.umich.edu // Generate completion event for the FU 7557639Sgblack@eecs.umich.edu FUCompletion *execution = new FUCompletion(issuing_inst, 7567639Sgblack@eecs.umich.edu idx, this); 7577639Sgblack@eecs.umich.edu 7587639Sgblack@eecs.umich.edu execution->schedule(curTick + cpu->cycles(issue_latency - 1)); 7597639Sgblack@eecs.umich.edu 7607639Sgblack@eecs.umich.edu // @todo: Enforce that issue_latency == 1 or op_latency 7617639Sgblack@eecs.umich.edu if (issue_latency > 1) { 7627639Sgblack@eecs.umich.edu // If FU isn't pipelined, then it must be freed 7637639Sgblack@eecs.umich.edu // upon the execution completing. 7647639Sgblack@eecs.umich.edu execution->setFreeFU(); 7657639Sgblack@eecs.umich.edu } else { 7667639Sgblack@eecs.umich.edu // Add the FU onto the list of FU's to be freed next cycle. 7677639Sgblack@eecs.umich.edu fuPool->freeUnitNextCycle(idx); 7687639Sgblack@eecs.umich.edu } 7697639Sgblack@eecs.umich.edu } 7707639Sgblack@eecs.umich.edu 7717639Sgblack@eecs.umich.edu DPRINTF(IQ, "Thread %i: Issuing instruction PC %#x " 7727639Sgblack@eecs.umich.edu "[sn:%lli]\n", 7737639Sgblack@eecs.umich.edu tid, issuing_inst->readPC(), 7747639Sgblack@eecs.umich.edu issuing_inst->seqNum); 7757639Sgblack@eecs.umich.edu 7767639Sgblack@eecs.umich.edu readyInsts[op_class].pop(); 7777639Sgblack@eecs.umich.edu 7787639Sgblack@eecs.umich.edu if (!readyInsts[op_class].empty()) { 7797639Sgblack@eecs.umich.edu moveToYoungerInst(order_it); 7807639Sgblack@eecs.umich.edu } else { 7817639Sgblack@eecs.umich.edu readyIt[op_class] = listOrder.end(); 7827639Sgblack@eecs.umich.edu queueOnList[op_class] = false; 7837639Sgblack@eecs.umich.edu } 7847639Sgblack@eecs.umich.edu 7857639Sgblack@eecs.umich.edu issuing_inst->setIssued(); 7867639Sgblack@eecs.umich.edu ++total_issued; 7877639Sgblack@eecs.umich.edu 7887639Sgblack@eecs.umich.edu if (!issuing_inst->isMemRef()) { 7897639Sgblack@eecs.umich.edu // Memory instructions can not be freed from the IQ until they 7907639Sgblack@eecs.umich.edu // complete. 7917639Sgblack@eecs.umich.edu ++freeEntries; 7927639Sgblack@eecs.umich.edu count[tid]--; 7937639Sgblack@eecs.umich.edu issuing_inst->removeInIQ(); 7947639Sgblack@eecs.umich.edu } else { 7957639Sgblack@eecs.umich.edu memDepUnit[tid].issue(issuing_inst); 7967639Sgblack@eecs.umich.edu } 7977639Sgblack@eecs.umich.edu 7987639Sgblack@eecs.umich.edu listOrder.erase(order_it++); 7997639Sgblack@eecs.umich.edu statIssuedInstType[tid][op_class]++; 8007639Sgblack@eecs.umich.edu } else { 8017639Sgblack@eecs.umich.edu statFuBusy[op_class]++; 8027639Sgblack@eecs.umich.edu fuBusy[tid]++; 8037639Sgblack@eecs.umich.edu ++order_it; 8047639Sgblack@eecs.umich.edu } 8057639Sgblack@eecs.umich.edu } 8067639Sgblack@eecs.umich.edu 8077639Sgblack@eecs.umich.edu numIssuedDist.sample(total_issued); 8087639Sgblack@eecs.umich.edu iqInstsIssued+= total_issued; 8097639Sgblack@eecs.umich.edu 8107639Sgblack@eecs.umich.edu // If we issued any instructions, tell the CPU we had activity. 8117639Sgblack@eecs.umich.edu if (total_issued) { 8127639Sgblack@eecs.umich.edu cpu->activityThisCycle(); 8137639Sgblack@eecs.umich.edu } else { 8147639Sgblack@eecs.umich.edu DPRINTF(IQ, "Not able to schedule any instructions.\n"); 8157639Sgblack@eecs.umich.edu } 8167639Sgblack@eecs.umich.edu} 8177639Sgblack@eecs.umich.edu 8187639Sgblack@eecs.umich.edutemplate <class Impl> 8197639Sgblack@eecs.umich.eduvoid 8207639Sgblack@eecs.umich.eduInstructionQueue<Impl>::scheduleNonSpec(const InstSeqNum &inst) 8217639Sgblack@eecs.umich.edu{ 8227639Sgblack@eecs.umich.edu DPRINTF(IQ, "Marking nonspeculative instruction [sn:%lli] as ready " 8237639Sgblack@eecs.umich.edu "to execute.\n", inst); 8247639Sgblack@eecs.umich.edu 8257639Sgblack@eecs.umich.edu NonSpecMapIt inst_it = nonSpecInsts.find(inst); 8267639Sgblack@eecs.umich.edu 8277639Sgblack@eecs.umich.edu assert(inst_it != nonSpecInsts.end()); 8287639Sgblack@eecs.umich.edu 8297639Sgblack@eecs.umich.edu unsigned tid = (*inst_it).second->threadNumber; 8307639Sgblack@eecs.umich.edu 8317639Sgblack@eecs.umich.edu (*inst_it).second->setCanIssue(); 8327639Sgblack@eecs.umich.edu 8337639Sgblack@eecs.umich.edu if (!(*inst_it).second->isMemRef()) { 8347639Sgblack@eecs.umich.edu addIfReady((*inst_it).second); 8357639Sgblack@eecs.umich.edu } else { 8367639Sgblack@eecs.umich.edu memDepUnit[tid].nonSpecInstReady((*inst_it).second); 8377639Sgblack@eecs.umich.edu } 8387639Sgblack@eecs.umich.edu 8397639Sgblack@eecs.umich.edu (*inst_it).second = NULL; 8407639Sgblack@eecs.umich.edu 8417639Sgblack@eecs.umich.edu nonSpecInsts.erase(inst_it); 8427639Sgblack@eecs.umich.edu} 8437639Sgblack@eecs.umich.edu 8447639Sgblack@eecs.umich.edutemplate <class Impl> 8457639Sgblack@eecs.umich.eduvoid 8467639Sgblack@eecs.umich.eduInstructionQueue<Impl>::commit(const InstSeqNum &inst, unsigned tid) 8477639Sgblack@eecs.umich.edu{ 8487639Sgblack@eecs.umich.edu DPRINTF(IQ, "[tid:%i]: Committing instructions older than [sn:%i]\n", 8497639Sgblack@eecs.umich.edu tid,inst); 8507639Sgblack@eecs.umich.edu 8517639Sgblack@eecs.umich.edu ListIt iq_it = instList[tid].begin(); 8527639Sgblack@eecs.umich.edu 8537639Sgblack@eecs.umich.edu while (iq_it != instList[tid].end() && 8547639Sgblack@eecs.umich.edu (*iq_it)->seqNum <= inst) { 8557639Sgblack@eecs.umich.edu ++iq_it; 8567639Sgblack@eecs.umich.edu instList[tid].pop_front(); 8577639Sgblack@eecs.umich.edu } 8587639Sgblack@eecs.umich.edu 8597639Sgblack@eecs.umich.edu assert(freeEntries == (numEntries - countInsts())); 8607639Sgblack@eecs.umich.edu} 8617639Sgblack@eecs.umich.edu 8627639Sgblack@eecs.umich.edutemplate <class Impl> 8637639Sgblack@eecs.umich.eduint 8647639Sgblack@eecs.umich.eduInstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst) 8657639Sgblack@eecs.umich.edu{ 8667639Sgblack@eecs.umich.edu int dependents = 0; 8677639Sgblack@eecs.umich.edu 8687639Sgblack@eecs.umich.edu DPRINTF(IQ, "Waking dependents of completed instruction.\n"); 8697639Sgblack@eecs.umich.edu 8707639Sgblack@eecs.umich.edu assert(!completed_inst->isSquashed()); 8717639Sgblack@eecs.umich.edu 8727639Sgblack@eecs.umich.edu // Tell the memory dependence unit to wake any dependents on this 8737639Sgblack@eecs.umich.edu // instruction if it is a memory instruction. Also complete the memory 8747639Sgblack@eecs.umich.edu // instruction at this point since we know it executed without issues. 8757639Sgblack@eecs.umich.edu // @todo: Might want to rename "completeMemInst" to something that 8767639Sgblack@eecs.umich.edu // indicates that it won't need to be replayed, and call this 8777639Sgblack@eecs.umich.edu // earlier. Might not be a big deal. 8787639Sgblack@eecs.umich.edu if (completed_inst->isMemRef()) { 8797639Sgblack@eecs.umich.edu memDepUnit[completed_inst->threadNumber].wakeDependents(completed_inst); 8807639Sgblack@eecs.umich.edu completeMemInst(completed_inst); 8817639Sgblack@eecs.umich.edu } else if (completed_inst->isMemBarrier() || 8827639Sgblack@eecs.umich.edu completed_inst->isWriteBarrier()) { 8837639Sgblack@eecs.umich.edu memDepUnit[completed_inst->threadNumber].completeBarrier(completed_inst); 8847639Sgblack@eecs.umich.edu } 8857639Sgblack@eecs.umich.edu 8867639Sgblack@eecs.umich.edu for (int dest_reg_idx = 0; 8877639Sgblack@eecs.umich.edu dest_reg_idx < completed_inst->numDestRegs(); 8887639Sgblack@eecs.umich.edu dest_reg_idx++) 8897639Sgblack@eecs.umich.edu { 8907639Sgblack@eecs.umich.edu PhysRegIndex dest_reg = 8917639Sgblack@eecs.umich.edu completed_inst->renamedDestRegIdx(dest_reg_idx); 8927639Sgblack@eecs.umich.edu 8937639Sgblack@eecs.umich.edu // Special case of uniq or control registers. They are not 8947639Sgblack@eecs.umich.edu // handled by the IQ and thus have no dependency graph entry. 8957639Sgblack@eecs.umich.edu // @todo Figure out a cleaner way to handle this. 8967639Sgblack@eecs.umich.edu if (dest_reg >= numPhysRegs) { 8977639Sgblack@eecs.umich.edu continue; 8987639Sgblack@eecs.umich.edu } 8997639Sgblack@eecs.umich.edu 9007639Sgblack@eecs.umich.edu DPRINTF(IQ, "Waking any dependents on register %i.\n", 9017639Sgblack@eecs.umich.edu (int) dest_reg); 9027639Sgblack@eecs.umich.edu 9037639Sgblack@eecs.umich.edu //Go through the dependency chain, marking the registers as 9047639Sgblack@eecs.umich.edu //ready within the waiting instructions. 9057639Sgblack@eecs.umich.edu DynInstPtr dep_inst = dependGraph.pop(dest_reg); 9067639Sgblack@eecs.umich.edu 9077639Sgblack@eecs.umich.edu while (dep_inst) { 9087639Sgblack@eecs.umich.edu DPRINTF(IQ, "Waking up a dependent instruction, PC%#x.\n", 9097639Sgblack@eecs.umich.edu dep_inst->readPC()); 9107639Sgblack@eecs.umich.edu 9117639Sgblack@eecs.umich.edu // Might want to give more information to the instruction 9127639Sgblack@eecs.umich.edu // so that it knows which of its source registers is 9137639Sgblack@eecs.umich.edu // ready. However that would mean that the dependency 9147639Sgblack@eecs.umich.edu // graph entries would need to hold the src_reg_idx. 9157639Sgblack@eecs.umich.edu dep_inst->markSrcRegReady(); 9167639Sgblack@eecs.umich.edu 9177639Sgblack@eecs.umich.edu addIfReady(dep_inst); 9187639Sgblack@eecs.umich.edu 9197639Sgblack@eecs.umich.edu dep_inst = dependGraph.pop(dest_reg); 9207639Sgblack@eecs.umich.edu 9217639Sgblack@eecs.umich.edu ++dependents; 9227639Sgblack@eecs.umich.edu } 9237639Sgblack@eecs.umich.edu 9247639Sgblack@eecs.umich.edu // Reset the head node now that all of its dependents have 9257639Sgblack@eecs.umich.edu // been woken up. 9267639Sgblack@eecs.umich.edu assert(dependGraph.empty(dest_reg)); 9277639Sgblack@eecs.umich.edu dependGraph.clearInst(dest_reg); 9287639Sgblack@eecs.umich.edu 9297639Sgblack@eecs.umich.edu // Mark the scoreboard as having that register ready. 9307639Sgblack@eecs.umich.edu regScoreboard[dest_reg] = true; 9317639Sgblack@eecs.umich.edu } 9327639Sgblack@eecs.umich.edu return dependents; 9337639Sgblack@eecs.umich.edu} 9347639Sgblack@eecs.umich.edu 9357639Sgblack@eecs.umich.edutemplate <class Impl> 9367639Sgblack@eecs.umich.eduvoid 9377639Sgblack@eecs.umich.eduInstructionQueue<Impl>::addReadyMemInst(DynInstPtr &ready_inst) 9387639Sgblack@eecs.umich.edu{ 9397639Sgblack@eecs.umich.edu OpClass op_class = ready_inst->opClass(); 9407639Sgblack@eecs.umich.edu 9417639Sgblack@eecs.umich.edu readyInsts[op_class].push(ready_inst); 9427639Sgblack@eecs.umich.edu 9437639Sgblack@eecs.umich.edu // Will need to reorder the list if either a queue is not on the list, 9447639Sgblack@eecs.umich.edu // or it has an older instruction than last time. 9457639Sgblack@eecs.umich.edu if (!queueOnList[op_class]) { 9467639Sgblack@eecs.umich.edu addToOrderList(op_class); 9477639Sgblack@eecs.umich.edu } else if (readyInsts[op_class].top()->seqNum < 9487639Sgblack@eecs.umich.edu (*readyIt[op_class]).oldestInst) { 9497639Sgblack@eecs.umich.edu listOrder.erase(readyIt[op_class]); 9507639Sgblack@eecs.umich.edu addToOrderList(op_class); 9517639Sgblack@eecs.umich.edu } 9527639Sgblack@eecs.umich.edu 9537639Sgblack@eecs.umich.edu DPRINTF(IQ, "Instruction is ready to issue, putting it onto " 9547639Sgblack@eecs.umich.edu "the ready list, PC %#x opclass:%i [sn:%lli].\n", 9557639Sgblack@eecs.umich.edu ready_inst->readPC(), op_class, ready_inst->seqNum); 9567639Sgblack@eecs.umich.edu} 9577639Sgblack@eecs.umich.edu 9587639Sgblack@eecs.umich.edutemplate <class Impl> 9597639Sgblack@eecs.umich.eduvoid 9607639Sgblack@eecs.umich.eduInstructionQueue<Impl>::rescheduleMemInst(DynInstPtr &resched_inst) 9617639Sgblack@eecs.umich.edu{ 9627639Sgblack@eecs.umich.edu memDepUnit[resched_inst->threadNumber].reschedule(resched_inst); 9637639Sgblack@eecs.umich.edu} 9647639Sgblack@eecs.umich.edu 9657639Sgblack@eecs.umich.edutemplate <class Impl> 9667639Sgblack@eecs.umich.eduvoid 9677639Sgblack@eecs.umich.eduInstructionQueue<Impl>::replayMemInst(DynInstPtr &replay_inst) 9687639Sgblack@eecs.umich.edu{ 9697639Sgblack@eecs.umich.edu memDepUnit[replay_inst->threadNumber].replay(replay_inst); 9707639Sgblack@eecs.umich.edu} 9717639Sgblack@eecs.umich.edu 9727639Sgblack@eecs.umich.edutemplate <class Impl> 9737639Sgblack@eecs.umich.eduvoid 9747639Sgblack@eecs.umich.eduInstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst) 9757639Sgblack@eecs.umich.edu{ 9767639Sgblack@eecs.umich.edu int tid = completed_inst->threadNumber; 9777639Sgblack@eecs.umich.edu 9787639Sgblack@eecs.umich.edu DPRINTF(IQ, "Completing mem instruction PC:%#x [sn:%lli]\n", 9797639Sgblack@eecs.umich.edu completed_inst->readPC(), completed_inst->seqNum); 9807639Sgblack@eecs.umich.edu 9817639Sgblack@eecs.umich.edu ++freeEntries; 9827639Sgblack@eecs.umich.edu 9837639Sgblack@eecs.umich.edu completed_inst->memOpDone = true; 9847639Sgblack@eecs.umich.edu 9857639Sgblack@eecs.umich.edu memDepUnit[tid].completed(completed_inst); 9867639Sgblack@eecs.umich.edu 9877639Sgblack@eecs.umich.edu count[tid]--; 9887639Sgblack@eecs.umich.edu} 9897639Sgblack@eecs.umich.edu 9907639Sgblack@eecs.umich.edutemplate <class Impl> 9917639Sgblack@eecs.umich.eduvoid 9927639Sgblack@eecs.umich.eduInstructionQueue<Impl>::violation(DynInstPtr &store, 9937639Sgblack@eecs.umich.edu DynInstPtr &faulting_load) 9947639Sgblack@eecs.umich.edu{ 9957639Sgblack@eecs.umich.edu memDepUnit[store->threadNumber].violation(store, faulting_load); 9967639Sgblack@eecs.umich.edu} 9977639Sgblack@eecs.umich.edu 9987639Sgblack@eecs.umich.edutemplate <class Impl> 9997639Sgblack@eecs.umich.eduvoid 10007639Sgblack@eecs.umich.eduInstructionQueue<Impl>::squash(unsigned tid) 10017639Sgblack@eecs.umich.edu{ 10027639Sgblack@eecs.umich.edu DPRINTF(IQ, "[tid:%i]: Starting to squash instructions in " 10037639Sgblack@eecs.umich.edu "the IQ.\n", tid); 10047639Sgblack@eecs.umich.edu 10057639Sgblack@eecs.umich.edu // Read instruction sequence number of last instruction out of the 10067639Sgblack@eecs.umich.edu // time buffer. 10077639Sgblack@eecs.umich.edu squashedSeqNum[tid] = fromCommit->commitInfo[tid].doneSeqNum; 10087639Sgblack@eecs.umich.edu 10097639Sgblack@eecs.umich.edu // Call doSquash if there are insts in the IQ 10107639Sgblack@eecs.umich.edu if (count[tid] > 0) { 10117639Sgblack@eecs.umich.edu doSquash(tid); 10127639Sgblack@eecs.umich.edu } 10137639Sgblack@eecs.umich.edu 10147639Sgblack@eecs.umich.edu // Also tell the memory dependence unit to squash. 10157639Sgblack@eecs.umich.edu memDepUnit[tid].squash(squashedSeqNum[tid], tid); 10167639Sgblack@eecs.umich.edu} 10177639Sgblack@eecs.umich.edu 10187639Sgblack@eecs.umich.edutemplate <class Impl> 10197639Sgblack@eecs.umich.eduvoid 10207639Sgblack@eecs.umich.eduInstructionQueue<Impl>::doSquash(unsigned tid) 10217639Sgblack@eecs.umich.edu{ 10227639Sgblack@eecs.umich.edu // Start at the tail. 10237639Sgblack@eecs.umich.edu ListIt squash_it = instList[tid].end(); 10247639Sgblack@eecs.umich.edu --squash_it; 10257639Sgblack@eecs.umich.edu 10267639Sgblack@eecs.umich.edu DPRINTF(IQ, "[tid:%i]: Squashing until sequence number %i!\n", 10277639Sgblack@eecs.umich.edu tid, squashedSeqNum[tid]); 10287639Sgblack@eecs.umich.edu 10297639Sgblack@eecs.umich.edu // Squash any instructions younger than the squashed sequence number 10307639Sgblack@eecs.umich.edu // given. 10317639Sgblack@eecs.umich.edu while (squash_it != instList[tid].end() && 10327639Sgblack@eecs.umich.edu (*squash_it)->seqNum > squashedSeqNum[tid]) { 10337639Sgblack@eecs.umich.edu 10347639Sgblack@eecs.umich.edu DynInstPtr squashed_inst = (*squash_it); 10357639Sgblack@eecs.umich.edu 10367639Sgblack@eecs.umich.edu // Only handle the instruction if it actually is in the IQ and 10377639Sgblack@eecs.umich.edu // hasn't already been squashed in the IQ. 10387639Sgblack@eecs.umich.edu if (squashed_inst->threadNumber != tid || 10397639Sgblack@eecs.umich.edu squashed_inst->isSquashedInIQ()) { 10407639Sgblack@eecs.umich.edu --squash_it; 10417639Sgblack@eecs.umich.edu continue; 10427639Sgblack@eecs.umich.edu } 10437639Sgblack@eecs.umich.edu 10447639Sgblack@eecs.umich.edu if (!squashed_inst->isIssued() || 10457639Sgblack@eecs.umich.edu (squashed_inst->isMemRef() && 10467639Sgblack@eecs.umich.edu !squashed_inst->memOpDone)) { 10477639Sgblack@eecs.umich.edu 10487639Sgblack@eecs.umich.edu // Remove the instruction from the dependency list. 10497639Sgblack@eecs.umich.edu if (!squashed_inst->isNonSpeculative() && 10507639Sgblack@eecs.umich.edu !squashed_inst->isStoreConditional() && 10517639Sgblack@eecs.umich.edu !squashed_inst->isMemBarrier() && 10527639Sgblack@eecs.umich.edu !squashed_inst->isWriteBarrier()) { 10537639Sgblack@eecs.umich.edu 10547639Sgblack@eecs.umich.edu for (int src_reg_idx = 0; 10557639Sgblack@eecs.umich.edu src_reg_idx < squashed_inst->numSrcRegs(); 10567639Sgblack@eecs.umich.edu src_reg_idx++) 10577639Sgblack@eecs.umich.edu { 10587639Sgblack@eecs.umich.edu PhysRegIndex src_reg = 10597639Sgblack@eecs.umich.edu squashed_inst->renamedSrcRegIdx(src_reg_idx); 10607639Sgblack@eecs.umich.edu 10617639Sgblack@eecs.umich.edu // Only remove it from the dependency graph if it 10627639Sgblack@eecs.umich.edu // was placed there in the first place. 10637639Sgblack@eecs.umich.edu 10647639Sgblack@eecs.umich.edu // Instead of doing a linked list traversal, we 10657639Sgblack@eecs.umich.edu // can just remove these squashed instructions 10667639Sgblack@eecs.umich.edu // either at issue time, or when the register is 10677639Sgblack@eecs.umich.edu // overwritten. The only downside to this is it 10687639Sgblack@eecs.umich.edu // leaves more room for error. 10697639Sgblack@eecs.umich.edu 10707639Sgblack@eecs.umich.edu if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) && 10717639Sgblack@eecs.umich.edu src_reg < numPhysRegs) { 10727639Sgblack@eecs.umich.edu dependGraph.remove(src_reg, squashed_inst); 10737639Sgblack@eecs.umich.edu } 10747639Sgblack@eecs.umich.edu 10757639Sgblack@eecs.umich.edu 10767639Sgblack@eecs.umich.edu ++iqSquashedOperandsExamined; 10777639Sgblack@eecs.umich.edu } 10787639Sgblack@eecs.umich.edu } else { 10797639Sgblack@eecs.umich.edu NonSpecMapIt ns_inst_it = 10807639Sgblack@eecs.umich.edu nonSpecInsts.find(squashed_inst->seqNum); 10817639Sgblack@eecs.umich.edu assert(ns_inst_it != nonSpecInsts.end()); 10827639Sgblack@eecs.umich.edu 10837639Sgblack@eecs.umich.edu (*ns_inst_it).second = NULL; 10847639Sgblack@eecs.umich.edu 10857639Sgblack@eecs.umich.edu nonSpecInsts.erase(ns_inst_it); 10867639Sgblack@eecs.umich.edu 10877639Sgblack@eecs.umich.edu ++iqSquashedNonSpecRemoved; 10887639Sgblack@eecs.umich.edu } 10897639Sgblack@eecs.umich.edu 10907639Sgblack@eecs.umich.edu // Might want to also clear out the head of the dependency graph. 10917639Sgblack@eecs.umich.edu 10927639Sgblack@eecs.umich.edu // Mark it as squashed within the IQ. 10937639Sgblack@eecs.umich.edu squashed_inst->setSquashedInIQ(); 10947639Sgblack@eecs.umich.edu 10957639Sgblack@eecs.umich.edu // @todo: Remove this hack where several statuses are set so the 10967639Sgblack@eecs.umich.edu // inst will flow through the rest of the pipeline. 10977639Sgblack@eecs.umich.edu squashed_inst->setIssued(); 10987639Sgblack@eecs.umich.edu squashed_inst->setCanCommit(); 10997639Sgblack@eecs.umich.edu squashed_inst->removeInIQ(); 11007639Sgblack@eecs.umich.edu 11017639Sgblack@eecs.umich.edu //Update Thread IQ Count 11027639Sgblack@eecs.umich.edu count[squashed_inst->threadNumber]--; 11037639Sgblack@eecs.umich.edu 11047639Sgblack@eecs.umich.edu ++freeEntries; 11057639Sgblack@eecs.umich.edu 11067639Sgblack@eecs.umich.edu DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %#x " 11077639Sgblack@eecs.umich.edu "squashed.\n", 11087639Sgblack@eecs.umich.edu tid, squashed_inst->seqNum, squashed_inst->readPC()); 11097639Sgblack@eecs.umich.edu } 11107639Sgblack@eecs.umich.edu 11117639Sgblack@eecs.umich.edu instList[tid].erase(squash_it--); 11127639Sgblack@eecs.umich.edu ++iqSquashedInstsExamined; 11137639Sgblack@eecs.umich.edu } 11147639Sgblack@eecs.umich.edu} 11157639Sgblack@eecs.umich.edu 11167639Sgblack@eecs.umich.edutemplate <class Impl> 11177639Sgblack@eecs.umich.edubool 11187639Sgblack@eecs.umich.eduInstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst) 11197639Sgblack@eecs.umich.edu{ 11207639Sgblack@eecs.umich.edu // Loop through the instruction's source registers, adding 11217639Sgblack@eecs.umich.edu // them to the dependency list if they are not ready. 11227639Sgblack@eecs.umich.edu int8_t total_src_regs = new_inst->numSrcRegs(); 11237639Sgblack@eecs.umich.edu bool return_val = false; 11247639Sgblack@eecs.umich.edu 11257639Sgblack@eecs.umich.edu for (int src_reg_idx = 0; 11267639Sgblack@eecs.umich.edu src_reg_idx < total_src_regs; 11277639Sgblack@eecs.umich.edu src_reg_idx++) 11287639Sgblack@eecs.umich.edu { 11297639Sgblack@eecs.umich.edu // Only add it to the dependency graph if it's not ready. 11307639Sgblack@eecs.umich.edu if (!new_inst->isReadySrcRegIdx(src_reg_idx)) { 11317639Sgblack@eecs.umich.edu PhysRegIndex src_reg = new_inst->renamedSrcRegIdx(src_reg_idx); 11327639Sgblack@eecs.umich.edu 11337639Sgblack@eecs.umich.edu // Check the IQ's scoreboard to make sure the register 11347639Sgblack@eecs.umich.edu // hasn't become ready while the instruction was in flight 11357639Sgblack@eecs.umich.edu // between stages. Only if it really isn't ready should 11367639Sgblack@eecs.umich.edu // it be added to the dependency graph. 11377639Sgblack@eecs.umich.edu if (src_reg >= numPhysRegs) { 11387639Sgblack@eecs.umich.edu continue; 11397639Sgblack@eecs.umich.edu } else if (regScoreboard[src_reg] == false) { 11407639Sgblack@eecs.umich.edu DPRINTF(IQ, "Instruction PC %#x has src reg %i that " 11417639Sgblack@eecs.umich.edu "is being added to the dependency chain.\n", 11427639Sgblack@eecs.umich.edu new_inst->readPC(), src_reg); 11437639Sgblack@eecs.umich.edu 11447639Sgblack@eecs.umich.edu dependGraph.insert(src_reg, new_inst); 11457639Sgblack@eecs.umich.edu 11467639Sgblack@eecs.umich.edu // Change the return value to indicate that something 11477639Sgblack@eecs.umich.edu // was added to the dependency graph. 11487639Sgblack@eecs.umich.edu return_val = true; 11497639Sgblack@eecs.umich.edu } else { 11507639Sgblack@eecs.umich.edu DPRINTF(IQ, "Instruction PC %#x has src reg %i that " 11517639Sgblack@eecs.umich.edu "became ready before it reached the IQ.\n", 11527639Sgblack@eecs.umich.edu new_inst->readPC(), src_reg); 11537639Sgblack@eecs.umich.edu // Mark a register ready within the instruction. 11547639Sgblack@eecs.umich.edu new_inst->markSrcRegReady(src_reg_idx); 11557639Sgblack@eecs.umich.edu } 11567639Sgblack@eecs.umich.edu } 11577639Sgblack@eecs.umich.edu } 11587639Sgblack@eecs.umich.edu 11597639Sgblack@eecs.umich.edu return return_val; 11607639Sgblack@eecs.umich.edu} 11617639Sgblack@eecs.umich.edu 11627639Sgblack@eecs.umich.edutemplate <class Impl> 11637639Sgblack@eecs.umich.eduvoid 11647639Sgblack@eecs.umich.eduInstructionQueue<Impl>::addToProducers(DynInstPtr &new_inst) 11657639Sgblack@eecs.umich.edu{ 11667639Sgblack@eecs.umich.edu // Nothing really needs to be marked when an instruction becomes 11677639Sgblack@eecs.umich.edu // the producer of a register's value, but for convenience a ptr 11687639Sgblack@eecs.umich.edu // to the producing instruction will be placed in the head node of 11697639Sgblack@eecs.umich.edu // the dependency links. 11707639Sgblack@eecs.umich.edu int8_t total_dest_regs = new_inst->numDestRegs(); 11717639Sgblack@eecs.umich.edu 11727639Sgblack@eecs.umich.edu for (int dest_reg_idx = 0; 11737639Sgblack@eecs.umich.edu dest_reg_idx < total_dest_regs; 11747639Sgblack@eecs.umich.edu dest_reg_idx++) 11757639Sgblack@eecs.umich.edu { 11767639Sgblack@eecs.umich.edu PhysRegIndex dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx); 11777639Sgblack@eecs.umich.edu 11787639Sgblack@eecs.umich.edu // Instructions that use the misc regs will have a reg number 11797639Sgblack@eecs.umich.edu // higher than the normal physical registers. In this case these 11807639Sgblack@eecs.umich.edu // registers are not renamed, and there is no need to track 11817639Sgblack@eecs.umich.edu // dependencies as these instructions must be executed at commit. 11827639Sgblack@eecs.umich.edu if (dest_reg >= numPhysRegs) { 11837639Sgblack@eecs.umich.edu continue; 11847639Sgblack@eecs.umich.edu } 11857639Sgblack@eecs.umich.edu 11867639Sgblack@eecs.umich.edu if (!dependGraph.empty(dest_reg)) { 11877639Sgblack@eecs.umich.edu dependGraph.dump(); 11887639Sgblack@eecs.umich.edu panic("Dependency graph %i not empty!", dest_reg); 11897639Sgblack@eecs.umich.edu } 11907639Sgblack@eecs.umich.edu 11917639Sgblack@eecs.umich.edu dependGraph.setInst(dest_reg, new_inst); 11927639Sgblack@eecs.umich.edu 11937639Sgblack@eecs.umich.edu // Mark the scoreboard to say it's not yet ready. 11947639Sgblack@eecs.umich.edu regScoreboard[dest_reg] = false; 11957639Sgblack@eecs.umich.edu } 11967639Sgblack@eecs.umich.edu} 11977639Sgblack@eecs.umich.edu 11987639Sgblack@eecs.umich.edutemplate <class Impl> 11997639Sgblack@eecs.umich.eduvoid 12007639Sgblack@eecs.umich.eduInstructionQueue<Impl>::addIfReady(DynInstPtr &inst) 12017639Sgblack@eecs.umich.edu{ 12027639Sgblack@eecs.umich.edu // If the instruction now has all of its source registers 12037639Sgblack@eecs.umich.edu // available, then add it to the list of ready instructions. 12047639Sgblack@eecs.umich.edu if (inst->readyToIssue()) { 12057639Sgblack@eecs.umich.edu 12067639Sgblack@eecs.umich.edu //Add the instruction to the proper ready list. 12077639Sgblack@eecs.umich.edu if (inst->isMemRef()) { 12087639Sgblack@eecs.umich.edu 12097639Sgblack@eecs.umich.edu DPRINTF(IQ, "Checking if memory instruction can issue.\n"); 12107639Sgblack@eecs.umich.edu 12117639Sgblack@eecs.umich.edu // Message to the mem dependence unit that this instruction has 12127639Sgblack@eecs.umich.edu // its registers ready. 12137639Sgblack@eecs.umich.edu memDepUnit[inst->threadNumber].regsReady(inst); 12147639Sgblack@eecs.umich.edu 12157639Sgblack@eecs.umich.edu return; 12167639Sgblack@eecs.umich.edu } 12177639Sgblack@eecs.umich.edu 12187639Sgblack@eecs.umich.edu OpClass op_class = inst->opClass(); 12197639Sgblack@eecs.umich.edu 12207639Sgblack@eecs.umich.edu DPRINTF(IQ, "Instruction is ready to issue, putting it onto " 12217639Sgblack@eecs.umich.edu "the ready list, PC %#x opclass:%i [sn:%lli].\n", 12227639Sgblack@eecs.umich.edu inst->readPC(), op_class, inst->seqNum); 12237639Sgblack@eecs.umich.edu 12247639Sgblack@eecs.umich.edu readyInsts[op_class].push(inst); 12257639Sgblack@eecs.umich.edu 12267639Sgblack@eecs.umich.edu // Will need to reorder the list if either a queue is not on the list, 12277639Sgblack@eecs.umich.edu // or it has an older instruction than last time. 12287639Sgblack@eecs.umich.edu if (!queueOnList[op_class]) { 12297639Sgblack@eecs.umich.edu addToOrderList(op_class); 12307639Sgblack@eecs.umich.edu } else if (readyInsts[op_class].top()->seqNum < 12317639Sgblack@eecs.umich.edu (*readyIt[op_class]).oldestInst) { 12327639Sgblack@eecs.umich.edu listOrder.erase(readyIt[op_class]); 12337639Sgblack@eecs.umich.edu addToOrderList(op_class); 12347639Sgblack@eecs.umich.edu } 12357639Sgblack@eecs.umich.edu } 12367639Sgblack@eecs.umich.edu} 12377639Sgblack@eecs.umich.edu 12387639Sgblack@eecs.umich.edutemplate <class Impl> 12397639Sgblack@eecs.umich.eduint 12407639Sgblack@eecs.umich.eduInstructionQueue<Impl>::countInsts() 12417639Sgblack@eecs.umich.edu{ 12427639Sgblack@eecs.umich.edu //ksewell:This works but definitely could use a cleaner write 12437639Sgblack@eecs.umich.edu //with a more intuitive way of counting. Right now it's 12447639Sgblack@eecs.umich.edu //just brute force .... 12457639Sgblack@eecs.umich.edu 12467639Sgblack@eecs.umich.edu#if 0 12477639Sgblack@eecs.umich.edu int total_insts = 0; 12487639Sgblack@eecs.umich.edu 12497639Sgblack@eecs.umich.edu for (int i = 0; i < numThreads; ++i) { 12507639Sgblack@eecs.umich.edu ListIt count_it = instList[i].begin(); 12517639Sgblack@eecs.umich.edu 12527639Sgblack@eecs.umich.edu while (count_it != instList[i].end()) { 12537639Sgblack@eecs.umich.edu if (!(*count_it)->isSquashed() && !(*count_it)->isSquashedInIQ()) { 12547639Sgblack@eecs.umich.edu if (!(*count_it)->isIssued()) { 12557639Sgblack@eecs.umich.edu ++total_insts; 12567639Sgblack@eecs.umich.edu } else if ((*count_it)->isMemRef() && 12577639Sgblack@eecs.umich.edu !(*count_it)->memOpDone) { 12587639Sgblack@eecs.umich.edu // Loads that have not been marked as executed still count 12597639Sgblack@eecs.umich.edu // towards the total instructions. 12607639Sgblack@eecs.umich.edu ++total_insts; 12617639Sgblack@eecs.umich.edu } 12627639Sgblack@eecs.umich.edu } 12637639Sgblack@eecs.umich.edu 12647639Sgblack@eecs.umich.edu ++count_it; 12657639Sgblack@eecs.umich.edu } 12667639Sgblack@eecs.umich.edu } 12677639Sgblack@eecs.umich.edu 12687639Sgblack@eecs.umich.edu return total_insts; 12697639Sgblack@eecs.umich.edu#else 12707639Sgblack@eecs.umich.edu return numEntries - freeEntries; 12717639Sgblack@eecs.umich.edu#endif 12727639Sgblack@eecs.umich.edu} 12737639Sgblack@eecs.umich.edu 12747639Sgblack@eecs.umich.edutemplate <class Impl> 12757639Sgblack@eecs.umich.eduvoid 12767639Sgblack@eecs.umich.eduInstructionQueue<Impl>::dumpLists() 12777639Sgblack@eecs.umich.edu{ 12787639Sgblack@eecs.umich.edu for (int i = 0; i < Num_OpClasses; ++i) { 12797639Sgblack@eecs.umich.edu cprintf("Ready list %i size: %i\n", i, readyInsts[i].size()); 12807639Sgblack@eecs.umich.edu 12817639Sgblack@eecs.umich.edu cprintf("\n"); 12827639Sgblack@eecs.umich.edu } 12837639Sgblack@eecs.umich.edu 12847639Sgblack@eecs.umich.edu cprintf("Non speculative list size: %i\n", nonSpecInsts.size()); 12857639Sgblack@eecs.umich.edu 12867639Sgblack@eecs.umich.edu NonSpecMapIt non_spec_it = nonSpecInsts.begin(); 12877639Sgblack@eecs.umich.edu NonSpecMapIt non_spec_end_it = nonSpecInsts.end(); 12887639Sgblack@eecs.umich.edu 12897639Sgblack@eecs.umich.edu cprintf("Non speculative list: "); 12907639Sgblack@eecs.umich.edu 12917639Sgblack@eecs.umich.edu while (non_spec_it != non_spec_end_it) { 12927639Sgblack@eecs.umich.edu cprintf("%#x [sn:%lli]", (*non_spec_it).second->readPC(), 12937639Sgblack@eecs.umich.edu (*non_spec_it).second->seqNum); 12947639Sgblack@eecs.umich.edu ++non_spec_it; 12957639Sgblack@eecs.umich.edu } 12967639Sgblack@eecs.umich.edu 12977639Sgblack@eecs.umich.edu cprintf("\n"); 12987639Sgblack@eecs.umich.edu 12997639Sgblack@eecs.umich.edu ListOrderIt list_order_it = listOrder.begin(); 13007639Sgblack@eecs.umich.edu ListOrderIt list_order_end_it = listOrder.end(); 13017639Sgblack@eecs.umich.edu int i = 1; 13027639Sgblack@eecs.umich.edu 13037639Sgblack@eecs.umich.edu cprintf("List order: "); 13047639Sgblack@eecs.umich.edu 13057639Sgblack@eecs.umich.edu while (list_order_it != list_order_end_it) { 13067639Sgblack@eecs.umich.edu cprintf("%i OpClass:%i [sn:%lli] ", i, (*list_order_it).queueType, 13077639Sgblack@eecs.umich.edu (*list_order_it).oldestInst); 13087639Sgblack@eecs.umich.edu 13097639Sgblack@eecs.umich.edu ++list_order_it; 13107639Sgblack@eecs.umich.edu ++i; 13117639Sgblack@eecs.umich.edu } 13127639Sgblack@eecs.umich.edu 13137639Sgblack@eecs.umich.edu cprintf("\n"); 13147639Sgblack@eecs.umich.edu} 13157639Sgblack@eecs.umich.edu 13167639Sgblack@eecs.umich.edu 13177639Sgblack@eecs.umich.edutemplate <class Impl> 13187639Sgblack@eecs.umich.eduvoid 13197639Sgblack@eecs.umich.eduInstructionQueue<Impl>::dumpInsts() 13207639Sgblack@eecs.umich.edu{ 13217639Sgblack@eecs.umich.edu for (int i = 0; i < numThreads; ++i) { 13227639Sgblack@eecs.umich.edu int num = 0; 13237639Sgblack@eecs.umich.edu int valid_num = 0; 13247639Sgblack@eecs.umich.edu ListIt inst_list_it = instList[i].begin(); 13257639Sgblack@eecs.umich.edu 13267639Sgblack@eecs.umich.edu while (inst_list_it != instList[i].end()) 13277639Sgblack@eecs.umich.edu { 13287639Sgblack@eecs.umich.edu cprintf("Instruction:%i\n", 13297639Sgblack@eecs.umich.edu num); 13307639Sgblack@eecs.umich.edu if (!(*inst_list_it)->isSquashed()) { 13317639Sgblack@eecs.umich.edu if (!(*inst_list_it)->isIssued()) { 13327639Sgblack@eecs.umich.edu ++valid_num; 13337639Sgblack@eecs.umich.edu cprintf("Count:%i\n", valid_num); 13347639Sgblack@eecs.umich.edu } else if ((*inst_list_it)->isMemRef() && 13357639Sgblack@eecs.umich.edu !(*inst_list_it)->memOpDone) { 13367639Sgblack@eecs.umich.edu // Loads that have not been marked as executed 13377639Sgblack@eecs.umich.edu // still count towards the total instructions. 13387639Sgblack@eecs.umich.edu ++valid_num; 13397639Sgblack@eecs.umich.edu cprintf("Count:%i\n", valid_num); 13407639Sgblack@eecs.umich.edu } 13417639Sgblack@eecs.umich.edu } 13427639Sgblack@eecs.umich.edu 13437639Sgblack@eecs.umich.edu cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n" 13447639Sgblack@eecs.umich.edu "Issued:%i\nSquashed:%i\n", 13457639Sgblack@eecs.umich.edu (*inst_list_it)->readPC(), 13467639Sgblack@eecs.umich.edu (*inst_list_it)->seqNum, 13477639Sgblack@eecs.umich.edu (*inst_list_it)->threadNumber, 13487639Sgblack@eecs.umich.edu (*inst_list_it)->isIssued(), 13497639Sgblack@eecs.umich.edu (*inst_list_it)->isSquashed()); 13507639Sgblack@eecs.umich.edu 13517639Sgblack@eecs.umich.edu if ((*inst_list_it)->isMemRef()) { 13527639Sgblack@eecs.umich.edu cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone); 13537639Sgblack@eecs.umich.edu } 13547639Sgblack@eecs.umich.edu 13557639Sgblack@eecs.umich.edu cprintf("\n"); 13567639Sgblack@eecs.umich.edu 13577639Sgblack@eecs.umich.edu inst_list_it++; 13587639Sgblack@eecs.umich.edu ++num; 13597639Sgblack@eecs.umich.edu } 13607639Sgblack@eecs.umich.edu } 13617639Sgblack@eecs.umich.edu 13627639Sgblack@eecs.umich.edu cprintf("Insts to Execute list:\n"); 13637639Sgblack@eecs.umich.edu 13647639Sgblack@eecs.umich.edu int num = 0; 13657639Sgblack@eecs.umich.edu int valid_num = 0; 13667639Sgblack@eecs.umich.edu ListIt inst_list_it = instsToExecute.begin(); 13677639Sgblack@eecs.umich.edu 13687639Sgblack@eecs.umich.edu while (inst_list_it != instsToExecute.end()) 13697639Sgblack@eecs.umich.edu { 13707639Sgblack@eecs.umich.edu cprintf("Instruction:%i\n", 13717639Sgblack@eecs.umich.edu num); 13727639Sgblack@eecs.umich.edu if (!(*inst_list_it)->isSquashed()) { 13737639Sgblack@eecs.umich.edu if (!(*inst_list_it)->isIssued()) { 13747639Sgblack@eecs.umich.edu ++valid_num; 13757639Sgblack@eecs.umich.edu cprintf("Count:%i\n", valid_num); 13767639Sgblack@eecs.umich.edu } else if ((*inst_list_it)->isMemRef() && 13777639Sgblack@eecs.umich.edu !(*inst_list_it)->memOpDone) { 13787639Sgblack@eecs.umich.edu // Loads that have not been marked as executed 13797639Sgblack@eecs.umich.edu // still count towards the total instructions. 13807639Sgblack@eecs.umich.edu ++valid_num; 13817639Sgblack@eecs.umich.edu cprintf("Count:%i\n", valid_num); 13827639Sgblack@eecs.umich.edu } 13837639Sgblack@eecs.umich.edu } 13847639Sgblack@eecs.umich.edu 13857639Sgblack@eecs.umich.edu cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n" 13867639Sgblack@eecs.umich.edu "Issued:%i\nSquashed:%i\n", 13877639Sgblack@eecs.umich.edu (*inst_list_it)->readPC(), 13887639Sgblack@eecs.umich.edu (*inst_list_it)->seqNum, 13897639Sgblack@eecs.umich.edu (*inst_list_it)->threadNumber, 13907639Sgblack@eecs.umich.edu (*inst_list_it)->isIssued(), 13917639Sgblack@eecs.umich.edu (*inst_list_it)->isSquashed()); 13927639Sgblack@eecs.umich.edu 13937639Sgblack@eecs.umich.edu if ((*inst_list_it)->isMemRef()) { 13947639Sgblack@eecs.umich.edu cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone); 13957639Sgblack@eecs.umich.edu } 13967639Sgblack@eecs.umich.edu 13977639Sgblack@eecs.umich.edu cprintf("\n"); 13987639Sgblack@eecs.umich.edu 13997639Sgblack@eecs.umich.edu inst_list_it++; 14007639Sgblack@eecs.umich.edu ++num; 14017639Sgblack@eecs.umich.edu } 14027639Sgblack@eecs.umich.edu} 14037639Sgblack@eecs.umich.edu