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