inst_queue_impl.hh revision 4762:c94e103c83ad
111988Sandreas.sandberg@arm.com/*
28839Sandreas.hansson@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
38839Sandreas.hansson@arm.com * All rights reserved.
48839Sandreas.hansson@arm.com *
58839Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68839Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78839Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88839Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98839Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108839Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118839Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128839Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
133101Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from
148579Ssteve.reinhardt@amd.com * this software without specific prior written permission.
153101Sstever@eecs.umich.edu *
163101Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173101Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183101Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193101Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203101Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213101Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223101Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233101Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243101Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253101Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263101Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273101Sstever@eecs.umich.edu *
283101Sstever@eecs.umich.edu * Authors: Kevin Lim
293101Sstever@eecs.umich.edu *          Korey Sewell
303101Sstever@eecs.umich.edu */
313101Sstever@eecs.umich.edu
323101Sstever@eecs.umich.edu#include <limits>
333101Sstever@eecs.umich.edu#include <vector>
343101Sstever@eecs.umich.edu
353101Sstever@eecs.umich.edu#include "cpu/o3/fu_pool.hh"
363101Sstever@eecs.umich.edu#include "cpu/o3/inst_queue.hh"
373101Sstever@eecs.umich.edu#include "enums/OpClass.hh"
383101Sstever@eecs.umich.edu#include "sim/core.hh"
393101Sstever@eecs.umich.edu
403101Sstever@eecs.umich.edutemplate <class Impl>
413101Sstever@eecs.umich.eduInstructionQueue<Impl>::FUCompletion::FUCompletion(DynInstPtr &_inst,
427778Sgblack@eecs.umich.edu                                                   int fu_idx,
438839Sandreas.hansson@arm.com                                                   InstructionQueue<Impl> *iq_ptr)
443101Sstever@eecs.umich.edu    : Event(&mainEventQueue, Stat_Event_Pri),
453101Sstever@eecs.umich.edu      inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false)
463101Sstever@eecs.umich.edu{
473101Sstever@eecs.umich.edu    this->setFlags(Event::AutoDelete);
483101Sstever@eecs.umich.edu}
493101Sstever@eecs.umich.edu
503101Sstever@eecs.umich.edutemplate <class Impl>
513101Sstever@eecs.umich.eduvoid
523101Sstever@eecs.umich.eduInstructionQueue<Impl>::FUCompletion::process()
533101Sstever@eecs.umich.edu{
543101Sstever@eecs.umich.edu    iqPtr->processFUCompletion(inst, freeFU ? fuIdx : -1);
553101Sstever@eecs.umich.edu    inst = NULL;
563101Sstever@eecs.umich.edu}
573101Sstever@eecs.umich.edu
583101Sstever@eecs.umich.edu
593101Sstever@eecs.umich.edutemplate <class Impl>
603101Sstever@eecs.umich.educonst char *
613101Sstever@eecs.umich.eduInstructionQueue<Impl>::FUCompletion::description()
623885Sbinkertn@umich.edu{
633885Sbinkertn@umich.edu    return "Functional unit completion event";
644762Snate@binkert.org}
653885Sbinkertn@umich.edu
663885Sbinkertn@umich.edutemplate <class Impl>
677528Ssteve.reinhardt@amd.comInstructionQueue<Impl>::InstructionQueue(O3CPU *cpu_ptr, IEW *iew_ptr,
683885Sbinkertn@umich.edu                                         Params *params)
694380Sbinkertn@umich.edu    : cpu(cpu_ptr),
704167Sbinkertn@umich.edu      iewStage(iew_ptr),
713102Sstever@eecs.umich.edu      fuPool(params->fuPool),
723101Sstever@eecs.umich.edu      numEntries(params->numIQEntries),
734762Snate@binkert.org      totalWidth(params->issueWidth),
744762Snate@binkert.org      numPhysIntRegs(params->numPhysIntRegs),
754762Snate@binkert.org      numPhysFloatRegs(params->numPhysFloatRegs),
764762Snate@binkert.org      commitToIEWDelay(params->commitToIEWDelay)
774762Snate@binkert.org{
784762Snate@binkert.org    assert(fuPool);
794762Snate@binkert.org
804762Snate@binkert.org    switchedOut = false;
814762Snate@binkert.org
825033Smilesck@eecs.umich.edu    numThreads = params->numberOfThreads;
835033Smilesck@eecs.umich.edu
845033Smilesck@eecs.umich.edu    // Set the number of physical registers as the number of int + float
855033Smilesck@eecs.umich.edu    numPhysRegs = numPhysIntRegs + numPhysFloatRegs;
865033Smilesck@eecs.umich.edu
875033Smilesck@eecs.umich.edu    //Create an entry for each physical register within the
885033Smilesck@eecs.umich.edu    //dependency graph.
895033Smilesck@eecs.umich.edu    dependGraph.resize(numPhysRegs);
905033Smilesck@eecs.umich.edu
915033Smilesck@eecs.umich.edu    // Resize the register scoreboard.
923101Sstever@eecs.umich.edu    regScoreboard.resize(numPhysRegs);
933101Sstever@eecs.umich.edu
943101Sstever@eecs.umich.edu    //Initialize Mem Dependence Units
955033Smilesck@eecs.umich.edu    for (int i = 0; i < numThreads; i++) {
9610267SGeoffrey.Blake@arm.com        memDepUnit[i].init(params,i);
978596Ssteve.reinhardt@amd.com        memDepUnit[i].setIQ(this);
988596Ssteve.reinhardt@amd.com    }
998596Ssteve.reinhardt@amd.com
1008596Ssteve.reinhardt@amd.com    resetState();
1017673Snate@binkert.org
1027673Snate@binkert.org    std::string policy = params->smtIQPolicy;
1037673Snate@binkert.org
1047673Snate@binkert.org    //Convert string to lowercase
10511988Sandreas.sandberg@arm.com    std::transform(policy.begin(), policy.end(), policy.begin(),
10611988Sandreas.sandberg@arm.com                   (int(*)(int)) tolower);
10711988Sandreas.sandberg@arm.com
10811988Sandreas.sandberg@arm.com    //Figure out resource sharing policy
1093101Sstever@eecs.umich.edu    if (policy == "dynamic") {
1103101Sstever@eecs.umich.edu        iqPolicy = Dynamic;
1113101Sstever@eecs.umich.edu
1123101Sstever@eecs.umich.edu        //Set Max Entries to Total ROB Capacity
1133101Sstever@eecs.umich.edu        for (int i = 0; i < numThreads; i++) {
11410380SAndrew.Bardsley@arm.com            maxEntries[i] = numEntries;
11510380SAndrew.Bardsley@arm.com        }
11610380SAndrew.Bardsley@arm.com
11710380SAndrew.Bardsley@arm.com    } else if (policy == "partitioned") {
11810380SAndrew.Bardsley@arm.com        iqPolicy = Partitioned;
11910380SAndrew.Bardsley@arm.com
12010458Sandreas.hansson@arm.com        //@todo:make work if part_amt doesnt divide evenly.
12110458Sandreas.hansson@arm.com        int part_amt = numEntries / numThreads;
12210458Sandreas.hansson@arm.com
12310458Sandreas.hansson@arm.com        //Divide ROB up evenly
12410458Sandreas.hansson@arm.com        for (int i = 0; i < numThreads; i++) {
12510458Sandreas.hansson@arm.com            maxEntries[i] = part_amt;
12610458Sandreas.hansson@arm.com        }
12710458Sandreas.hansson@arm.com
12810458Sandreas.hansson@arm.com        DPRINTF(IQ, "IQ sharing policy set to Partitioned:"
12910458Sandreas.hansson@arm.com                "%i entries per thread.\n",part_amt);
13010458Sandreas.hansson@arm.com    } else if (policy == "threshold") {
13110458Sandreas.hansson@arm.com        iqPolicy = Threshold;
1323101Sstever@eecs.umich.edu
1333101Sstever@eecs.umich.edu        double threshold =  (double)params->smtIQThreshold / 100;
1343101Sstever@eecs.umich.edu
1353101Sstever@eecs.umich.edu        int thresholdIQ = (int)((double)threshold * numEntries);
1363101Sstever@eecs.umich.edu
13710267SGeoffrey.Blake@arm.com        //Divide up by threshold amount
13810267SGeoffrey.Blake@arm.com        for (int i = 0; i < numThreads; i++) {
13910267SGeoffrey.Blake@arm.com            maxEntries[i] = thresholdIQ;
14010267SGeoffrey.Blake@arm.com        }
1413101Sstever@eecs.umich.edu
1423101Sstever@eecs.umich.edu        DPRINTF(IQ, "IQ sharing policy set to Threshold:"
1433101Sstever@eecs.umich.edu                "%i entries per thread.\n",thresholdIQ);
1443101Sstever@eecs.umich.edu   } else {
1453101Sstever@eecs.umich.edu       assert(0 && "Invalid IQ Sharing Policy.Options Are:{Dynamic,"
1463101Sstever@eecs.umich.edu              "Partitioned, Threshold}");
1473101Sstever@eecs.umich.edu   }
1483101Sstever@eecs.umich.edu}
1493101Sstever@eecs.umich.edu
1503101Sstever@eecs.umich.edutemplate <class Impl>
1513101Sstever@eecs.umich.eduInstructionQueue<Impl>::~InstructionQueue()
1523101Sstever@eecs.umich.edu{
1533101Sstever@eecs.umich.edu    dependGraph.reset();
1543101Sstever@eecs.umich.edu#ifdef DEBUG
1553101Sstever@eecs.umich.edu    cprintf("Nodes traversed: %i, removed: %i\n",
1563101Sstever@eecs.umich.edu            dependGraph.nodesTraversed, dependGraph.nodesRemoved);
1573101Sstever@eecs.umich.edu#endif
1583101Sstever@eecs.umich.edu}
1593101Sstever@eecs.umich.edu
1603101Sstever@eecs.umich.edutemplate <class Impl>
1613101Sstever@eecs.umich.edustd::string
1623101Sstever@eecs.umich.eduInstructionQueue<Impl>::name() const
1633101Sstever@eecs.umich.edu{
1643101Sstever@eecs.umich.edu    return cpu->name() + ".iq";
1653101Sstever@eecs.umich.edu}
1663101Sstever@eecs.umich.edu
1673101Sstever@eecs.umich.edutemplate <class Impl>
1683101Sstever@eecs.umich.eduvoid
1693101Sstever@eecs.umich.eduInstructionQueue<Impl>::regStats()
1703101Sstever@eecs.umich.edu{
1713101Sstever@eecs.umich.edu    using namespace Stats;
1723101Sstever@eecs.umich.edu    iqInstsAdded
1733101Sstever@eecs.umich.edu        .name(name() + ".iqInstsAdded")
1743101Sstever@eecs.umich.edu        .desc("Number of instructions added to the IQ (excludes non-spec)")
1753101Sstever@eecs.umich.edu        .prereq(iqInstsAdded);
1765033Smilesck@eecs.umich.edu
1776656Snate@binkert.org    iqNonSpecInstsAdded
1785033Smilesck@eecs.umich.edu        .name(name() + ".iqNonSpecInstsAdded")
1795033Smilesck@eecs.umich.edu        .desc("Number of non-speculative instructions added to the IQ")
1805033Smilesck@eecs.umich.edu        .prereq(iqNonSpecInstsAdded);
1813101Sstever@eecs.umich.edu
1823101Sstever@eecs.umich.edu    iqInstsIssued
1833101Sstever@eecs.umich.edu        .name(name() + ".iqInstsIssued")
18410267SGeoffrey.Blake@arm.com        .desc("Number of instructions issued")
18510267SGeoffrey.Blake@arm.com        .prereq(iqInstsIssued);
18610267SGeoffrey.Blake@arm.com
18710267SGeoffrey.Blake@arm.com    iqIntInstsIssued
18810267SGeoffrey.Blake@arm.com        .name(name() + ".iqIntInstsIssued")
18910267SGeoffrey.Blake@arm.com        .desc("Number of integer instructions issued")
19010267SGeoffrey.Blake@arm.com        .prereq(iqIntInstsIssued);
19110267SGeoffrey.Blake@arm.com
19210267SGeoffrey.Blake@arm.com    iqFloatInstsIssued
19310267SGeoffrey.Blake@arm.com        .name(name() + ".iqFloatInstsIssued")
19410267SGeoffrey.Blake@arm.com        .desc("Number of float instructions issued")
19510267SGeoffrey.Blake@arm.com        .prereq(iqFloatInstsIssued);
19610267SGeoffrey.Blake@arm.com
1973101Sstever@eecs.umich.edu    iqBranchInstsIssued
1983101Sstever@eecs.umich.edu        .name(name() + ".iqBranchInstsIssued")
1993101Sstever@eecs.umich.edu        .desc("Number of branch instructions issued")
2003101Sstever@eecs.umich.edu        .prereq(iqBranchInstsIssued);
2013101Sstever@eecs.umich.edu
2023101Sstever@eecs.umich.edu    iqMemInstsIssued
2033101Sstever@eecs.umich.edu        .name(name() + ".iqMemInstsIssued")
2043101Sstever@eecs.umich.edu        .desc("Number of memory instructions issued")
2053101Sstever@eecs.umich.edu        .prereq(iqMemInstsIssued);
2063101Sstever@eecs.umich.edu
2073102Sstever@eecs.umich.edu    iqMiscInstsIssued
2083101Sstever@eecs.umich.edu        .name(name() + ".iqMiscInstsIssued")
2093101Sstever@eecs.umich.edu        .desc("Number of miscellaneous instructions issued")
2103101Sstever@eecs.umich.edu        .prereq(iqMiscInstsIssued);
21110267SGeoffrey.Blake@arm.com
21210267SGeoffrey.Blake@arm.com    iqSquashedInstsIssued
21310267SGeoffrey.Blake@arm.com        .name(name() + ".iqSquashedInstsIssued")
21410267SGeoffrey.Blake@arm.com        .desc("Number of squashed instructions issued")
21510267SGeoffrey.Blake@arm.com        .prereq(iqSquashedInstsIssued);
21610267SGeoffrey.Blake@arm.com
21710267SGeoffrey.Blake@arm.com    iqSquashedInstsExamined
2187673Snate@binkert.org        .name(name() + ".iqSquashedInstsExamined")
2198607Sgblack@eecs.umich.edu        .desc("Number of squashed instructions iterated over during squash;"
2207673Snate@binkert.org              " mainly for profiling")
2213101Sstever@eecs.umich.edu        .prereq(iqSquashedInstsExamined);
22211988Sandreas.sandberg@arm.com
22311988Sandreas.sandberg@arm.com    iqSquashedOperandsExamined
22411988Sandreas.sandberg@arm.com        .name(name() + ".iqSquashedOperandsExamined")
2257673Snate@binkert.org        .desc("Number of squashed operands that are examined and possibly "
2267673Snate@binkert.org              "removed from graph")
2273101Sstever@eecs.umich.edu        .prereq(iqSquashedOperandsExamined);
2283101Sstever@eecs.umich.edu
2293101Sstever@eecs.umich.edu    iqSquashedNonSpecRemoved
2303101Sstever@eecs.umich.edu        .name(name() + ".iqSquashedNonSpecRemoved")
2313101Sstever@eecs.umich.edu        .desc("Number of squashed non-spec instructions that were removed")
2323101Sstever@eecs.umich.edu        .prereq(iqSquashedNonSpecRemoved);
2335033Smilesck@eecs.umich.edu/*
2345475Snate@binkert.org    queueResDist
2355475Snate@binkert.org        .init(Num_OpClasses, 0, 99, 2)
2365475Snate@binkert.org        .name(name() + ".IQ:residence:")
2375475Snate@binkert.org        .desc("cycles from dispatch to issue")
23810380SAndrew.Bardsley@arm.com        .flags(total | pdf | cdf )
23910380SAndrew.Bardsley@arm.com        ;
24010380SAndrew.Bardsley@arm.com    for (int i = 0; i < Num_OpClasses; ++i) {
2413101Sstever@eecs.umich.edu        queueResDist.subname(i, opClassStrings[i]);
2423101Sstever@eecs.umich.edu    }
2433101Sstever@eecs.umich.edu*/
2444762Snate@binkert.org    numIssuedDist
2454762Snate@binkert.org        .init(0,totalWidth,1)
2464762Snate@binkert.org        .name(name() + ".ISSUE:issued_per_cycle")
2473101Sstever@eecs.umich.edu        .desc("Number of insts issued each cycle")
24812050Snikos.nikoleris@arm.com        .flags(pdf)
24912050Snikos.nikoleris@arm.com        ;
25012050Snikos.nikoleris@arm.com/*
2518459SAli.Saidi@ARM.com    dist_unissued
2528459SAli.Saidi@ARM.com        .init(Num_OpClasses+2)
25312050Snikos.nikoleris@arm.com        .name(name() + ".ISSUE:unissued_cause")
2543101Sstever@eecs.umich.edu        .desc("Reason ready instruction not issued")
2557528Ssteve.reinhardt@amd.com        .flags(pdf | dist)
2567528Ssteve.reinhardt@amd.com        ;
2577528Ssteve.reinhardt@amd.com    for (int i=0; i < (Num_OpClasses + 2); ++i) {
2587528Ssteve.reinhardt@amd.com        dist_unissued.subname(i, unissued_names[i]);
2597528Ssteve.reinhardt@amd.com    }
2607528Ssteve.reinhardt@amd.com*/
2613101Sstever@eecs.umich.edu    statIssuedInstType
2627528Ssteve.reinhardt@amd.com        .init(numThreads,Enums::Num_OpClass)
2637528Ssteve.reinhardt@amd.com        .name(name() + ".ISSUE:FU_type")
2647528Ssteve.reinhardt@amd.com        .desc("Type of FU issued")
2657528Ssteve.reinhardt@amd.com        .flags(total | pdf | dist)
2667528Ssteve.reinhardt@amd.com        ;
2677528Ssteve.reinhardt@amd.com    statIssuedInstType.ysubnames(Enums::OpClassStrings);
2687528Ssteve.reinhardt@amd.com
2697528Ssteve.reinhardt@amd.com    //
2707528Ssteve.reinhardt@amd.com    //  How long did instructions for a particular FU type wait prior to issue
2717528Ssteve.reinhardt@amd.com    //
2728321Ssteve.reinhardt@amd.com/*
2738321Ssteve.reinhardt@amd.com    issueDelayDist
2747528Ssteve.reinhardt@amd.com        .init(Num_OpClasses,0,99,2)
2757528Ssteve.reinhardt@amd.com        .name(name() + ".ISSUE:")
2767528Ssteve.reinhardt@amd.com        .desc("cycles from operands ready to issue")
2777528Ssteve.reinhardt@amd.com        .flags(pdf | cdf)
2787528Ssteve.reinhardt@amd.com        ;
2797528Ssteve.reinhardt@amd.com
2807528Ssteve.reinhardt@amd.com    for (int i=0; i<Num_OpClasses; ++i) {
2817528Ssteve.reinhardt@amd.com        std::stringstream subname;
2827528Ssteve.reinhardt@amd.com        subname << opClassStrings[i] << "_delay";
2837528Ssteve.reinhardt@amd.com        issueDelayDist.subname(i, subname.str());
2847528Ssteve.reinhardt@amd.com    }
2857528Ssteve.reinhardt@amd.com*/
2867528Ssteve.reinhardt@amd.com    issueRate
2873101Sstever@eecs.umich.edu        .name(name() + ".ISSUE:rate")
2888664SAli.Saidi@ARM.com        .desc("Inst issue rate")
2898664SAli.Saidi@ARM.com        .flags(total)
2908664SAli.Saidi@ARM.com        ;
2918664SAli.Saidi@ARM.com    issueRate = iqInstsIssued / cpu->numCycles;
2928664SAli.Saidi@ARM.com
2938664SAli.Saidi@ARM.com    statFuBusy
2949953Sgeoffrey.blake@arm.com        .init(Num_OpClasses)
2959953Sgeoffrey.blake@arm.com        .name(name() + ".ISSUE:fu_full")
2969953Sgeoffrey.blake@arm.com        .desc("attempts to use FU when none available")
2979953Sgeoffrey.blake@arm.com        .flags(pdf | dist)
2989953Sgeoffrey.blake@arm.com        ;
2999953Sgeoffrey.blake@arm.com    for (int i=0; i < Num_OpClasses; ++i) {
3009953Sgeoffrey.blake@arm.com        statFuBusy.subname(i, Enums::OpClassStrings[i]);
3019953Sgeoffrey.blake@arm.com    }
3029953Sgeoffrey.blake@arm.com
3039953Sgeoffrey.blake@arm.com    fuBusy
3049953Sgeoffrey.blake@arm.com        .init(numThreads)
3059953Sgeoffrey.blake@arm.com        .name(name() + ".ISSUE:fu_busy_cnt")
3069953Sgeoffrey.blake@arm.com        .desc("FU busy when requested")
30710267SGeoffrey.Blake@arm.com        .flags(total)
30810267SGeoffrey.Blake@arm.com        ;
30910267SGeoffrey.Blake@arm.com
31010267SGeoffrey.Blake@arm.com    fuBusyRate
31110267SGeoffrey.Blake@arm.com        .name(name() + ".ISSUE:fu_busy_rate")
31210267SGeoffrey.Blake@arm.com        .desc("FU busy rate (busy events/executed inst)")
31310267SGeoffrey.Blake@arm.com        .flags(total)
31410267SGeoffrey.Blake@arm.com        ;
31510267SGeoffrey.Blake@arm.com    fuBusyRate = fuBusy / iqInstsIssued;
31610267SGeoffrey.Blake@arm.com
31710267SGeoffrey.Blake@arm.com    for ( int i=0; i < numThreads; i++) {
31810267SGeoffrey.Blake@arm.com        // Tell mem dependence unit to reg stats as well.
31910267SGeoffrey.Blake@arm.com        memDepUnit[i].regStats();
32010267SGeoffrey.Blake@arm.com    }
32110267SGeoffrey.Blake@arm.com}
32210267SGeoffrey.Blake@arm.com
32310267SGeoffrey.Blake@arm.comtemplate <class Impl>
32410267SGeoffrey.Blake@arm.comvoid
32510267SGeoffrey.Blake@arm.comInstructionQueue<Impl>::resetState()
32610267SGeoffrey.Blake@arm.com{
3273101Sstever@eecs.umich.edu    //Initialize thread IQ counts
3283101Sstever@eecs.umich.edu    for (int i = 0; i <numThreads; i++) {
3293101Sstever@eecs.umich.edu        count[i] = 0;
3303101Sstever@eecs.umich.edu        instList[i].clear();
3313101Sstever@eecs.umich.edu    }
3323101Sstever@eecs.umich.edu
3333101Sstever@eecs.umich.edu    // Initialize the number of free IQ entries.
33410364SGeoffrey.Blake@arm.com    freeEntries = numEntries;
33510364SGeoffrey.Blake@arm.com
33610364SGeoffrey.Blake@arm.com    // Note that in actuality, the registers corresponding to the logical
33710364SGeoffrey.Blake@arm.com    // registers start off as ready.  However this doesn't matter for the
3383101Sstever@eecs.umich.edu    // IQ as the instruction should have been correctly told if those
3394762Snate@binkert.org    // registers are ready in rename.  Thus it can all be initialized as
3404762Snate@binkert.org    // unready.
3414762Snate@binkert.org    for (int i = 0; i < numPhysRegs; ++i) {
3424762Snate@binkert.org        regScoreboard[i] = false;
3437528Ssteve.reinhardt@amd.com    }
3444762Snate@binkert.org
3454762Snate@binkert.org    for (int i = 0; i < numThreads; ++i) {
3464762Snate@binkert.org        squashedSeqNum[i] = 0;
34710267SGeoffrey.Blake@arm.com    }
34810267SGeoffrey.Blake@arm.com
34910267SGeoffrey.Blake@arm.com    for (int i = 0; i < Num_OpClasses; ++i) {
35010267SGeoffrey.Blake@arm.com        while (!readyInsts[i].empty())
35110267SGeoffrey.Blake@arm.com            readyInsts[i].pop();
35210267SGeoffrey.Blake@arm.com        queueOnList[i] = false;
35310267SGeoffrey.Blake@arm.com        readyIt[i] = listOrder.end();
35410267SGeoffrey.Blake@arm.com    }
35510267SGeoffrey.Blake@arm.com    nonSpecInsts.clear();
35610267SGeoffrey.Blake@arm.com    listOrder.clear();
35710267SGeoffrey.Blake@arm.com}
35810267SGeoffrey.Blake@arm.com
35910267SGeoffrey.Blake@arm.comtemplate <class Impl>
36010267SGeoffrey.Blake@arm.comvoid
36110267SGeoffrey.Blake@arm.comInstructionQueue<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
36210267SGeoffrey.Blake@arm.com{
36310267SGeoffrey.Blake@arm.com    activeThreads = at_ptr;
36410267SGeoffrey.Blake@arm.com}
36510267SGeoffrey.Blake@arm.com
36610267SGeoffrey.Blake@arm.comtemplate <class Impl>
36710267SGeoffrey.Blake@arm.comvoid
36810267SGeoffrey.Blake@arm.comInstructionQueue<Impl>::setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2e_ptr)
36910267SGeoffrey.Blake@arm.com{
37010267SGeoffrey.Blake@arm.com      issueToExecuteQueue = i2e_ptr;
37110267SGeoffrey.Blake@arm.com}
37210267SGeoffrey.Blake@arm.com
37310364SGeoffrey.Blake@arm.comtemplate <class Impl>
37410364SGeoffrey.Blake@arm.comvoid
37510267SGeoffrey.Blake@arm.comInstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
37610267SGeoffrey.Blake@arm.com{
37710267SGeoffrey.Blake@arm.com    timeBuffer = tb_ptr;
37810267SGeoffrey.Blake@arm.com
37910267SGeoffrey.Blake@arm.com    fromCommit = timeBuffer->getWire(-commitToIEWDelay);
38010267SGeoffrey.Blake@arm.com}
3817673Snate@binkert.org
3827673Snate@binkert.orgtemplate <class Impl>
3837673Snate@binkert.orgvoid
3843101Sstever@eecs.umich.eduInstructionQueue<Impl>::switchOut()
38511988Sandreas.sandberg@arm.com{
38611988Sandreas.sandberg@arm.com/*
38711988Sandreas.sandberg@arm.com    if (!instList[0].empty() || (numEntries != freeEntries) ||
38811988Sandreas.sandberg@arm.com        !readyInsts[0].empty() || !nonSpecInsts.empty() || !listOrder.empty()) {
3897673Snate@binkert.org        dumpInsts();
3907673Snate@binkert.org//        assert(0);
3913101Sstever@eecs.umich.edu    }
3923101Sstever@eecs.umich.edu*/
3933101Sstever@eecs.umich.edu    resetState();
3943101Sstever@eecs.umich.edu    dependGraph.reset();
3953101Sstever@eecs.umich.edu    instsToExecute.clear();
3963101Sstever@eecs.umich.edu    switchedOut = true;
3973101Sstever@eecs.umich.edu    for (int i = 0; i < numThreads; ++i) {
3983101Sstever@eecs.umich.edu        memDepUnit[i].switchOut();
3993101Sstever@eecs.umich.edu    }
4003101Sstever@eecs.umich.edu}
4013101Sstever@eecs.umich.edu
4023101Sstever@eecs.umich.edutemplate <class Impl>
4033101Sstever@eecs.umich.eduvoid
4043101Sstever@eecs.umich.eduInstructionQueue<Impl>::takeOverFrom()
4053101Sstever@eecs.umich.edu{
4065033Smilesck@eecs.umich.edu    switchedOut = false;
4075033Smilesck@eecs.umich.edu}
4083101Sstever@eecs.umich.edu
4093101Sstever@eecs.umich.edutemplate <class Impl>
4103101Sstever@eecs.umich.eduint
4113101Sstever@eecs.umich.eduInstructionQueue<Impl>::entryAmount(int num_threads)
4123101Sstever@eecs.umich.edu{
4133101Sstever@eecs.umich.edu    if (iqPolicy == Partitioned) {
4143101Sstever@eecs.umich.edu        return numEntries / num_threads;
4153101Sstever@eecs.umich.edu    } else {
4163101Sstever@eecs.umich.edu        return 0;
4173101Sstever@eecs.umich.edu    }
4183101Sstever@eecs.umich.edu}
4193101Sstever@eecs.umich.edu
4203101Sstever@eecs.umich.edu
4213101Sstever@eecs.umich.edutemplate <class Impl>
4223101Sstever@eecs.umich.eduvoid
4233101Sstever@eecs.umich.eduInstructionQueue<Impl>::resetEntries()
4243101Sstever@eecs.umich.edu{
4253101Sstever@eecs.umich.edu    if (iqPolicy != Dynamic || numThreads > 1) {
4263101Sstever@eecs.umich.edu        int active_threads = activeThreads->size();
4273101Sstever@eecs.umich.edu
4283101Sstever@eecs.umich.edu        std::list<unsigned>::iterator threads = activeThreads->begin();
4293101Sstever@eecs.umich.edu        std::list<unsigned>::iterator end = activeThreads->end();
4303101Sstever@eecs.umich.edu
4313101Sstever@eecs.umich.edu        while (threads != end) {
4323101Sstever@eecs.umich.edu            unsigned tid = *threads++;
43310267SGeoffrey.Blake@arm.com
4347673Snate@binkert.org            if (iqPolicy == Partitioned) {
4357673Snate@binkert.org                maxEntries[tid] = numEntries / active_threads;
4367673Snate@binkert.org            } else if(iqPolicy == Threshold && active_threads == 1) {
4377673Snate@binkert.org                maxEntries[tid] = numEntries;
4387673Snate@binkert.org            }
43910267SGeoffrey.Blake@arm.com        }
44010267SGeoffrey.Blake@arm.com    }
44110267SGeoffrey.Blake@arm.com}
44210267SGeoffrey.Blake@arm.com
44310458Sandreas.hansson@arm.comtemplate <class Impl>
44410458Sandreas.hansson@arm.comunsigned
44510458Sandreas.hansson@arm.comInstructionQueue<Impl>::numFreeEntries()
44610458Sandreas.hansson@arm.com{
44710458Sandreas.hansson@arm.com    return freeEntries;
4484762Snate@binkert.org}
4494762Snate@binkert.org
4503101Sstever@eecs.umich.edutemplate <class Impl>
4513101Sstever@eecs.umich.eduunsigned
4523101Sstever@eecs.umich.eduInstructionQueue<Impl>::numFreeEntries(unsigned tid)
4533101Sstever@eecs.umich.edu{
4543101Sstever@eecs.umich.edu    return maxEntries[tid] - count[tid];
4553101Sstever@eecs.umich.edu}
4563101Sstever@eecs.umich.edu
4573101Sstever@eecs.umich.edu// Might want to do something more complex if it knows how many instructions
4583101Sstever@eecs.umich.edu// will be issued this cycle.
4593101Sstever@eecs.umich.edutemplate <class Impl>
4603101Sstever@eecs.umich.edubool
4613714Sstever@eecs.umich.eduInstructionQueue<Impl>::isFull()
4623714Sstever@eecs.umich.edu{
4633714Sstever@eecs.umich.edu    if (freeEntries == 0) {
4643714Sstever@eecs.umich.edu        return(true);
4653714Sstever@eecs.umich.edu    } else {
4663714Sstever@eecs.umich.edu        return(false);
4673101Sstever@eecs.umich.edu    }
4683101Sstever@eecs.umich.edu}
4693101Sstever@eecs.umich.edu
4703101Sstever@eecs.umich.edutemplate <class Impl>
4713101Sstever@eecs.umich.edubool
4723101Sstever@eecs.umich.eduInstructionQueue<Impl>::isFull(unsigned tid)
4733101Sstever@eecs.umich.edu{
4743101Sstever@eecs.umich.edu    if (numFreeEntries(tid) == 0) {
4753101Sstever@eecs.umich.edu        return(true);
4763101Sstever@eecs.umich.edu    } else {
4773101Sstever@eecs.umich.edu        return(false);
4783101Sstever@eecs.umich.edu    }
4793101Sstever@eecs.umich.edu}
4803101Sstever@eecs.umich.edu
4813101Sstever@eecs.umich.edutemplate <class Impl>
4823101Sstever@eecs.umich.edubool
4833101Sstever@eecs.umich.eduInstructionQueue<Impl>::hasReadyInsts()
4843101Sstever@eecs.umich.edu{
4853101Sstever@eecs.umich.edu    if (!listOrder.empty()) {
4863101Sstever@eecs.umich.edu        return true;
4873101Sstever@eecs.umich.edu    }
4883101Sstever@eecs.umich.edu
4893101Sstever@eecs.umich.edu    for (int i = 0; i < Num_OpClasses; ++i) {
4903101Sstever@eecs.umich.edu        if (!readyInsts[i].empty()) {
49110380SAndrew.Bardsley@arm.com            return true;
49210380SAndrew.Bardsley@arm.com        }
49310380SAndrew.Bardsley@arm.com    }
49410458Sandreas.hansson@arm.com
49510458Sandreas.hansson@arm.com    return false;
49610458Sandreas.hansson@arm.com}
49710458Sandreas.hansson@arm.com
49810458Sandreas.hansson@arm.comtemplate <class Impl>
49910458Sandreas.hansson@arm.comvoid
50010458Sandreas.hansson@arm.comInstructionQueue<Impl>::insert(DynInstPtr &new_inst)
50110458Sandreas.hansson@arm.com{
50210458Sandreas.hansson@arm.com    // Make sure the instruction is valid
50310458Sandreas.hansson@arm.com    assert(new_inst);
50410458Sandreas.hansson@arm.com
50510458Sandreas.hansson@arm.com    DPRINTF(IQ, "Adding instruction [sn:%lli] PC %#x to the IQ.\n",
50610458Sandreas.hansson@arm.com            new_inst->seqNum, new_inst->readPC());
5073101Sstever@eecs.umich.edu
5085033Smilesck@eecs.umich.edu    assert(freeEntries != 0);
5093101Sstever@eecs.umich.edu
5103101Sstever@eecs.umich.edu    instList[new_inst->threadNumber].push_back(new_inst);
5113101Sstever@eecs.umich.edu
5123101Sstever@eecs.umich.edu    --freeEntries;
5133101Sstever@eecs.umich.edu
5143101Sstever@eecs.umich.edu    new_inst->setInIQ();
5153101Sstever@eecs.umich.edu
5163101Sstever@eecs.umich.edu    // Look through its source registers (physical regs), and mark any
5173101Sstever@eecs.umich.edu    // dependencies.
5183101Sstever@eecs.umich.edu    addToDependents(new_inst);
5193101Sstever@eecs.umich.edu
5203101Sstever@eecs.umich.edu    // Have this instruction set itself as the producer of its destination
5215822Ssaidi@eecs.umich.edu    // register(s).
5225822Ssaidi@eecs.umich.edu    addToProducers(new_inst);
5233101Sstever@eecs.umich.edu
5243101Sstever@eecs.umich.edu    if (new_inst->isMemRef()) {
5253101Sstever@eecs.umich.edu        memDepUnit[new_inst->threadNumber].insert(new_inst);
5263101Sstever@eecs.umich.edu    } else {
5273101Sstever@eecs.umich.edu        addIfReady(new_inst);
5283101Sstever@eecs.umich.edu    }
5293101Sstever@eecs.umich.edu
5303101Sstever@eecs.umich.edu    ++iqInstsAdded;
5313101Sstever@eecs.umich.edu
5323101Sstever@eecs.umich.edu    count[new_inst->threadNumber]++;
5333101Sstever@eecs.umich.edu
5343101Sstever@eecs.umich.edu    assert(freeEntries == (numEntries - countInsts()));
5353101Sstever@eecs.umich.edu}
53610267SGeoffrey.Blake@arm.com
5373101Sstever@eecs.umich.edutemplate <class Impl>
5383101Sstever@eecs.umich.eduvoid
5393101Sstever@eecs.umich.eduInstructionQueue<Impl>::insertNonSpec(DynInstPtr &new_inst)
5403101Sstever@eecs.umich.edu{
5413101Sstever@eecs.umich.edu    // @todo: Clean up this code; can do it by setting inst as unable
5423101Sstever@eecs.umich.edu    // to issue, then calling normal insert on the inst.
5433101Sstever@eecs.umich.edu
5443101Sstever@eecs.umich.edu    assert(new_inst);
5453102Sstever@eecs.umich.edu
5463714Sstever@eecs.umich.edu    nonSpecInsts[new_inst->seqNum] = new_inst;
5473101Sstever@eecs.umich.edu
5483714Sstever@eecs.umich.edu    DPRINTF(IQ, "Adding non-speculative instruction [sn:%lli] PC %#x "
5493714Sstever@eecs.umich.edu            "to the IQ.\n",
5503714Sstever@eecs.umich.edu            new_inst->seqNum, new_inst->readPC());
5513101Sstever@eecs.umich.edu
5523101Sstever@eecs.umich.edu    assert(freeEntries != 0);
55310267SGeoffrey.Blake@arm.com
55410267SGeoffrey.Blake@arm.com    instList[new_inst->threadNumber].push_back(new_inst);
55510267SGeoffrey.Blake@arm.com
55610267SGeoffrey.Blake@arm.com    --freeEntries;
5577673Snate@binkert.org
5587673Snate@binkert.org    new_inst->setInIQ();
5597673Snate@binkert.org
5607673Snate@binkert.org    // Have this instruction set itself as the producer of its destination
5617673Snate@binkert.org    // register(s).
5624762Snate@binkert.org    addToProducers(new_inst);
5634762Snate@binkert.org
5644762Snate@binkert.org    // If it's a memory instruction, add it to the memory dependency
5653101Sstever@eecs.umich.edu    // unit.
5663101Sstever@eecs.umich.edu    if (new_inst->isMemRef()) {
5673101Sstever@eecs.umich.edu        memDepUnit[new_inst->threadNumber].insertNonSpec(new_inst);
5683101Sstever@eecs.umich.edu    }
5693101Sstever@eecs.umich.edu
5703101Sstever@eecs.umich.edu    ++iqNonSpecInstsAdded;
5713101Sstever@eecs.umich.edu
5723101Sstever@eecs.umich.edu    count[new_inst->threadNumber]++;
5733101Sstever@eecs.umich.edu
5743101Sstever@eecs.umich.edu    assert(freeEntries == (numEntries - countInsts()));
5753101Sstever@eecs.umich.edu}
5763101Sstever@eecs.umich.edu
5773101Sstever@eecs.umich.edutemplate <class Impl>
5783101Sstever@eecs.umich.eduvoid
5793101Sstever@eecs.umich.eduInstructionQueue<Impl>::insertBarrier(DynInstPtr &barr_inst)
5803101Sstever@eecs.umich.edu{
5813101Sstever@eecs.umich.edu    memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst);
5823101Sstever@eecs.umich.edu
5833101Sstever@eecs.umich.edu    insertNonSpec(barr_inst);
5849184Sandreas.hansson@arm.com}
5859184Sandreas.hansson@arm.com
5869184Sandreas.hansson@arm.comtemplate <class Impl>
5879184Sandreas.hansson@arm.comtypename Impl::DynInstPtr
5889184Sandreas.hansson@arm.comInstructionQueue<Impl>::getInstToExecute()
5899184Sandreas.hansson@arm.com{
59011802Sandreas.sandberg@arm.com    assert(!instsToExecute.empty());
5919184Sandreas.hansson@arm.com    DynInstPtr inst = instsToExecute.front();
5929184Sandreas.hansson@arm.com    instsToExecute.pop_front();
59310458Sandreas.hansson@arm.com    return inst;
59410458Sandreas.hansson@arm.com}
59510458Sandreas.hansson@arm.com
59610458Sandreas.hansson@arm.comtemplate <class Impl>
59710458Sandreas.hansson@arm.comvoid
59810458Sandreas.hansson@arm.comInstructionQueue<Impl>::addToOrderList(OpClass op_class)
59910458Sandreas.hansson@arm.com{
60010458Sandreas.hansson@arm.com    assert(!readyInsts[op_class].empty());
60110458Sandreas.hansson@arm.com
60210458Sandreas.hansson@arm.com    ListOrderEntry queue_entry;
60310458Sandreas.hansson@arm.com
60410458Sandreas.hansson@arm.com    queue_entry.queueType = op_class;
60510458Sandreas.hansson@arm.com
60610458Sandreas.hansson@arm.com    queue_entry.oldestInst = readyInsts[op_class].top()->seqNum;
6073101Sstever@eecs.umich.edu
6084446Sbinkertn@umich.edu    ListOrderIt list_it = listOrder.begin();
60910668SGeoffrey.Blake@arm.com    ListOrderIt list_end_it = listOrder.end();
6103101Sstever@eecs.umich.edu
6115468Snate@binkert.org    while (list_it != list_end_it) {
61210267SGeoffrey.Blake@arm.com        if ((*list_it).oldestInst > queue_entry.oldestInst) {
6135468Snate@binkert.org            break;
6145468Snate@binkert.org        }
6155468Snate@binkert.org
6165468Snate@binkert.org        list_it++;
6175468Snate@binkert.org    }
61810267SGeoffrey.Blake@arm.com
61910267SGeoffrey.Blake@arm.com    readyIt[op_class] = listOrder.insert(list_it, queue_entry);
62010267SGeoffrey.Blake@arm.com    queueOnList[op_class] = true;
62110267SGeoffrey.Blake@arm.com}
6224762Snate@binkert.org
6234762Snate@binkert.orgtemplate <class Impl>
6244762Snate@binkert.orgvoid
62510380SAndrew.Bardsley@arm.comInstructionQueue<Impl>::moveToYoungerInst(ListOrderIt list_order_it)
62610380SAndrew.Bardsley@arm.com{
62710380SAndrew.Bardsley@arm.com    // Get iterator of next item on the list
62810458Sandreas.hansson@arm.com    // Delete the original iterator
62910458Sandreas.hansson@arm.com    // Determine if the next item is either the end of the list or younger
63010458Sandreas.hansson@arm.com    // than the new instruction.  If so, then add in a new iterator right here.
63110458Sandreas.hansson@arm.com    // If not, then move along.
63210458Sandreas.hansson@arm.com    ListOrderEntry queue_entry;
63310458Sandreas.hansson@arm.com    OpClass op_class = (*list_order_it).queueType;
63410458Sandreas.hansson@arm.com    ListOrderIt next_it = list_order_it;
63510458Sandreas.hansson@arm.com
6363101Sstever@eecs.umich.edu    ++next_it;
6373101Sstever@eecs.umich.edu
63810267SGeoffrey.Blake@arm.com    queue_entry.queueType = op_class;
6393101Sstever@eecs.umich.edu    queue_entry.oldestInst = readyInsts[op_class].top()->seqNum;
6403101Sstever@eecs.umich.edu
6413101Sstever@eecs.umich.edu    while (next_it != listOrder.end() &&
6423101Sstever@eecs.umich.edu           (*next_it).oldestInst < queue_entry.oldestInst) {
6433101Sstever@eecs.umich.edu        ++next_it;
6443101Sstever@eecs.umich.edu    }
6453102Sstever@eecs.umich.edu
6463101Sstever@eecs.umich.edu    readyIt[op_class] = listOrder.insert(next_it, queue_entry);
6473101Sstever@eecs.umich.edu}
6483101Sstever@eecs.umich.edu
6494168Sbinkertn@umich.edutemplate <class Impl>
65010267SGeoffrey.Blake@arm.comvoid
6513101Sstever@eecs.umich.eduInstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx)
6523101Sstever@eecs.umich.edu{
6533101Sstever@eecs.umich.edu    DPRINTF(IQ, "Processing FU completion [sn:%lli]\n", inst->seqNum);
6543101Sstever@eecs.umich.edu    // The CPU could have been sleeping until this op completed (*extremely*
6553101Sstever@eecs.umich.edu    // long latency op).  Wake it if it was.  This may be overkill.
6563101Sstever@eecs.umich.edu    if (isSwitchedOut()) {
6573102Sstever@eecs.umich.edu        DPRINTF(IQ, "FU completion not processed, IQ is switched out [sn:%lli]\n",
6583101Sstever@eecs.umich.edu                inst->seqNum);
6593101Sstever@eecs.umich.edu        return;
6603101Sstever@eecs.umich.edu    }
6613101Sstever@eecs.umich.edu
6623101Sstever@eecs.umich.edu    iewStage->wakeCPU();
6633101Sstever@eecs.umich.edu
6643101Sstever@eecs.umich.edu    if (fu_idx > -1)
6653101Sstever@eecs.umich.edu        fuPool->freeUnitNextCycle(fu_idx);
6663101Sstever@eecs.umich.edu
6673101Sstever@eecs.umich.edu    // @todo: Ensure that these FU Completions happen at the beginning
6683101Sstever@eecs.umich.edu    // of a cycle, otherwise they could add too many instructions to
66910317Smitch.hayenga@arm.com    // the queue.
67010317Smitch.hayenga@arm.com    issueToExecuteQueue->access(0)->size++;
67110317Smitch.hayenga@arm.com    instsToExecute.push_back(inst);
67210317Smitch.hayenga@arm.com}
67310317Smitch.hayenga@arm.com
6743102Sstever@eecs.umich.edu// @todo: Figure out a better way to remove the squashed items from the
67510317Smitch.hayenga@arm.com// lists.  Checking the top item of each list to see if it's squashed
67610317Smitch.hayenga@arm.com// wastes time and forces jumps.
67710317Smitch.hayenga@arm.comtemplate <class Impl>
67810317Smitch.hayenga@arm.comvoid
67910317Smitch.hayenga@arm.comInstructionQueue<Impl>::scheduleReadyInsts()
6803101Sstever@eecs.umich.edu{
6813584Ssaidi@eecs.umich.edu    DPRINTF(IQ, "Attempting to schedule ready instructions from "
6823584Ssaidi@eecs.umich.edu            "the IQ.\n");
6833584Ssaidi@eecs.umich.edu
6843584Ssaidi@eecs.umich.edu    IssueStruct *i2e_info = issueToExecuteQueue->access(0);
6853584Ssaidi@eecs.umich.edu
68610267SGeoffrey.Blake@arm.com    // Have iterator to head of the list
68710267SGeoffrey.Blake@arm.com    // While I haven't exceeded bandwidth or reached the end of the list,
68810267SGeoffrey.Blake@arm.com    // Try to get a FU that can do what this op needs.
68910267SGeoffrey.Blake@arm.com    // If successful, change the oldestInst to the new top of the list, put
69010267SGeoffrey.Blake@arm.com    // the queue in the proper place in the list.
69110267SGeoffrey.Blake@arm.com    // Increment the iterator.
6923101Sstever@eecs.umich.edu    // This will avoid trying to schedule a certain op class if there are no
6939232Sandreas.hansson@arm.com    // FUs that handle it.
6949235Sandreas.hansson@arm.com    ListOrderIt order_it = listOrder.begin();
6953101Sstever@eecs.umich.edu    ListOrderIt order_end_it = listOrder.end();
6963101Sstever@eecs.umich.edu    int total_issued = 0;
69710676Sandreas.hansson@arm.com
6989411Sandreas.hansson@arm.com    while (total_issued < totalWidth &&
69910676Sandreas.hansson@arm.com           iewStage->canIssue() &&
7009411Sandreas.hansson@arm.com           order_it != order_end_it) {
7019411Sandreas.hansson@arm.com        OpClass op_class = (*order_it).queueType;
7029411Sandreas.hansson@arm.com
7033101Sstever@eecs.umich.edu        assert(!readyInsts[op_class].empty());
7049411Sandreas.hansson@arm.com
7059411Sandreas.hansson@arm.com        DynInstPtr issuing_inst = readyInsts[op_class].top();
7069411Sandreas.hansson@arm.com
7073101Sstever@eecs.umich.edu        assert(issuing_inst->seqNum == (*order_it).oldestInst);
7089232Sandreas.hansson@arm.com
7093101Sstever@eecs.umich.edu        if (issuing_inst->isSquashed()) {
7109232Sandreas.hansson@arm.com            readyInsts[op_class].pop();
7113101Sstever@eecs.umich.edu
7123101Sstever@eecs.umich.edu            if (!readyInsts[op_class].empty()) {
7133101Sstever@eecs.umich.edu                moveToYoungerInst(order_it);
7149411Sandreas.hansson@arm.com            } else {
7159411Sandreas.hansson@arm.com                readyIt[op_class] = listOrder.end();
7169411Sandreas.hansson@arm.com                queueOnList[op_class] = false;
71710676Sandreas.hansson@arm.com            }
71810676Sandreas.hansson@arm.com
7199411Sandreas.hansson@arm.com            listOrder.erase(order_it++);
7209411Sandreas.hansson@arm.com
7219411Sandreas.hansson@arm.com            ++iqSquashedInstsIssued;
7229411Sandreas.hansson@arm.com
7239411Sandreas.hansson@arm.com            continue;
7243101Sstever@eecs.umich.edu        }
7259232Sandreas.hansson@arm.com
7263101Sstever@eecs.umich.edu        int idx = -2;
7273101Sstever@eecs.umich.edu        int op_latency = 1;
7283101Sstever@eecs.umich.edu        int tid = issuing_inst->threadNumber;
7293101Sstever@eecs.umich.edu
7309232Sandreas.hansson@arm.com        if (op_class != No_OpClass) {
7313101Sstever@eecs.umich.edu            idx = fuPool->getUnit(op_class);
7325219Ssaidi@eecs.umich.edu
7339232Sandreas.hansson@arm.com            if (idx > -1) {
7349232Sandreas.hansson@arm.com                op_latency = fuPool->getOpLatency(op_class);
7353101Sstever@eecs.umich.edu            }
7369232Sandreas.hansson@arm.com        }
7379232Sandreas.hansson@arm.com
7383101Sstever@eecs.umich.edu        // If we have an instruction that doesn't require a FU, or a
7393101Sstever@eecs.umich.edu        // valid FU, then schedule for execution.
7409232Sandreas.hansson@arm.com        if (idx == -2 || idx != -1) {
7419232Sandreas.hansson@arm.com            if (op_latency == 1) {
7423101Sstever@eecs.umich.edu                i2e_info->size++;
7433101Sstever@eecs.umich.edu                instsToExecute.push_back(issuing_inst);
7443101Sstever@eecs.umich.edu
7453101Sstever@eecs.umich.edu                // Add the FU onto the list of FU's to be freed next
7469232Sandreas.hansson@arm.com                // cycle if we used one.
7473101Sstever@eecs.umich.edu                if (idx >= 0)
7483101Sstever@eecs.umich.edu                    fuPool->freeUnitNextCycle(idx);
74911620SMatthew.Poremba@amd.com            } else {
75011620SMatthew.Poremba@amd.com                int issue_latency = fuPool->getIssueLatency(op_class);
75111620SMatthew.Poremba@amd.com                // Generate completion event for the FU
7529232Sandreas.hansson@arm.com                FUCompletion *execution = new FUCompletion(issuing_inst,
7539232Sandreas.hansson@arm.com                                                           idx, this);
7549411Sandreas.hansson@arm.com
7559411Sandreas.hansson@arm.com                execution->schedule(curTick + cpu->cycles(issue_latency - 1));
7563101Sstever@eecs.umich.edu
7577673Snate@binkert.org                // @todo: Enforce that issue_latency == 1 or op_latency
7587673Snate@binkert.org                if (issue_latency > 1) {
7599232Sandreas.hansson@arm.com                    // If FU isn't pipelined, then it must be freed
7609235Sandreas.hansson@arm.com                    // upon the execution completing.
7617675Snate@binkert.org                    execution->setFreeFU();
7627675Snate@binkert.org                } else {
76311988Sandreas.sandberg@arm.com                    // Add the FU onto the list of FU's to be freed next cycle.
76411988Sandreas.sandberg@arm.com                    fuPool->freeUnitNextCycle(idx);
76511988Sandreas.sandberg@arm.com                }
76611988Sandreas.sandberg@arm.com            }
76711988Sandreas.sandberg@arm.com
76810458Sandreas.hansson@arm.com            DPRINTF(IQ, "Thread %i: Issuing instruction PC %#x "
76910458Sandreas.hansson@arm.com                    "[sn:%lli]\n",
77010458Sandreas.hansson@arm.com                    tid, issuing_inst->readPC(),
77110458Sandreas.hansson@arm.com                    issuing_inst->seqNum);
77210458Sandreas.hansson@arm.com
77311620SMatthew.Poremba@amd.com            readyInsts[op_class].pop();
77411620SMatthew.Poremba@amd.com
77510458Sandreas.hansson@arm.com            if (!readyInsts[op_class].empty()) {
77610458Sandreas.hansson@arm.com                moveToYoungerInst(order_it);
77710458Sandreas.hansson@arm.com            } else {
77810458Sandreas.hansson@arm.com                readyIt[op_class] = listOrder.end();
77910458Sandreas.hansson@arm.com                queueOnList[op_class] = false;
78011620SMatthew.Poremba@amd.com            }
78111620SMatthew.Poremba@amd.com
78211620SMatthew.Poremba@amd.com            issuing_inst->setIssued();
78311620SMatthew.Poremba@amd.com            ++total_issued;
78411620SMatthew.Poremba@amd.com
78511620SMatthew.Poremba@amd.com            if (!issuing_inst->isMemRef()) {
78611620SMatthew.Poremba@amd.com                // Memory instructions can not be freed from the IQ until they
78711620SMatthew.Poremba@amd.com                // complete.
78811620SMatthew.Poremba@amd.com                ++freeEntries;
78911620SMatthew.Poremba@amd.com                count[tid]--;
79010458Sandreas.hansson@arm.com                issuing_inst->clearInIQ();
79110458Sandreas.hansson@arm.com            } else {
79210458Sandreas.hansson@arm.com                memDepUnit[tid].issue(issuing_inst);
79311620SMatthew.Poremba@amd.com            }
79411620SMatthew.Poremba@amd.com
79510458Sandreas.hansson@arm.com            listOrder.erase(order_it++);
79610458Sandreas.hansson@arm.com            statIssuedInstType[tid][op_class]++;
7974762Snate@binkert.org            iewStage->incrWb(issuing_inst->seqNum);
79811991Sandreas.sandberg@arm.com        } else {
79911802Sandreas.sandberg@arm.com            statFuBusy[op_class]++;
8004762Snate@binkert.org            fuBusy[tid]++;
8019411Sandreas.hansson@arm.com            ++order_it;
80210676Sandreas.hansson@arm.com        }
80310676Sandreas.hansson@arm.com    }
8043101Sstever@eecs.umich.edu
8053101Sstever@eecs.umich.edu    numIssuedDist.sample(total_issued);
8063101Sstever@eecs.umich.edu    iqInstsIssued+= total_issued;
8073101Sstever@eecs.umich.edu
8083101Sstever@eecs.umich.edu    // If we issued any instructions, tell the CPU we had activity.
8093101Sstever@eecs.umich.edu    if (total_issued) {
81010267SGeoffrey.Blake@arm.com        cpu->activityThisCycle();
81110267SGeoffrey.Blake@arm.com    } else {
8123101Sstever@eecs.umich.edu        DPRINTF(IQ, "Not able to schedule any instructions.\n");
8133101Sstever@eecs.umich.edu    }
8143102Sstever@eecs.umich.edu}
8153101Sstever@eecs.umich.edu
8163101Sstever@eecs.umich.edutemplate <class Impl>
8173101Sstever@eecs.umich.eduvoid
81810267SGeoffrey.Blake@arm.comInstructionQueue<Impl>::scheduleNonSpec(const InstSeqNum &inst)
81910267SGeoffrey.Blake@arm.com{
82010267SGeoffrey.Blake@arm.com    DPRINTF(IQ, "Marking nonspeculative instruction [sn:%lli] as ready "
82110267SGeoffrey.Blake@arm.com            "to execute.\n", inst);
8224762Snate@binkert.org
8234762Snate@binkert.org    NonSpecMapIt inst_it = nonSpecInsts.find(inst);
8244762Snate@binkert.org
8253101Sstever@eecs.umich.edu    assert(inst_it != nonSpecInsts.end());
8263101Sstever@eecs.umich.edu
8273101Sstever@eecs.umich.edu    unsigned tid = (*inst_it).second->threadNumber;
8288934SBrad.Beckmann@amd.com
8298934SBrad.Beckmann@amd.com    (*inst_it).second->setAtCommit();
8308934SBrad.Beckmann@amd.com
8318934SBrad.Beckmann@amd.com    (*inst_it).second->setCanIssue();
8328934SBrad.Beckmann@amd.com
8333101Sstever@eecs.umich.edu    if (!(*inst_it).second->isMemRef()) {
8343101Sstever@eecs.umich.edu        addIfReady((*inst_it).second);
8353101Sstever@eecs.umich.edu    } else {
8363101Sstever@eecs.umich.edu        memDepUnit[tid].nonSpecInstReady((*inst_it).second);
8373101Sstever@eecs.umich.edu    }
83810380SAndrew.Bardsley@arm.com
83910380SAndrew.Bardsley@arm.com    (*inst_it).second = NULL;
84010380SAndrew.Bardsley@arm.com
84110458Sandreas.hansson@arm.com    nonSpecInsts.erase(inst_it);
84210458Sandreas.hansson@arm.com}
84310458Sandreas.hansson@arm.com
84410458Sandreas.hansson@arm.comtemplate <class Impl>
84510458Sandreas.hansson@arm.comvoid
84610458Sandreas.hansson@arm.comInstructionQueue<Impl>::commit(const InstSeqNum &inst, unsigned tid)
84710458Sandreas.hansson@arm.com{
84810458Sandreas.hansson@arm.com    DPRINTF(IQ, "[tid:%i]: Committing instructions older than [sn:%i]\n",
84910458Sandreas.hansson@arm.com            tid,inst);
85010458Sandreas.hansson@arm.com
8513101Sstever@eecs.umich.edu    ListIt iq_it = instList[tid].begin();
8523101Sstever@eecs.umich.edu
8533101Sstever@eecs.umich.edu    while (iq_it != instList[tid].end() &&
8543101Sstever@eecs.umich.edu           (*iq_it)->seqNum <= inst) {
8553101Sstever@eecs.umich.edu        ++iq_it;
8563101Sstever@eecs.umich.edu        instList[tid].pop_front();
8573101Sstever@eecs.umich.edu    }
8583101Sstever@eecs.umich.edu
8593101Sstever@eecs.umich.edu    assert(freeEntries == (numEntries - countInsts()));
8603101Sstever@eecs.umich.edu}
8613101Sstever@eecs.umich.edu
8623101Sstever@eecs.umich.edutemplate <class Impl>
8634380Sbinkertn@umich.eduint
8644380Sbinkertn@umich.eduInstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
8654380Sbinkertn@umich.edu{
8663101Sstever@eecs.umich.edu    int dependents = 0;
8674380Sbinkertn@umich.edu
8684380Sbinkertn@umich.edu    DPRINTF(IQ, "Waking dependents of completed instruction.\n");
8694380Sbinkertn@umich.edu
8703101Sstever@eecs.umich.edu    assert(!completed_inst->isSquashed());
8713101Sstever@eecs.umich.edu
8723101Sstever@eecs.umich.edu    // Tell the memory dependence unit to wake any dependents on this
87310267SGeoffrey.Blake@arm.com    // instruction if it is a memory instruction.  Also complete the memory
87410267SGeoffrey.Blake@arm.com    // instruction at this point since we know it executed without issues.
8757673Snate@binkert.org    // @todo: Might want to rename "completeMemInst" to something that
8767673Snate@binkert.org    // indicates that it won't need to be replayed, and call this
8777673Snate@binkert.org    // earlier.  Might not be a big deal.
8787673Snate@binkert.org    if (completed_inst->isMemRef()) {
8797673Snate@binkert.org        memDepUnit[completed_inst->threadNumber].wakeDependents(completed_inst);
8803101Sstever@eecs.umich.edu        completeMemInst(completed_inst);
8813101Sstever@eecs.umich.edu    } else if (completed_inst->isMemBarrier() ||
8823101Sstever@eecs.umich.edu               completed_inst->isWriteBarrier()) {
8833101Sstever@eecs.umich.edu        memDepUnit[completed_inst->threadNumber].completeBarrier(completed_inst);
8843101Sstever@eecs.umich.edu    }
8853101Sstever@eecs.umich.edu
8863101Sstever@eecs.umich.edu    for (int dest_reg_idx = 0;
8873101Sstever@eecs.umich.edu         dest_reg_idx < completed_inst->numDestRegs();
8883101Sstever@eecs.umich.edu         dest_reg_idx++)
8893101Sstever@eecs.umich.edu    {
8903101Sstever@eecs.umich.edu        PhysRegIndex dest_reg =
8913101Sstever@eecs.umich.edu            completed_inst->renamedDestRegIdx(dest_reg_idx);
8923101Sstever@eecs.umich.edu
8939941SGeoffrey.Blake@arm.com        // Special case of uniq or control registers.  They are not
8943101Sstever@eecs.umich.edu        // handled by the IQ and thus have no dependency graph entry.
8953101Sstever@eecs.umich.edu        // @todo Figure out a cleaner way to handle this.
8963101Sstever@eecs.umich.edu        if (dest_reg >= numPhysRegs) {
8973101Sstever@eecs.umich.edu            continue;
89810267SGeoffrey.Blake@arm.com        }
89910267SGeoffrey.Blake@arm.com
90010267SGeoffrey.Blake@arm.com        DPRINTF(IQ, "Waking any dependents on register %i.\n",
90110267SGeoffrey.Blake@arm.com                (int) dest_reg);
9023101Sstever@eecs.umich.edu
9033101Sstever@eecs.umich.edu        //Go through the dependency chain, marking the registers as
9044380Sbinkertn@umich.edu        //ready within the waiting instructions.
9053101Sstever@eecs.umich.edu        DynInstPtr dep_inst = dependGraph.pop(dest_reg);
9063101Sstever@eecs.umich.edu
9074762Snate@binkert.org        while (dep_inst) {
90811988Sandreas.sandberg@arm.com            DPRINTF(IQ, "Waking up a dependent instruction, PC%#x.\n",
9094762Snate@binkert.org                    dep_inst->readPC());
9104762Snate@binkert.org
91111228SAndrew.Bardsley@arm.com            // Might want to give more information to the instruction
91211228SAndrew.Bardsley@arm.com            // so that it knows which of its source registers is
91311228SAndrew.Bardsley@arm.com            // ready.  However that would mean that the dependency
9144380Sbinkertn@umich.edu            // graph entries would need to hold the src_reg_idx.
9154380Sbinkertn@umich.edu            dep_inst->markSrcRegReady();
9163101Sstever@eecs.umich.edu
91710458Sandreas.hansson@arm.com            addIfReady(dep_inst);
91810458Sandreas.hansson@arm.com
91910458Sandreas.hansson@arm.com            dep_inst = dependGraph.pop(dest_reg);
92010458Sandreas.hansson@arm.com
92110458Sandreas.hansson@arm.com            ++dependents;
9227777Sgblack@eecs.umich.edu        }
9237777Sgblack@eecs.umich.edu
9247777Sgblack@eecs.umich.edu        // Reset the head node now that all of its dependents have
9257777Sgblack@eecs.umich.edu        // been woken up.
92610267SGeoffrey.Blake@arm.com        assert(dependGraph.empty(dest_reg));
92710267SGeoffrey.Blake@arm.com        dependGraph.clearInst(dest_reg);
9287777Sgblack@eecs.umich.edu
9297777Sgblack@eecs.umich.edu        // Mark the scoreboard as having that register ready.
9307777Sgblack@eecs.umich.edu        regScoreboard[dest_reg] = true;
9317777Sgblack@eecs.umich.edu    }
9327777Sgblack@eecs.umich.edu    return dependents;
9337777Sgblack@eecs.umich.edu}
9347777Sgblack@eecs.umich.edu
9357777Sgblack@eecs.umich.edutemplate <class Impl>
9367777Sgblack@eecs.umich.eduvoid
9377777Sgblack@eecs.umich.eduInstructionQueue<Impl>::addReadyMemInst(DynInstPtr &ready_inst)
9387777Sgblack@eecs.umich.edu{
9397777Sgblack@eecs.umich.edu    OpClass op_class = ready_inst->opClass();
9407777Sgblack@eecs.umich.edu
9417777Sgblack@eecs.umich.edu    readyInsts[op_class].push(ready_inst);
9427777Sgblack@eecs.umich.edu
94310267SGeoffrey.Blake@arm.com    // Will need to reorder the list if either a queue is not on the list,
94410267SGeoffrey.Blake@arm.com    // or it has an older instruction than last time.
94510267SGeoffrey.Blake@arm.com    if (!queueOnList[op_class]) {
94610267SGeoffrey.Blake@arm.com        addToOrderList(op_class);
9478579Ssteve.reinhardt@amd.com    } else if (readyInsts[op_class].top()->seqNum  <
9488579Ssteve.reinhardt@amd.com               (*readyIt[op_class]).oldestInst) {
9498579Ssteve.reinhardt@amd.com        listOrder.erase(readyIt[op_class]);
9508579Ssteve.reinhardt@amd.com        addToOrderList(op_class);
9518579Ssteve.reinhardt@amd.com    }
9528579Ssteve.reinhardt@amd.com
9538579Ssteve.reinhardt@amd.com    DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
9548579Ssteve.reinhardt@amd.com            "the ready list, PC %#x opclass:%i [sn:%lli].\n",
9558579Ssteve.reinhardt@amd.com            ready_inst->readPC(), op_class, ready_inst->seqNum);
9568579Ssteve.reinhardt@amd.com}
9578579Ssteve.reinhardt@amd.com
9588579Ssteve.reinhardt@amd.comtemplate <class Impl>
9598579Ssteve.reinhardt@amd.comvoid
9608579Ssteve.reinhardt@amd.comInstructionQueue<Impl>::rescheduleMemInst(DynInstPtr &resched_inst)
9618579Ssteve.reinhardt@amd.com{
9628579Ssteve.reinhardt@amd.com    DPRINTF(IQ, "Rescheduling mem inst [sn:%lli]\n", resched_inst->seqNum);
9638579Ssteve.reinhardt@amd.com    resched_inst->clearCanIssue();
9648579Ssteve.reinhardt@amd.com    memDepUnit[resched_inst->threadNumber].reschedule(resched_inst);
9657777Sgblack@eecs.umich.edu}
9667777Sgblack@eecs.umich.edu
9677798Sgblack@eecs.umich.edutemplate <class Impl>
9687777Sgblack@eecs.umich.eduvoid
9697777Sgblack@eecs.umich.eduInstructionQueue<Impl>::replayMemInst(DynInstPtr &replay_inst)
97011988Sandreas.sandberg@arm.com{
9717777Sgblack@eecs.umich.edu    memDepUnit[replay_inst->threadNumber].replay(replay_inst);
9727777Sgblack@eecs.umich.edu}
9737777Sgblack@eecs.umich.edu
9747777Sgblack@eecs.umich.edutemplate <class Impl>
9757777Sgblack@eecs.umich.eduvoid
9767777Sgblack@eecs.umich.eduInstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst)
9777777Sgblack@eecs.umich.edu{
97810267SGeoffrey.Blake@arm.com    int tid = completed_inst->threadNumber;
97910267SGeoffrey.Blake@arm.com
9807777Sgblack@eecs.umich.edu    DPRINTF(IQ, "Completing mem instruction PC:%#x [sn:%lli]\n",
9817777Sgblack@eecs.umich.edu            completed_inst->readPC(), completed_inst->seqNum);
9827777Sgblack@eecs.umich.edu
9837777Sgblack@eecs.umich.edu    ++freeEntries;
9847777Sgblack@eecs.umich.edu
9857777Sgblack@eecs.umich.edu    completed_inst->memOpDone = true;
9867777Sgblack@eecs.umich.edu
9877777Sgblack@eecs.umich.edu    memDepUnit[tid].completed(completed_inst);
9887777Sgblack@eecs.umich.edu    count[tid]--;
9897777Sgblack@eecs.umich.edu}
9907777Sgblack@eecs.umich.edu
9917777Sgblack@eecs.umich.edutemplate <class Impl>
9927777Sgblack@eecs.umich.eduvoid
9937777Sgblack@eecs.umich.eduInstructionQueue<Impl>::violation(DynInstPtr &store,
9947777Sgblack@eecs.umich.edu                                  DynInstPtr &faulting_load)
9957777Sgblack@eecs.umich.edu{
9967777Sgblack@eecs.umich.edu    memDepUnit[store->threadNumber].violation(store, faulting_load);
9977777Sgblack@eecs.umich.edu}
9987777Sgblack@eecs.umich.edu
9997777Sgblack@eecs.umich.edutemplate <class Impl>
10007777Sgblack@eecs.umich.eduvoid
10017777Sgblack@eecs.umich.eduInstructionQueue<Impl>::squash(unsigned tid)
10027777Sgblack@eecs.umich.edu{
10037777Sgblack@eecs.umich.edu    DPRINTF(IQ, "[tid:%i]: Starting to squash instructions in "
10047777Sgblack@eecs.umich.edu            "the IQ.\n", tid);
10057777Sgblack@eecs.umich.edu
10067777Sgblack@eecs.umich.edu    // Read instruction sequence number of last instruction out of the
10077777Sgblack@eecs.umich.edu    // time buffer.
10087777Sgblack@eecs.umich.edu    squashedSeqNum[tid] = fromCommit->commitInfo[tid].doneSeqNum;
10097777Sgblack@eecs.umich.edu
10107777Sgblack@eecs.umich.edu    // Call doSquash if there are insts in the IQ
10117777Sgblack@eecs.umich.edu    if (count[tid] > 0) {
10127777Sgblack@eecs.umich.edu        doSquash(tid);
10137777Sgblack@eecs.umich.edu    }
10147777Sgblack@eecs.umich.edu
10157777Sgblack@eecs.umich.edu    // Also tell the memory dependence unit to squash.
10167777Sgblack@eecs.umich.edu    memDepUnit[tid].squash(squashedSeqNum[tid], tid);
10177777Sgblack@eecs.umich.edu}
10187777Sgblack@eecs.umich.edu
10197777Sgblack@eecs.umich.edutemplate <class Impl>
10207777Sgblack@eecs.umich.eduvoid
102110267SGeoffrey.Blake@arm.comInstructionQueue<Impl>::doSquash(unsigned tid)
102210267SGeoffrey.Blake@arm.com{
102310267SGeoffrey.Blake@arm.com    // Start at the tail.
102410267SGeoffrey.Blake@arm.com    ListIt squash_it = instList[tid].end();
10258579Ssteve.reinhardt@amd.com    --squash_it;
10268579Ssteve.reinhardt@amd.com
10278579Ssteve.reinhardt@amd.com    DPRINTF(IQ, "[tid:%i]: Squashing until sequence number %i!\n",
10288579Ssteve.reinhardt@amd.com            tid, squashedSeqNum[tid]);
10298579Ssteve.reinhardt@amd.com
10308579Ssteve.reinhardt@amd.com    // Squash any instructions younger than the squashed sequence number
10318579Ssteve.reinhardt@amd.com    // given.
10328579Ssteve.reinhardt@amd.com    while (squash_it != instList[tid].end() &&
10338579Ssteve.reinhardt@amd.com           (*squash_it)->seqNum > squashedSeqNum[tid]) {
10348579Ssteve.reinhardt@amd.com
10358579Ssteve.reinhardt@amd.com        DynInstPtr squashed_inst = (*squash_it);
10368579Ssteve.reinhardt@amd.com
10378579Ssteve.reinhardt@amd.com        // Only handle the instruction if it actually is in the IQ and
10388579Ssteve.reinhardt@amd.com        // hasn't already been squashed in the IQ.
10397777Sgblack@eecs.umich.edu        if (squashed_inst->threadNumber != tid ||
10407777Sgblack@eecs.umich.edu            squashed_inst->isSquashedInIQ()) {
10417777Sgblack@eecs.umich.edu            --squash_it;
10427777Sgblack@eecs.umich.edu            continue;
10437777Sgblack@eecs.umich.edu        }
10447777Sgblack@eecs.umich.edu
104511988Sandreas.sandberg@arm.com        if (!squashed_inst->isIssued() ||
10467777Sgblack@eecs.umich.edu            (squashed_inst->isMemRef() &&
10477777Sgblack@eecs.umich.edu             !squashed_inst->memOpDone)) {
10487777Sgblack@eecs.umich.edu
10497777Sgblack@eecs.umich.edu            DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %#x "
10507777Sgblack@eecs.umich.edu                    "squashed.\n",
10517777Sgblack@eecs.umich.edu                    tid, squashed_inst->seqNum, squashed_inst->readPC());
105210267SGeoffrey.Blake@arm.com
105310267SGeoffrey.Blake@arm.com            // Remove the instruction from the dependency list.
10547777Sgblack@eecs.umich.edu            if (!squashed_inst->isNonSpeculative() &&
10557777Sgblack@eecs.umich.edu                !squashed_inst->isStoreConditional() &&
10567777Sgblack@eecs.umich.edu                !squashed_inst->isMemBarrier() &&
10577777Sgblack@eecs.umich.edu                !squashed_inst->isWriteBarrier()) {
10587777Sgblack@eecs.umich.edu
10597777Sgblack@eecs.umich.edu                for (int src_reg_idx = 0;
10607777Sgblack@eecs.umich.edu                     src_reg_idx < squashed_inst->numSrcRegs();
10617777Sgblack@eecs.umich.edu                     src_reg_idx++)
10627777Sgblack@eecs.umich.edu                {
10637777Sgblack@eecs.umich.edu                    PhysRegIndex src_reg =
10647777Sgblack@eecs.umich.edu                        squashed_inst->renamedSrcRegIdx(src_reg_idx);
10657777Sgblack@eecs.umich.edu
10667777Sgblack@eecs.umich.edu                    // Only remove it from the dependency graph if it
10677777Sgblack@eecs.umich.edu                    // was placed there in the first place.
10687777Sgblack@eecs.umich.edu
10697777Sgblack@eecs.umich.edu                    // Instead of doing a linked list traversal, we
10707777Sgblack@eecs.umich.edu                    // can just remove these squashed instructions
10717777Sgblack@eecs.umich.edu                    // either at issue time, or when the register is
10727777Sgblack@eecs.umich.edu                    // overwritten.  The only downside to this is it
10737777Sgblack@eecs.umich.edu                    // leaves more room for error.
10747777Sgblack@eecs.umich.edu
10757777Sgblack@eecs.umich.edu                    if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) &&
10767777Sgblack@eecs.umich.edu                        src_reg < numPhysRegs) {
10777777Sgblack@eecs.umich.edu                        dependGraph.remove(src_reg, squashed_inst);
10787777Sgblack@eecs.umich.edu                    }
10797777Sgblack@eecs.umich.edu
10807777Sgblack@eecs.umich.edu
10817777Sgblack@eecs.umich.edu                    ++iqSquashedOperandsExamined;
10827777Sgblack@eecs.umich.edu                }
10837777Sgblack@eecs.umich.edu            } else if (!squashed_inst->isStoreConditional() ||
10847777Sgblack@eecs.umich.edu                       !squashed_inst->isCompleted()) {
10857777Sgblack@eecs.umich.edu                NonSpecMapIt ns_inst_it =
10867777Sgblack@eecs.umich.edu                    nonSpecInsts.find(squashed_inst->seqNum);
10877777Sgblack@eecs.umich.edu                assert(ns_inst_it != nonSpecInsts.end());
10887777Sgblack@eecs.umich.edu                if (ns_inst_it == nonSpecInsts.end()) {
10897777Sgblack@eecs.umich.edu                    assert(squashed_inst->getFault() != NoFault);
10907777Sgblack@eecs.umich.edu                } else {
10917777Sgblack@eecs.umich.edu
10927777Sgblack@eecs.umich.edu                    (*ns_inst_it).second = NULL;
10937777Sgblack@eecs.umich.edu
10947777Sgblack@eecs.umich.edu                    nonSpecInsts.erase(ns_inst_it);
109510267SGeoffrey.Blake@arm.com
109610267SGeoffrey.Blake@arm.com                    ++iqSquashedNonSpecRemoved;
109710267SGeoffrey.Blake@arm.com                }
109810267SGeoffrey.Blake@arm.com            }
10998579Ssteve.reinhardt@amd.com
11008579Ssteve.reinhardt@amd.com            // Might want to also clear out the head of the dependency graph.
11018579Ssteve.reinhardt@amd.com
11028579Ssteve.reinhardt@amd.com            // Mark it as squashed within the IQ.
11038579Ssteve.reinhardt@amd.com            squashed_inst->setSquashedInIQ();
11048579Ssteve.reinhardt@amd.com
11058579Ssteve.reinhardt@amd.com            // @todo: Remove this hack where several statuses are set so the
11068579Ssteve.reinhardt@amd.com            // inst will flow through the rest of the pipeline.
11078579Ssteve.reinhardt@amd.com            squashed_inst->setIssued();
11088579Ssteve.reinhardt@amd.com            squashed_inst->setCanCommit();
11098579Ssteve.reinhardt@amd.com            squashed_inst->clearInIQ();
11108579Ssteve.reinhardt@amd.com
11118579Ssteve.reinhardt@amd.com            //Update Thread IQ Count
11128579Ssteve.reinhardt@amd.com            count[squashed_inst->threadNumber]--;
11137777Sgblack@eecs.umich.edu
11147777Sgblack@eecs.umich.edu            ++freeEntries;
11157777Sgblack@eecs.umich.edu        }
11167777Sgblack@eecs.umich.edu
11177777Sgblack@eecs.umich.edu        instList[tid].erase(squash_it--);
11187777Sgblack@eecs.umich.edu        ++iqSquashedInstsExamined;
111911988Sandreas.sandberg@arm.com    }
11207777Sgblack@eecs.umich.edu}
11217777Sgblack@eecs.umich.edu
11223932Sbinkertn@umich.edutemplate <class Impl>
112310380SAndrew.Bardsley@arm.combool
11243932Sbinkertn@umich.eduInstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst)
11253932Sbinkertn@umich.edu{
11263932Sbinkertn@umich.edu    // Loop through the instruction's source registers, adding
11273932Sbinkertn@umich.edu    // them to the dependency list if they are not ready.
11283932Sbinkertn@umich.edu    int8_t total_src_regs = new_inst->numSrcRegs();
11293932Sbinkertn@umich.edu    bool return_val = false;
11303932Sbinkertn@umich.edu
11313932Sbinkertn@umich.edu    for (int src_reg_idx = 0;
11323932Sbinkertn@umich.edu         src_reg_idx < total_src_regs;
11333932Sbinkertn@umich.edu         src_reg_idx++)
11343932Sbinkertn@umich.edu    {
11353885Sbinkertn@umich.edu        // Only add it to the dependency graph if it's not ready.
11363932Sbinkertn@umich.edu        if (!new_inst->isReadySrcRegIdx(src_reg_idx)) {
11373932Sbinkertn@umich.edu            PhysRegIndex src_reg = new_inst->renamedSrcRegIdx(src_reg_idx);
11383885Sbinkertn@umich.edu
11393932Sbinkertn@umich.edu            // Check the IQ's scoreboard to make sure the register
11403932Sbinkertn@umich.edu            // hasn't become ready while the instruction was in flight
11413932Sbinkertn@umich.edu            // between stages.  Only if it really isn't ready should
11423932Sbinkertn@umich.edu            // it be added to the dependency graph.
11433932Sbinkertn@umich.edu            if (src_reg >= numPhysRegs) {
11443932Sbinkertn@umich.edu                continue;
11453932Sbinkertn@umich.edu            } else if (regScoreboard[src_reg] == false) {
11463932Sbinkertn@umich.edu                DPRINTF(IQ, "Instruction PC %#x has src reg %i that "
11473932Sbinkertn@umich.edu                        "is being added to the dependency chain.\n",
11483932Sbinkertn@umich.edu                        new_inst->readPC(), src_reg);
11493932Sbinkertn@umich.edu
11503932Sbinkertn@umich.edu                dependGraph.insert(src_reg, new_inst);
11513932Sbinkertn@umich.edu
11523932Sbinkertn@umich.edu                // Change the return value to indicate that something
11533932Sbinkertn@umich.edu                // was added to the dependency graph.
11543932Sbinkertn@umich.edu                return_val = true;
11553932Sbinkertn@umich.edu            } else {
11563932Sbinkertn@umich.edu                DPRINTF(IQ, "Instruction PC %#x has src reg %i that "
11573885Sbinkertn@umich.edu                        "became ready before it reached the IQ.\n",
11583885Sbinkertn@umich.edu                        new_inst->readPC(), src_reg);
11593885Sbinkertn@umich.edu                // Mark a register ready within the instruction.
11603885Sbinkertn@umich.edu                new_inst->markSrcRegReady(src_reg_idx);
11614762Snate@binkert.org            }
11627673Snate@binkert.org        }
11637673Snate@binkert.org    }
11647673Snate@binkert.org
11657673Snate@binkert.org    return return_val;
11667673Snate@binkert.org}
11673885Sbinkertn@umich.edu
11683932Sbinkertn@umich.edutemplate <class Impl>
11693885Sbinkertn@umich.eduvoid
117010267SGeoffrey.Blake@arm.comInstructionQueue<Impl>::addToProducers(DynInstPtr &new_inst)
117110267SGeoffrey.Blake@arm.com{
117210267SGeoffrey.Blake@arm.com    // Nothing really needs to be marked when an instruction becomes
117310267SGeoffrey.Blake@arm.com    // the producer of a register's value, but for convenience a ptr
11744762Snate@binkert.org    // to the producing instruction will be placed in the head node of
117511988Sandreas.sandberg@arm.com    // the dependency links.
117611988Sandreas.sandberg@arm.com    int8_t total_dest_regs = new_inst->numDestRegs();
11774762Snate@binkert.org
117811988Sandreas.sandberg@arm.com    for (int dest_reg_idx = 0;
11794762Snate@binkert.org         dest_reg_idx < total_dest_regs;
11803885Sbinkertn@umich.edu         dest_reg_idx++)
11814762Snate@binkert.org    {
11823885Sbinkertn@umich.edu        PhysRegIndex dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx);
11833885Sbinkertn@umich.edu
11843932Sbinkertn@umich.edu        // Instructions that use the misc regs will have a reg number
11853885Sbinkertn@umich.edu        // higher than the normal physical registers.  In this case these
11868664SAli.Saidi@ARM.com        // registers are not renamed, and there is no need to track
118710380SAndrew.Bardsley@arm.com        // dependencies as these instructions must be executed at commit.
11888664SAli.Saidi@ARM.com        if (dest_reg >= numPhysRegs) {
11898664SAli.Saidi@ARM.com            continue;
119010458Sandreas.hansson@arm.com        }
119110458Sandreas.hansson@arm.com
119210458Sandreas.hansson@arm.com        if (!dependGraph.empty(dest_reg)) {
119310458Sandreas.hansson@arm.com            dependGraph.dump();
119410458Sandreas.hansson@arm.com            panic("Dependency graph %i not empty!", dest_reg);
119510458Sandreas.hansson@arm.com        }
119610458Sandreas.hansson@arm.com
119710458Sandreas.hansson@arm.com        dependGraph.setInst(dest_reg, new_inst);
119810458Sandreas.hansson@arm.com
119910458Sandreas.hansson@arm.com        // Mark the scoreboard to say it's not yet ready.
12003101Sstever@eecs.umich.edu        regScoreboard[dest_reg] = false;
12013101Sstever@eecs.umich.edu    }
12023101Sstever@eecs.umich.edu}
12033101Sstever@eecs.umich.edu
12043101Sstever@eecs.umich.edutemplate <class Impl>
12053101Sstever@eecs.umich.eduvoid
12063101Sstever@eecs.umich.eduInstructionQueue<Impl>::addIfReady(DynInstPtr &inst)
12073101Sstever@eecs.umich.edu{
12083101Sstever@eecs.umich.edu    // If the instruction now has all of its source registers
12093101Sstever@eecs.umich.edu    // available, then add it to the list of ready instructions.
12103101Sstever@eecs.umich.edu    if (inst->readyToIssue()) {
12113101Sstever@eecs.umich.edu
12123101Sstever@eecs.umich.edu        //Add the instruction to the proper ready list.
12133101Sstever@eecs.umich.edu        if (inst->isMemRef()) {
12144762Snate@binkert.org
12153101Sstever@eecs.umich.edu            DPRINTF(IQ, "Checking if memory instruction can issue.\n");
12165033Smilesck@eecs.umich.edu
12174762Snate@binkert.org            // Message to the mem dependence unit that this instruction has
12184762Snate@binkert.org            // its registers ready.
12194762Snate@binkert.org            memDepUnit[inst->threadNumber].regsReady(inst);
12204762Snate@binkert.org
12214762Snate@binkert.org            return;
12224762Snate@binkert.org        }
12234762Snate@binkert.org
12243101Sstever@eecs.umich.edu        OpClass op_class = inst->opClass();
12253101Sstever@eecs.umich.edu
12263101Sstever@eecs.umich.edu        DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
12273101Sstever@eecs.umich.edu                "the ready list, PC %#x opclass:%i [sn:%lli].\n",
12283101Sstever@eecs.umich.edu                inst->readPC(), op_class, inst->seqNum);
12293101Sstever@eecs.umich.edu
12303101Sstever@eecs.umich.edu        readyInsts[op_class].push(inst);
12313101Sstever@eecs.umich.edu
12323101Sstever@eecs.umich.edu        // Will need to reorder the list if either a queue is not on the list,
12333101Sstever@eecs.umich.edu        // or it has an older instruction than last time.
12343101Sstever@eecs.umich.edu        if (!queueOnList[op_class]) {
12353101Sstever@eecs.umich.edu            addToOrderList(op_class);
12363101Sstever@eecs.umich.edu        } else if (readyInsts[op_class].top()->seqNum  <
12373101Sstever@eecs.umich.edu                   (*readyIt[op_class]).oldestInst) {
12383101Sstever@eecs.umich.edu            listOrder.erase(readyIt[op_class]);
12393101Sstever@eecs.umich.edu            addToOrderList(op_class);
12403101Sstever@eecs.umich.edu        }
12413101Sstever@eecs.umich.edu    }
12423101Sstever@eecs.umich.edu}
12433101Sstever@eecs.umich.edu
12444762Snate@binkert.orgtemplate <class Impl>
12453101Sstever@eecs.umich.eduint
12463101Sstever@eecs.umich.eduInstructionQueue<Impl>::countInsts()
12473101Sstever@eecs.umich.edu{
12483101Sstever@eecs.umich.edu#if 0
12493101Sstever@eecs.umich.edu    //ksewell:This works but definitely could use a cleaner write
12503101Sstever@eecs.umich.edu    //with a more intuitive way of counting. Right now it's
12517673Snate@binkert.org    //just brute force ....
125210201SAndrew.Bardsley@arm.com    // Change the #if if you want to use this method.
125310201SAndrew.Bardsley@arm.com    int total_insts = 0;
125410201SAndrew.Bardsley@arm.com
125510201SAndrew.Bardsley@arm.com    for (int i = 0; i < numThreads; ++i) {
125610201SAndrew.Bardsley@arm.com        ListIt count_it = instList[i].begin();
12577673Snate@binkert.org
125810201SAndrew.Bardsley@arm.com        while (count_it != instList[i].end()) {
125910201SAndrew.Bardsley@arm.com            if (!(*count_it)->isSquashed() && !(*count_it)->isSquashedInIQ()) {
12607673Snate@binkert.org                if (!(*count_it)->isIssued()) {
126110201SAndrew.Bardsley@arm.com                    ++total_insts;
12627673Snate@binkert.org                } else if ((*count_it)->isMemRef() &&
12637673Snate@binkert.org                           !(*count_it)->memOpDone) {
12647673Snate@binkert.org                    // Loads that have not been marked as executed still count
12654762Snate@binkert.org                    // towards the total instructions.
12667673Snate@binkert.org                    ++total_insts;
12678902Sandreas.hansson@arm.com                }
12687673Snate@binkert.org            }
126910201SAndrew.Bardsley@arm.com
12704762Snate@binkert.org            ++count_it;
127110201SAndrew.Bardsley@arm.com        }
127210201SAndrew.Bardsley@arm.com    }
127310201SAndrew.Bardsley@arm.com
127410201SAndrew.Bardsley@arm.com    return total_insts;
127510201SAndrew.Bardsley@arm.com#else
127610201SAndrew.Bardsley@arm.com    return numEntries - freeEntries;
127710201SAndrew.Bardsley@arm.com#endif
127810201SAndrew.Bardsley@arm.com}
127910201SAndrew.Bardsley@arm.com
12807673Snate@binkert.orgtemplate <class Impl>
12817673Snate@binkert.orgvoid
128210201SAndrew.Bardsley@arm.comInstructionQueue<Impl>::dumpLists()
128310201SAndrew.Bardsley@arm.com{
128410201SAndrew.Bardsley@arm.com    for (int i = 0; i < Num_OpClasses; ++i) {
128510201SAndrew.Bardsley@arm.com        cprintf("Ready list %i size: %i\n", i, readyInsts[i].size());
128610201SAndrew.Bardsley@arm.com
128710201SAndrew.Bardsley@arm.com        cprintf("\n");
128810201SAndrew.Bardsley@arm.com    }
128910201SAndrew.Bardsley@arm.com
129010201SAndrew.Bardsley@arm.com    cprintf("Non speculative list size: %i\n", nonSpecInsts.size());
129110201SAndrew.Bardsley@arm.com
129210201SAndrew.Bardsley@arm.com    NonSpecMapIt non_spec_it = nonSpecInsts.begin();
129310201SAndrew.Bardsley@arm.com    NonSpecMapIt non_spec_end_it = nonSpecInsts.end();
129410201SAndrew.Bardsley@arm.com
129510201SAndrew.Bardsley@arm.com    cprintf("Non speculative list: ");
129610201SAndrew.Bardsley@arm.com
12974762Snate@binkert.org    while (non_spec_it != non_spec_end_it) {
12987673Snate@binkert.org        cprintf("%#x [sn:%lli]", (*non_spec_it).second->readPC(),
129910201SAndrew.Bardsley@arm.com                (*non_spec_it).second->seqNum);
130010201SAndrew.Bardsley@arm.com        ++non_spec_it;
130110201SAndrew.Bardsley@arm.com    }
130210201SAndrew.Bardsley@arm.com
130310201SAndrew.Bardsley@arm.com    cprintf("\n");
130410201SAndrew.Bardsley@arm.com
13053101Sstever@eecs.umich.edu    ListOrderIt list_order_it = listOrder.begin();
130611988Sandreas.sandberg@arm.com    ListOrderIt list_order_end_it = listOrder.end();
130711988Sandreas.sandberg@arm.com    int i = 1;
130811988Sandreas.sandberg@arm.com
130911988Sandreas.sandberg@arm.com    cprintf("List order: ");
131011988Sandreas.sandberg@arm.com
131111988Sandreas.sandberg@arm.com    while (list_order_it != list_order_end_it) {
131211988Sandreas.sandberg@arm.com        cprintf("%i OpClass:%i [sn:%lli] ", i, (*list_order_it).queueType,
131311988Sandreas.sandberg@arm.com                (*list_order_it).oldestInst);
131411988Sandreas.sandberg@arm.com
131511988Sandreas.sandberg@arm.com        ++list_order_it;
131611988Sandreas.sandberg@arm.com        ++i;
131711988Sandreas.sandberg@arm.com    }
131811988Sandreas.sandberg@arm.com
131911988Sandreas.sandberg@arm.com    cprintf("\n");
132011988Sandreas.sandberg@arm.com}
132111988Sandreas.sandberg@arm.com
132211988Sandreas.sandberg@arm.com
132311988Sandreas.sandberg@arm.comtemplate <class Impl>
132411988Sandreas.sandberg@arm.comvoid
132511988Sandreas.sandberg@arm.comInstructionQueue<Impl>::dumpInsts()
132611988Sandreas.sandberg@arm.com{
132711988Sandreas.sandberg@arm.com    for (int i = 0; i < numThreads; ++i) {
132811988Sandreas.sandberg@arm.com        int num = 0;
132911988Sandreas.sandberg@arm.com        int valid_num = 0;
133011988Sandreas.sandberg@arm.com        ListIt inst_list_it = instList[i].begin();
133111988Sandreas.sandberg@arm.com
133211988Sandreas.sandberg@arm.com        while (inst_list_it != instList[i].end())
133311988Sandreas.sandberg@arm.com        {
133411988Sandreas.sandberg@arm.com            cprintf("Instruction:%i\n",
133511988Sandreas.sandberg@arm.com                    num);
133611988Sandreas.sandberg@arm.com            if (!(*inst_list_it)->isSquashed()) {
133711988Sandreas.sandberg@arm.com                if (!(*inst_list_it)->isIssued()) {
133811988Sandreas.sandberg@arm.com                    ++valid_num;
133911988Sandreas.sandberg@arm.com                    cprintf("Count:%i\n", valid_num);
13408596Ssteve.reinhardt@amd.com                } else if ((*inst_list_it)->isMemRef() &&
13413101Sstever@eecs.umich.edu                           !(*inst_list_it)->memOpDone) {
13423101Sstever@eecs.umich.edu                    // Loads that have not been marked as executed
13433101Sstever@eecs.umich.edu                    // still count towards the total instructions.
13443101Sstever@eecs.umich.edu                    ++valid_num;
134510267SGeoffrey.Blake@arm.com                    cprintf("Count:%i\n", valid_num);
13463101Sstever@eecs.umich.edu                }
134710201SAndrew.Bardsley@arm.com            }
134810201SAndrew.Bardsley@arm.com
134910201SAndrew.Bardsley@arm.com            cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
135010201SAndrew.Bardsley@arm.com                    "Issued:%i\nSquashed:%i\n",
135110201SAndrew.Bardsley@arm.com                    (*inst_list_it)->readPC(),
135210201SAndrew.Bardsley@arm.com                    (*inst_list_it)->seqNum,
135310201SAndrew.Bardsley@arm.com                    (*inst_list_it)->threadNumber,
135410201SAndrew.Bardsley@arm.com                    (*inst_list_it)->isIssued(),
135510201SAndrew.Bardsley@arm.com                    (*inst_list_it)->isSquashed());
13563101Sstever@eecs.umich.edu
13573101Sstever@eecs.umich.edu            if ((*inst_list_it)->isMemRef()) {
13583101Sstever@eecs.umich.edu                cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone);
13593101Sstever@eecs.umich.edu            }
13603101Sstever@eecs.umich.edu
13613101Sstever@eecs.umich.edu            cprintf("\n");
136210267SGeoffrey.Blake@arm.com
136310267SGeoffrey.Blake@arm.com            inst_list_it++;
136410267SGeoffrey.Blake@arm.com            ++num;
136510267SGeoffrey.Blake@arm.com        }
13667675Snate@binkert.org    }
13677675Snate@binkert.org
13687675Snate@binkert.org    cprintf("Insts to Execute list:\n");
13697675Snate@binkert.org
13707675Snate@binkert.org    int num = 0;
137110458Sandreas.hansson@arm.com    int valid_num = 0;
137210458Sandreas.hansson@arm.com    ListIt inst_list_it = instsToExecute.begin();
137310458Sandreas.hansson@arm.com
137410458Sandreas.hansson@arm.com    while (inst_list_it != instsToExecute.end())
137510458Sandreas.hansson@arm.com    {
137610458Sandreas.hansson@arm.com        cprintf("Instruction:%i\n",
137710458Sandreas.hansson@arm.com                num);
137810458Sandreas.hansson@arm.com        if (!(*inst_list_it)->isSquashed()) {
137910458Sandreas.hansson@arm.com            if (!(*inst_list_it)->isIssued()) {
138010458Sandreas.hansson@arm.com                ++valid_num;
138110458Sandreas.hansson@arm.com                cprintf("Count:%i\n", valid_num);
138210458Sandreas.hansson@arm.com            } else if ((*inst_list_it)->isMemRef() &&
13834762Snate@binkert.org                       !(*inst_list_it)->memOpDone) {
138411988Sandreas.sandberg@arm.com                // Loads that have not been marked as executed
138511988Sandreas.sandberg@arm.com                // still count towards the total instructions.
138611988Sandreas.sandberg@arm.com                ++valid_num;
13874762Snate@binkert.org                cprintf("Count:%i\n", valid_num);
13883101Sstever@eecs.umich.edu            }
13893101Sstever@eecs.umich.edu        }
13903101Sstever@eecs.umich.edu
13913101Sstever@eecs.umich.edu        cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
13923101Sstever@eecs.umich.edu                "Issued:%i\nSquashed:%i\n",
13933101Sstever@eecs.umich.edu                (*inst_list_it)->readPC(),
13944167Sbinkertn@umich.edu                (*inst_list_it)->seqNum,
13953101Sstever@eecs.umich.edu                (*inst_list_it)->threadNumber,
139610267SGeoffrey.Blake@arm.com                (*inst_list_it)->isIssued(),
139710267SGeoffrey.Blake@arm.com                (*inst_list_it)->isSquashed());
13987673Snate@binkert.org
13997673Snate@binkert.org        if ((*inst_list_it)->isMemRef()) {
14007673Snate@binkert.org            cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone);
14017673Snate@binkert.org        }
14027673Snate@binkert.org
140310267SGeoffrey.Blake@arm.com        cprintf("\n");
140410267SGeoffrey.Blake@arm.com
140510267SGeoffrey.Blake@arm.com        inst_list_it++;
140610267SGeoffrey.Blake@arm.com        ++num;
14074762Snate@binkert.org    }
14084762Snate@binkert.org}
14094762Snate@binkert.org