inst_queue_impl.hh revision 2980
11689SN/A/*
213590Srekai.gonzalezalberquilla@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
39920Syasuko.eckert@amd.com * All rights reserved.
47944SGiacomo.Gabrielli@arm.com *
57944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without
67944SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are
77944SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright
87944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer;
97944SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright
107944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the
117944SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution;
127944SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its
137944SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from
147944SGiacomo.Gabrielli@arm.com * this software without specific prior written permission.
152326SN/A *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271689SN/A *
281689SN/A * Authors: Kevin Lim
291689SN/A *          Korey Sewell
301689SN/A */
311689SN/A
321689SN/A#include <limits>
331689SN/A#include <vector>
341689SN/A
351689SN/A#include "sim/root.hh"
361689SN/A
371689SN/A#include "cpu/o3/fu_pool.hh"
381689SN/A#include "cpu/o3/inst_queue.hh"
391689SN/A
402665Ssaidi@eecs.umich.edutemplate <class Impl>
412665Ssaidi@eecs.umich.eduInstructionQueue<Impl>::FUCompletion::FUCompletion(DynInstPtr &_inst,
422831Sksewell@umich.edu                                                   int fu_idx,
431689SN/A                                                   InstructionQueue<Impl> *iq_ptr)
441689SN/A    : Event(&mainEventQueue, Stat_Event_Pri),
459944Smatt.horsnell@ARM.com      inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false)
469944Smatt.horsnell@ARM.com{
479944Smatt.horsnell@ARM.com    this->setFlags(Event::AutoDelete);
482064SN/A}
491060SN/A
501060SN/Atemplate <class Impl>
5113449Sgabeblack@google.comvoid
522292SN/AInstructionQueue<Impl>::FUCompletion::process()
531717SN/A{
548232Snate@binkert.org    iqPtr->processFUCompletion(inst, freeFU ? fuIdx : -1);
554762Snate@binkert.org    inst = NULL;
566221Snate@binkert.org}
574762Snate@binkert.org
581060SN/A
598737Skoansin.tan@gmail.comtemplate <class Impl>
608737Skoansin.tan@gmail.comconst char *
618737Skoansin.tan@gmail.comInstructionQueue<Impl>::FUCompletion::description()
625529Snate@binkert.org{
631061SN/A    return "Functional unit completion event";
6413429Srekai.gonzalezalberquilla@arm.com}
655606Snate@binkert.org
668581Ssteve.reinhardt@amd.comtemplate <class Impl>
678581Ssteve.reinhardt@amd.comInstructionQueue<Impl>::InstructionQueue(Params *params)
681060SN/A    : fuPool(params->fuPool),
692292SN/A      numEntries(params->numIQEntries),
702292SN/A      totalWidth(params->issueWidth),
712292SN/A      numPhysIntRegs(params->numPhysIntRegs),
722292SN/A      numPhysFloatRegs(params->numPhysFloatRegs),
732292SN/A      commitToIEWDelay(params->commitToIEWDelay)
742292SN/A{
752326SN/A    assert(fuPool);
762292SN/A
772292SN/A    switchedOut = false;
782292SN/A
792292SN/A    numThreads = params->numberOfThreads;
802292SN/A
812292SN/A    // Set the number of physical registers as the number of int + float
825336Shines@cs.fsu.edu    numPhysRegs = numPhysIntRegs + numPhysFloatRegs;
832292SN/A
844873Sstever@eecs.umich.edu    DPRINTF(IQ, "There are %i physical registers.\n", numPhysRegs);
852292SN/A
862292SN/A    //Create an entry for each physical register within the
872292SN/A    //dependency graph.
884329Sktlim@umich.edu    dependGraph.resize(numPhysRegs);
895529Snate@binkert.org
904329Sktlim@umich.edu    // Resize the register scoreboard.
914329Sktlim@umich.edu    regScoreboard.resize(numPhysRegs);
924329Sktlim@umich.edu
9313561Snikos.nikoleris@arm.com    //Initialize Mem Dependence Units
942292SN/A    for (int i = 0; i < numThreads; i++) {
952292SN/A        memDepUnit[i].init(params,i);
962292SN/A        memDepUnit[i].setIQ(this);
972292SN/A    }
982292SN/A
992292SN/A    resetState();
1005529Snate@binkert.org
1011060SN/A    std::string policy = params->smtIQPolicy;
1029920Syasuko.eckert@amd.com
10312109SRekai.GonzalezAlberquilla@arm.com    //Convert string to lowercase
1049920Syasuko.eckert@amd.com    std::transform(policy.begin(), policy.end(), policy.begin(),
10512109SRekai.GonzalezAlberquilla@arm.com                   (int(*)(int)) tolower);
10612109SRekai.GonzalezAlberquilla@arm.com
10713610Sgiacomo.gabrielli@arm.com    //Figure out resource sharing policy
10812109SRekai.GonzalezAlberquilla@arm.com    if (policy == "dynamic") {
1091060SN/A        iqPolicy = Dynamic;
1101060SN/A
1111060SN/A        //Set Max Entries to Total ROB Capacity
1122326SN/A        for (int i = 0; i < numThreads; i++) {
1131060SN/A            maxEntries[i] = numEntries;
1141060SN/A        }
1151060SN/A
1161060SN/A    } else if (policy == "partitioned") {
1172292SN/A        iqPolicy = Partitioned;
11813453Srekai.gonzalezalberquilla@arm.com
1196221Snate@binkert.org        //@todo:make work if part_amt doesnt divide evenly.
1206221Snate@binkert.org        int part_amt = numEntries / numThreads;
1211060SN/A
1221060SN/A        //Divide ROB up evenly
1232307SN/A        for (int i = 0; i < numThreads; i++) {
1242292SN/A            maxEntries[i] = part_amt;
1252292SN/A        }
12613561Snikos.nikoleris@arm.com
1272292SN/A        DPRINTF(IQ, "IQ sharing policy set to Partitioned:"
1286221Snate@binkert.org                "%i entries per thread.\n",part_amt);
1296221Snate@binkert.org
1302292SN/A    } else if (policy == "threshold") {
1312292SN/A        iqPolicy = Threshold;
13213561Snikos.nikoleris@arm.com
1332292SN/A        double threshold =  (double)params->smtIQThreshold / 100;
1342292SN/A
1352292SN/A        int thresholdIQ = (int)((double)threshold * numEntries);
1362292SN/A
1376221Snate@binkert.org        //Divide up by threshold amount
1386221Snate@binkert.org        for (int i = 0; i < numThreads; i++) {
1392292SN/A            maxEntries[i] = thresholdIQ;
1402292SN/A        }
1412831Sksewell@umich.edu
1422292SN/A        DPRINTF(IQ, "IQ sharing policy set to Threshold:"
14313561Snikos.nikoleris@arm.com                "%i entries per thread.\n",thresholdIQ);
1442292SN/A   } else {
1452292SN/A       assert(0 && "Invalid IQ Sharing Policy.Options Are:{Dynamic,"
1462292SN/A              "Partitioned, Threshold}");
1472292SN/A   }
1482292SN/A}
1496221Snate@binkert.org
1506221Snate@binkert.orgtemplate <class Impl>
1512292SN/AInstructionQueue<Impl>::~InstructionQueue()
1522292SN/A{
1532831Sksewell@umich.edu    dependGraph.reset();
1542292SN/A#ifdef DEBUG
1552292SN/A    cprintf("Nodes traversed: %i, removed: %i\n",
15613453Srekai.gonzalezalberquilla@arm.com            dependGraph.nodesTraversed, dependGraph.nodesRemoved);
15713453Srekai.gonzalezalberquilla@arm.com#endif
15813453Srekai.gonzalezalberquilla@arm.com}
1592292SN/A
1602292SN/Atemplate <class Impl>
1612292SN/Astd::string
1622292SN/AInstructionQueue<Impl>::name() const
1632292SN/A{
1642326SN/A    return cpu->name() + ".iq";
1652348SN/A}
1662326SN/A
1672326SN/Atemplate <class Impl>
1682348SN/Avoid
1692292SN/AInstructionQueue<Impl>::regStats()
1702292SN/A{
1712292SN/A    using namespace Stats;
1722292SN/A    iqInstsAdded
1732292SN/A        .name(name() + ".iqInstsAdded")
1742292SN/A        .desc("Number of instructions added to the IQ (excludes non-spec)")
1752292SN/A        .prereq(iqInstsAdded);
1761060SN/A
1771060SN/A    iqNonSpecInstsAdded
1781061SN/A        .name(name() + ".iqNonSpecInstsAdded")
1791060SN/A        .desc("Number of non-speculative instructions added to the IQ")
1801062SN/A        .prereq(iqNonSpecInstsAdded);
1811062SN/A
1822301SN/A    iqInstsIssued
1831062SN/A        .name(name() + ".iqInstsIssued")
1841062SN/A        .desc("Number of instructions issued")
1851062SN/A        .prereq(iqInstsIssued);
1861062SN/A
1871062SN/A    iqIntInstsIssued
1881062SN/A        .name(name() + ".iqIntInstsIssued")
1891062SN/A        .desc("Number of integer instructions issued")
1901062SN/A        .prereq(iqIntInstsIssued);
1911062SN/A
1921062SN/A    iqFloatInstsIssued
1932301SN/A        .name(name() + ".iqFloatInstsIssued")
1942301SN/A        .desc("Number of float instructions issued")
1952301SN/A        .prereq(iqFloatInstsIssued);
1962301SN/A
1971062SN/A    iqBranchInstsIssued
1981062SN/A        .name(name() + ".iqBranchInstsIssued")
1991062SN/A        .desc("Number of branch instructions issued")
2001062SN/A        .prereq(iqBranchInstsIssued);
2011062SN/A
2021062SN/A    iqMemInstsIssued
2031062SN/A        .name(name() + ".iqMemInstsIssued")
2041062SN/A        .desc("Number of memory instructions issued")
2051062SN/A        .prereq(iqMemInstsIssued);
2061062SN/A
2071062SN/A    iqMiscInstsIssued
2081062SN/A        .name(name() + ".iqMiscInstsIssued")
2091062SN/A        .desc("Number of miscellaneous instructions issued")
2101062SN/A        .prereq(iqMiscInstsIssued);
2111062SN/A
2121062SN/A    iqSquashedInstsIssued
2131062SN/A        .name(name() + ".iqSquashedInstsIssued")
2141062SN/A        .desc("Number of squashed instructions issued")
2151062SN/A        .prereq(iqSquashedInstsIssued);
2161062SN/A
2171062SN/A    iqSquashedInstsExamined
2181062SN/A        .name(name() + ".iqSquashedInstsExamined")
2191062SN/A        .desc("Number of squashed instructions iterated over during squash;"
2201062SN/A              " mainly for profiling")
2211062SN/A        .prereq(iqSquashedInstsExamined);
2221062SN/A
2231062SN/A    iqSquashedOperandsExamined
2241062SN/A        .name(name() + ".iqSquashedOperandsExamined")
2251062SN/A        .desc("Number of squashed operands that are examined and possibly "
2261062SN/A              "removed from graph")
2271062SN/A        .prereq(iqSquashedOperandsExamined);
2281062SN/A
2291062SN/A    iqSquashedNonSpecRemoved
2301062SN/A        .name(name() + ".iqSquashedNonSpecRemoved")
2311062SN/A        .desc("Number of squashed non-spec instructions that were removed")
2321062SN/A        .prereq(iqSquashedNonSpecRemoved);
2331062SN/A
2341062SN/A    queueResDist
2351062SN/A        .init(Num_OpClasses, 0, 99, 2)
2361062SN/A        .name(name() + ".IQ:residence:")
2371062SN/A        .desc("cycles from dispatch to issue")
2381062SN/A        .flags(total | pdf | cdf )
2391062SN/A        ;
2401062SN/A    for (int i = 0; i < Num_OpClasses; ++i) {
2411062SN/A        queueResDist.subname(i, opClassStrings[i]);
2421062SN/A    }
2431062SN/A    numIssuedDist
2442361SN/A        .init(0,totalWidth,1)
2452326SN/A        .name(name() + ".ISSUE:issued_per_cycle")
2462301SN/A        .desc("Number of insts issued each cycle")
2472301SN/A        .flags(pdf)
2482301SN/A        ;
2492301SN/A/*
2502301SN/A    dist_unissued
2512301SN/A        .init(Num_OpClasses+2)
2522326SN/A        .name(name() + ".ISSUE:unissued_cause")
2532301SN/A        .desc("Reason ready instruction not issued")
2542361SN/A        .flags(pdf | dist)
2552326SN/A        ;
2562307SN/A    for (int i=0; i < (Num_OpClasses + 2); ++i) {
2578240Snate@binkert.org        dist_unissued.subname(i, unissued_names[i]);
2582301SN/A    }
2592307SN/A*/
2602301SN/A    statIssuedInstType
2612301SN/A        .init(numThreads,Num_OpClasses)
2622301SN/A        .name(name() + ".ISSUE:FU_type")
2632301SN/A        .desc("Type of FU issued")
2648240Snate@binkert.org        .flags(total | pdf | dist)
2652301SN/A        ;
2662301SN/A    statIssuedInstType.ysubnames(opClassStrings);
2672301SN/A
2682301SN/A    //
2692301SN/A    //  How long did instructions for a particular FU type wait prior to issue
2702301SN/A    //
2712301SN/A
2722326SN/A    issueDelayDist
2734762Snate@binkert.org        .init(Num_OpClasses,0,99,2)
2748240Snate@binkert.org        .name(name() + ".ISSUE:")
2752301SN/A        .desc("cycles from operands ready to issue")
2762301SN/A        .flags(pdf | cdf)
2772301SN/A        ;
2784762Snate@binkert.org
2792301SN/A    for (int i=0; i<Num_OpClasses; ++i) {
2802301SN/A        std::stringstream subname;
2812301SN/A        subname << opClassStrings[i] << "_delay";
2822301SN/A        issueDelayDist.subname(i, subname.str());
2832361SN/A    }
2842326SN/A
2852301SN/A    issueRate
2868240Snate@binkert.org        .name(name() + ".ISSUE:rate")
2872301SN/A        .desc("Inst issue rate")
2882301SN/A        .flags(total)
2892301SN/A        ;
2902301SN/A    issueRate = iqInstsIssued / cpu->numCycles;
2912301SN/A
2922980Sgblack@eecs.umich.edu    statFuBusy
2932301SN/A        .init(Num_OpClasses)
2942326SN/A        .name(name() + ".ISSUE:fu_full")
2952301SN/A        .desc("attempts to use FU when none available")
2962361SN/A        .flags(pdf | dist)
2972326SN/A        ;
2988240Snate@binkert.org    for (int i=0; i < Num_OpClasses; ++i) {
2992301SN/A        statFuBusy.subname(i, opClassStrings[i]);
3002301SN/A    }
3012301SN/A
3022326SN/A    fuBusy
3032727Sktlim@umich.edu        .init(numThreads)
3042326SN/A        .name(name() + ".ISSUE:fu_busy_cnt")
3052301SN/A        .desc("FU busy when requested")
3068240Snate@binkert.org        .flags(total)
3072301SN/A        ;
3082301SN/A
3092301SN/A    fuBusyRate
3102301SN/A        .name(name() + ".ISSUE:fu_busy_rate")
3114762Snate@binkert.org        .desc("FU busy rate (busy events/executed inst)")
3122301SN/A        .flags(total)
3132301SN/A        ;
3142326SN/A    fuBusyRate = fuBusy / iqInstsIssued;
3152301SN/A
3168240Snate@binkert.org    for ( int i=0; i < numThreads; i++) {
3172301SN/A        // Tell mem dependence unit to reg stats as well.
3182301SN/A        memDepUnit[i].regStats();
3192301SN/A    }
3202301SN/A}
3212326SN/A
3228240Snate@binkert.orgtemplate <class Impl>
3232301SN/Avoid
3242301SN/AInstructionQueue<Impl>::resetState()
3252301SN/A{
3262326SN/A    //Initialize thread IQ counts
3272301SN/A    for (int i = 0; i <numThreads; i++) {
3286221Snate@binkert.org        count[i] = 0;
3292292SN/A        instList[i].clear();
3306221Snate@binkert.org    }
3312292SN/A
3327897Shestness@cs.utexas.edu    // Initialize the number of free IQ entries.
3337897Shestness@cs.utexas.edu    freeEntries = numEntries;
3347897Shestness@cs.utexas.edu
3357897Shestness@cs.utexas.edu    // Note that in actuality, the registers corresponding to the logical
3367897Shestness@cs.utexas.edu    // registers start off as ready.  However this doesn't matter for the
3377897Shestness@cs.utexas.edu    // IQ as the instruction should have been correctly told if those
3387897Shestness@cs.utexas.edu    // registers are ready in rename.  Thus it can all be initialized as
3397897Shestness@cs.utexas.edu    // unready.
3407897Shestness@cs.utexas.edu    for (int i = 0; i < numPhysRegs; ++i) {
3417897Shestness@cs.utexas.edu        regScoreboard[i] = false;
3427897Shestness@cs.utexas.edu    }
3437897Shestness@cs.utexas.edu
3447897Shestness@cs.utexas.edu    for (int i = 0; i < numThreads; ++i) {
3457897Shestness@cs.utexas.edu        squashedSeqNum[i] = 0;
3467897Shestness@cs.utexas.edu    }
3477897Shestness@cs.utexas.edu
3487897Shestness@cs.utexas.edu    for (int i = 0; i < Num_OpClasses; ++i) {
3497897Shestness@cs.utexas.edu        while (!readyInsts[i].empty())
3507897Shestness@cs.utexas.edu            readyInsts[i].pop();
3517897Shestness@cs.utexas.edu        queueOnList[i] = false;
3527897Shestness@cs.utexas.edu        readyIt[i] = listOrder.end();
3537897Shestness@cs.utexas.edu    }
3547897Shestness@cs.utexas.edu    nonSpecInsts.clear();
3557897Shestness@cs.utexas.edu    listOrder.clear();
3567897Shestness@cs.utexas.edu}
3577897Shestness@cs.utexas.edu
35812110SRekai.GonzalezAlberquilla@arm.comtemplate <class Impl>
3597897Shestness@cs.utexas.eduvoid
3607897Shestness@cs.utexas.eduInstructionQueue<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
3617897Shestness@cs.utexas.edu{
3627897Shestness@cs.utexas.edu    DPRINTF(IQ, "Setting active threads list pointer.\n");
36312319Sandreas.sandberg@arm.com    activeThreads = at_ptr;
36412319Sandreas.sandberg@arm.com}
36512319Sandreas.sandberg@arm.com
36612319Sandreas.sandberg@arm.comtemplate <class Impl>
36712319Sandreas.sandberg@arm.comvoid
36812319Sandreas.sandberg@arm.comInstructionQueue<Impl>::setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2e_ptr)
36912319Sandreas.sandberg@arm.com{
37012319Sandreas.sandberg@arm.com    DPRINTF(IQ, "Set the issue to execute queue.\n");
37112319Sandreas.sandberg@arm.com    issueToExecuteQueue = i2e_ptr;
37212319Sandreas.sandberg@arm.com}
37312319Sandreas.sandberg@arm.com
37412319Sandreas.sandberg@arm.comtemplate <class Impl>
37512319Sandreas.sandberg@arm.comvoid
37612319Sandreas.sandberg@arm.comInstructionQueue<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
37712319Sandreas.sandberg@arm.com{
3787897Shestness@cs.utexas.edu    DPRINTF(IQ, "Set the time buffer.\n");
3797897Shestness@cs.utexas.edu    timeBuffer = tb_ptr;
3807897Shestness@cs.utexas.edu
3817897Shestness@cs.utexas.edu    fromCommit = timeBuffer->getWire(-commitToIEWDelay);
3827897Shestness@cs.utexas.edu}
3837897Shestness@cs.utexas.edu
3847897Shestness@cs.utexas.edutemplate <class Impl>
3857897Shestness@cs.utexas.eduvoid
3867897Shestness@cs.utexas.eduInstructionQueue<Impl>::switchOut()
3877897Shestness@cs.utexas.edu{
38812319Sandreas.sandberg@arm.com    resetState();
38912319Sandreas.sandberg@arm.com    dependGraph.reset();
39012319Sandreas.sandberg@arm.com    switchedOut = true;
39112319Sandreas.sandberg@arm.com    for (int i = 0; i < numThreads; ++i) {
39212319Sandreas.sandberg@arm.com        memDepUnit[i].switchOut();
3931062SN/A    }
3941062SN/A}
3951062SN/A
3961062SN/Atemplate <class Impl>
3972307SN/Avoid
3981060SN/AInstructionQueue<Impl>::takeOverFrom()
3992307SN/A{
40013453Srekai.gonzalezalberquilla@arm.com    switchedOut = false;
4016221Snate@binkert.org}
4026221Snate@binkert.org
4032307SN/Atemplate <class Impl>
4041060SN/Aint
4052307SN/AInstructionQueue<Impl>::entryAmount(int num_threads)
4062307SN/A{
4072307SN/A    if (iqPolicy == Partitioned) {
4082307SN/A        return numEntries / num_threads;
4092307SN/A    } else {
4102307SN/A        return 0;
4112307SN/A    }
4122307SN/A}
4132307SN/A
4142307SN/A
4152307SN/Atemplate <class Impl>
4162307SN/Avoid
41713453Srekai.gonzalezalberquilla@arm.comInstructionQueue<Impl>::resetEntries()
4186221Snate@binkert.org{
4192307SN/A    if (iqPolicy != Dynamic || numThreads > 1) {
4202307SN/A        int active_threads = (*activeThreads).size();
4212307SN/A
4222307SN/A        std::list<unsigned>::iterator threads  = (*activeThreads).begin();
4232307SN/A        std::list<unsigned>::iterator list_end = (*activeThreads).end();
4242307SN/A
4252307SN/A        while (threads != list_end) {
4262307SN/A            if (iqPolicy == Partitioned) {
4272307SN/A                maxEntries[*threads++] = numEntries / active_threads;
4282307SN/A            } else if(iqPolicy == Threshold && active_threads == 1) {
4297944SGiacomo.Gabrielli@arm.com                maxEntries[*threads++] = numEntries;
43010333Smitch.hayenga@arm.com            }
43110333Smitch.hayenga@arm.com        }
43210511Smitch.hayenga@arm.com    }
4331060SN/A}
4341060SN/A
4351061SN/Atemplate <class Impl>
4361060SN/Aunsigned
4376221Snate@binkert.orgInstructionQueue<Impl>::numFreeEntries()
4381060SN/A{
4392292SN/A    return freeEntries;
4402064SN/A}
4412064SN/A
4422064SN/Atemplate <class Impl>
4432064SN/Aunsigned
4442292SN/AInstructionQueue<Impl>::numFreeEntries(unsigned tid)
4452064SN/A{
4464318Sktlim@umich.edu    return maxEntries[tid] - count[tid];
4471060SN/A}
4481060SN/A
4491061SN/A// Might want to do something more complex if it knows how many instructions
4501060SN/A// will be issued this cycle.
4511060SN/Atemplate <class Impl>
4521060SN/Abool
4531060SN/AInstructionQueue<Impl>::isFull()
4541060SN/A{
4551060SN/A    if (freeEntries == 0) {
4561060SN/A        return(true);
4571060SN/A    } else {
4581684SN/A        return(false);
45910510Smitch.hayenga@arm.com    }
46010510Smitch.hayenga@arm.com}
46110510Smitch.hayenga@arm.com
46210511Smitch.hayenga@arm.comtemplate <class Impl>
46310511Smitch.hayenga@arm.combool
46410511Smitch.hayenga@arm.comInstructionQueue<Impl>::isFull(unsigned tid)
46510510Smitch.hayenga@arm.com{
46610510Smitch.hayenga@arm.com    if (numFreeEntries(tid) == 0) {
46710510Smitch.hayenga@arm.com        return(true);
46810510Smitch.hayenga@arm.com    } else {
46910510Smitch.hayenga@arm.com        return(false);
47010510Smitch.hayenga@arm.com    }
47110510Smitch.hayenga@arm.com}
4722307SN/A
4739444SAndreas.Sandberg@ARM.comtemplate <class Impl>
4742307SN/Abool
4759444SAndreas.Sandberg@ARM.comInstructionQueue<Impl>::hasReadyInsts()
4769444SAndreas.Sandberg@ARM.com{
4779444SAndreas.Sandberg@ARM.com    if (!listOrder.empty()) {
4789444SAndreas.Sandberg@ARM.com        return true;
4792307SN/A    }
4802307SN/A
4812307SN/A    for (int i = 0; i < Num_OpClasses; ++i) {
4822307SN/A        if (!readyInsts[i].empty()) {
4832307SN/A            return true;
4842307SN/A        }
4859444SAndreas.Sandberg@ARM.com    }
4862307SN/A
4872307SN/A    return false;
4882307SN/A}
4892292SN/A
4906221Snate@binkert.orgtemplate <class Impl>
4912292SN/Avoid
49213561Snikos.nikoleris@arm.comInstructionQueue<Impl>::insert(DynInstPtr &new_inst)
4932292SN/A{
4942292SN/A    // Make sure the instruction is valid
4952292SN/A    assert(new_inst);
4962292SN/A
4972292SN/A    DPRINTF(IQ, "Adding instruction [sn:%lli] PC %#x to the IQ.\n",
4982292SN/A            new_inst->seqNum, new_inst->readPC());
4992292SN/A
5002292SN/A    assert(freeEntries != 0);
5012292SN/A
5022292SN/A    instList[new_inst->threadNumber].push_back(new_inst);
5032292SN/A
50413561Snikos.nikoleris@arm.com    --freeEntries;
5053867Sbinkertn@umich.edu
5062292SN/A    new_inst->setInIQ();
5076221Snate@binkert.org
5086221Snate@binkert.org    // Look through its source registers (physical regs), and mark any
5092292SN/A    // dependencies.
5103867Sbinkertn@umich.edu    addToDependents(new_inst);
5116221Snate@binkert.org
5123867Sbinkertn@umich.edu    // Have this instruction set itself as the producer of its destination
51313561Snikos.nikoleris@arm.com    // register(s).
5143867Sbinkertn@umich.edu    addToProducers(new_inst);
51513561Snikos.nikoleris@arm.com
51613561Snikos.nikoleris@arm.com    if (new_inst->isMemRef()) {
5173867Sbinkertn@umich.edu        memDepUnit[new_inst->threadNumber].insert(new_inst);
5182292SN/A    } else {
5192292SN/A        addIfReady(new_inst);
5202292SN/A    }
5212292SN/A
5222292SN/A    ++iqInstsAdded;
5232292SN/A
5241684SN/A    count[new_inst->threadNumber]++;
5251684SN/A
5261684SN/A    assert(freeEntries == (numEntries - countInsts()));
5271684SN/A}
5281684SN/A
5291684SN/Atemplate <class Impl>
5302292SN/Avoid
5312292SN/AInstructionQueue<Impl>::insertNonSpec(DynInstPtr &new_inst)
5326221Snate@binkert.org{
5332292SN/A    // @todo: Clean up this code; can do it by setting inst as unable
5342292SN/A    // to issue, then calling normal insert on the inst.
5352292SN/A
5362292SN/A    assert(new_inst);
5371060SN/A
5381060SN/A    nonSpecInsts[new_inst->seqNum] = new_inst;
5391061SN/A
5401060SN/A    DPRINTF(IQ, "Adding non-speculative instruction [sn:%lli] PC %#x "
5411060SN/A            "to the IQ.\n",
5421060SN/A            new_inst->seqNum, new_inst->readPC());
5431060SN/A
5441060SN/A    assert(freeEntries != 0);
5451060SN/A
5461060SN/A    instList[new_inst->threadNumber].push_back(new_inst);
5471060SN/A
5481060SN/A    --freeEntries;
5491060SN/A
5501061SN/A    new_inst->setInIQ();
5512292SN/A
5526221Snate@binkert.org    // Have this instruction set itself as the producer of its destination
5532292SN/A    // register(s).
5542292SN/A    addToProducers(new_inst);
5552292SN/A
5562292SN/A    // If it's a memory instruction, add it to the memory dependency
5572292SN/A    // unit.
5582292SN/A    if (new_inst->isMemRef()) {
5592292SN/A        memDepUnit[new_inst->threadNumber].insertNonSpec(new_inst);
5602292SN/A    }
5612292SN/A
5622292SN/A    ++iqNonSpecInstsAdded;
5632292SN/A
5642292SN/A    count[new_inst->threadNumber]++;
5652292SN/A
5662292SN/A    assert(freeEntries == (numEntries - countInsts()));
5672292SN/A}
5682292SN/A
5692292SN/Atemplate <class Impl>
5702292SN/Avoid
5712292SN/AInstructionQueue<Impl>::insertBarrier(DynInstPtr &barr_inst)
5722292SN/A{
5732292SN/A    memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst);
5742292SN/A
5752292SN/A    insertNonSpec(barr_inst);
5762292SN/A}
5772292SN/A
5782292SN/Atemplate <class Impl>
5791060SN/Atypename Impl::DynInstPtr
58013429Srekai.gonzalezalberquilla@arm.comInstructionQueue<Impl>::getInstToExecute()
5811060SN/A{
58212110SRekai.GonzalezAlberquilla@arm.com    assert(!instsToExecute.empty());
58312110SRekai.GonzalezAlberquilla@arm.com    DynInstPtr inst = instsToExecute.front();
58412110SRekai.GonzalezAlberquilla@arm.com    instsToExecute.pop_front();
58512110SRekai.GonzalezAlberquilla@arm.com    return inst;
58612110SRekai.GonzalezAlberquilla@arm.com}
58712110SRekai.GonzalezAlberquilla@arm.com
58812110SRekai.GonzalezAlberquilla@arm.comtemplate <class Impl>
5891060SN/Avoid
5901060SN/AInstructionQueue<Impl>::addToOrderList(OpClass op_class)
5911060SN/A{
5927720Sgblack@eecs.umich.edu    assert(!readyInsts[op_class].empty());
5937720Sgblack@eecs.umich.edu
5941060SN/A    ListOrderEntry queue_entry;
5951060SN/A
5961060SN/A    queue_entry.queueType = op_class;
5972292SN/A
5981060SN/A    queue_entry.oldestInst = readyInsts[op_class].top()->seqNum;
5992064SN/A
6001060SN/A    ListOrderIt list_it = listOrder.begin();
6012292SN/A    ListOrderIt list_end_it = listOrder.end();
6021060SN/A
6031060SN/A    while (list_it != list_end_it) {
6041060SN/A        if ((*list_it).oldestInst > queue_entry.oldestInst) {
6051060SN/A            break;
6061060SN/A        }
6071060SN/A
6081060SN/A        list_it++;
6092326SN/A    }
6101060SN/A
6111061SN/A    readyIt[op_class] = listOrder.insert(list_it, queue_entry);
6122292SN/A    queueOnList[op_class] = true;
6131062SN/A}
6141062SN/A
6151061SN/Atemplate <class Impl>
6161061SN/Avoid
6171062SN/AInstructionQueue<Impl>::moveToYoungerInst(ListOrderIt list_order_it)
6181060SN/A{
6192292SN/A    // Get iterator of next item on the list
6202292SN/A    // Delete the original iterator
6211060SN/A    // Determine if the next item is either the end of the list or younger
6221060SN/A    // than the new instruction.  If so, then add in a new iterator right here.
6231060SN/A    // If not, then move along.
6241061SN/A    ListOrderEntry queue_entry;
6251061SN/A    OpClass op_class = (*list_order_it).queueType;
62613429Srekai.gonzalezalberquilla@arm.com    ListOrderIt next_it = list_order_it;
6271061SN/A
6281061SN/A    ++next_it;
6291061SN/A
63012110SRekai.GonzalezAlberquilla@arm.com    queue_entry.queueType = op_class;
63112110SRekai.GonzalezAlberquilla@arm.com    queue_entry.oldestInst = readyInsts[op_class].top()->seqNum;
63212110SRekai.GonzalezAlberquilla@arm.com
63312110SRekai.GonzalezAlberquilla@arm.com    while (next_it != listOrder.end() &&
63412110SRekai.GonzalezAlberquilla@arm.com           (*next_it).oldestInst < queue_entry.oldestInst) {
63512110SRekai.GonzalezAlberquilla@arm.com        ++next_it;
63612110SRekai.GonzalezAlberquilla@arm.com    }
6371061SN/A
6382292SN/A    readyIt[op_class] = listOrder.insert(next_it, queue_entry);
6391061SN/A}
6402292SN/A
6411061SN/Atemplate <class Impl>
6427720Sgblack@eecs.umich.eduvoid
6432326SN/AInstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx)
6447720Sgblack@eecs.umich.edu{
6452064SN/A    // The CPU could have been sleeping until this op completed (*extremely*
6461061SN/A    // long latency op).  Wake it if it was.  This may be overkill.
6471061SN/A    if (isSwitchedOut()) {
6482292SN/A        return;
6491061SN/A    }
6502064SN/A
6511061SN/A    iewStage->wakeCPU();
6522292SN/A
6531061SN/A    if (fu_idx > -1)
6541061SN/A        fuPool->freeUnitNextCycle(fu_idx);
6551061SN/A
6562326SN/A    // @todo: Ensure that these FU Completions happen at the beginning
6571061SN/A    // of a cycle, otherwise they could add too many instructions to
6581061SN/A    // the queue.
6591061SN/A    issueToExecuteQueue->access(0)->size++;
6602292SN/A    instsToExecute.push_back(inst);
6612292SN/A}
6621061SN/A
6631062SN/A// @todo: Figure out a better way to remove the squashed items from the
6641062SN/A// lists.  Checking the top item of each list to see if it's squashed
6652292SN/A// wastes time and forces jumps.
6662292SN/Atemplate <class Impl>
6672292SN/Avoid
6682292SN/AInstructionQueue<Impl>::scheduleReadyInsts()
6691061SN/A{
6701061SN/A    DPRINTF(IQ, "Attempting to schedule ready instructions from "
6711061SN/A            "the IQ.\n");
6721060SN/A
67313429Srekai.gonzalezalberquilla@arm.com    IssueStruct *i2e_info = issueToExecuteQueue->access(0);
6741060SN/A
6752292SN/A    // Have iterator to head of the list
6761060SN/A    // While I haven't exceeded bandwidth or reached the end of the list,
6772292SN/A    // Try to get a FU that can do what this op needs.
6782292SN/A    // If successful, change the oldestInst to the new top of the list, put
6791060SN/A    // the queue in the proper place in the list.
6802064SN/A    // Increment the iterator.
6812333SN/A    // This will avoid trying to schedule a certain op class if there are no
6822333SN/A    // FUs that handle it.
6832333SN/A    ListOrderIt order_it = listOrder.begin();
6842333SN/A    ListOrderIt order_end_it = listOrder.end();
68513429Srekai.gonzalezalberquilla@arm.com    int total_issued = 0;
6862333SN/A
68712110SRekai.GonzalezAlberquilla@arm.com    while (total_issued < totalWidth &&
6887897Shestness@cs.utexas.edu           iewStage->canIssue() &&
68912110SRekai.GonzalezAlberquilla@arm.com           order_it != order_end_it) {
69012110SRekai.GonzalezAlberquilla@arm.com        OpClass op_class = (*order_it).queueType;
6917897Shestness@cs.utexas.edu
6927897Shestness@cs.utexas.edu        assert(!readyInsts[op_class].empty());
6937897Shestness@cs.utexas.edu
6942333SN/A        DynInstPtr issuing_inst = readyInsts[op_class].top();
6952333SN/A
6961060SN/A        assert(issuing_inst->seqNum == (*order_it).oldestInst);
6972333SN/A
6982064SN/A        if (issuing_inst->isSquashed()) {
6992292SN/A            readyInsts[op_class].pop();
7002292SN/A
7012292SN/A            if (!readyInsts[op_class].empty()) {
7022292SN/A                moveToYoungerInst(order_it);
7032292SN/A            } else {
7042292SN/A                readyIt[op_class] = listOrder.end();
7052292SN/A                queueOnList[op_class] = false;
7062292SN/A            }
7072292SN/A
7082292SN/A            listOrder.erase(order_it++);
7092292SN/A
7102292SN/A            ++iqSquashedInstsIssued;
7112292SN/A
7122292SN/A            continue;
7132292SN/A        }
7142292SN/A
7152292SN/A        int idx = -2;
7162292SN/A        int op_latency = 1;
7172292SN/A        int tid = issuing_inst->threadNumber;
7181060SN/A
7191060SN/A        if (op_class != No_OpClass) {
7202292SN/A            idx = fuPool->getUnit(op_class);
7212292SN/A
7222292SN/A            if (idx > -1) {
7231060SN/A                op_latency = fuPool->getOpLatency(op_class);
7242292SN/A            }
7252292SN/A        }
7262292SN/A
7272292SN/A        // If we have an instruction that doesn't require a FU, or a
7282292SN/A        // valid FU, then schedule for execution.
7292292SN/A        if (idx == -2 || idx != -1) {
7302292SN/A            if (op_latency == 1) {
7312292SN/A                i2e_info->size++;
7322292SN/A                instsToExecute.push_back(issuing_inst);
7332292SN/A
7342292SN/A                // Add the FU onto the list of FU's to be freed next
7352292SN/A                // cycle if we used one.
7362292SN/A                if (idx >= 0)
7372292SN/A                    fuPool->freeUnitNextCycle(idx);
7382292SN/A            } else {
7392292SN/A                int issue_latency = fuPool->getIssueLatency(op_class);
7402292SN/A                // Generate completion event for the FU
7412292SN/A                FUCompletion *execution = new FUCompletion(issuing_inst,
7422292SN/A                                                           idx, this);
7432292SN/A
7442292SN/A                execution->schedule(curTick + cpu->cycles(issue_latency - 1));
7451060SN/A
7461060SN/A                // @todo: Enforce that issue_latency == 1 or op_latency
7472292SN/A                if (issue_latency > 1) {
7481060SN/A                    // If FU isn't pipelined, then it must be freed
7491060SN/A                    // upon the execution completing.
7502292SN/A                    execution->setFreeFU();
7512292SN/A                } else {
75213429Srekai.gonzalezalberquilla@arm.com                    // Add the FU onto the list of FU's to be freed next cycle.
7532292SN/A                    fuPool->freeUnitNextCycle(idx);
7542367SN/A                }
7559444SAndreas.Sandberg@ARM.com            }
7562292SN/A
7572292SN/A            DPRINTF(IQ, "Thread %i: Issuing instruction PC %#x "
75810511Smitch.hayenga@arm.com                    "[sn:%lli]\n",
7592292SN/A                    tid, issuing_inst->readPC(),
7602292SN/A                    issuing_inst->seqNum);
7612326SN/A
7622326SN/A            readyInsts[op_class].pop();
7632292SN/A
7642326SN/A            if (!readyInsts[op_class].empty()) {
7652326SN/A                moveToYoungerInst(order_it);
7662326SN/A            } else {
7675327Smengke97@hotmail.com                readyIt[op_class] = listOrder.end();
7682333SN/A                queueOnList[op_class] = false;
7692292SN/A            }
7702292SN/A
7711061SN/A            issuing_inst->setIssued();
7721061SN/A            ++total_issued;
7731061SN/A
7741061SN/A            if (!issuing_inst->isMemRef()) {
7751060SN/A                // Memory instructions can not be freed from the IQ until they
7761060SN/A                // complete.
7771060SN/A                ++freeEntries;
7782292SN/A                count[tid]--;
7792292SN/A                issuing_inst->clearInIQ();
7801060SN/A            } else {
7811060SN/A                memDepUnit[tid].issue(issuing_inst);
7821060SN/A            }
78310333Smitch.hayenga@arm.com
78413429Srekai.gonzalezalberquilla@arm.com            listOrder.erase(order_it++);
78510333Smitch.hayenga@arm.com            statIssuedInstType[tid][op_class]++;
78610333Smitch.hayenga@arm.com            iewStage->incrWb(issuing_inst->seqNum);
78710333Smitch.hayenga@arm.com        } else {
78810333Smitch.hayenga@arm.com            statFuBusy[op_class]++;
78913429Srekai.gonzalezalberquilla@arm.com            fuBusy[tid]++;
79010333Smitch.hayenga@arm.com            ++order_it;
7917944SGiacomo.Gabrielli@arm.com        }
7927944SGiacomo.Gabrielli@arm.com    }
7932292SN/A
7942292SN/A    numIssuedDist.sample(total_issued);
7952292SN/A    iqInstsIssued+= total_issued;
7962292SN/A
7972292SN/A    // If we issued any instructions, tell the CPU we had activity.
7982292SN/A    if (total_issued) {
7992292SN/A        cpu->activityThisCycle();
8002292SN/A    } else {
80110333Smitch.hayenga@arm.com        DPRINTF(IQ, "Not able to schedule any instructions.\n");
8022292SN/A    }
8032292SN/A}
8041060SN/A
80510333Smitch.hayenga@arm.comtemplate <class Impl>
8062292SN/Avoid
8071060SN/AInstructionQueue<Impl>::scheduleNonSpec(const InstSeqNum &inst)
8082292SN/A{
8091060SN/A    DPRINTF(IQ, "Marking nonspeculative instruction [sn:%lli] as ready "
8102292SN/A            "to execute.\n", inst);
8111060SN/A
81212110SRekai.GonzalezAlberquilla@arm.com    NonSpecMapIt inst_it = nonSpecInsts.find(inst);
81312110SRekai.GonzalezAlberquilla@arm.com
81412110SRekai.GonzalezAlberquilla@arm.com    assert(inst_it != nonSpecInsts.end());
81512110SRekai.GonzalezAlberquilla@arm.com
81612110SRekai.GonzalezAlberquilla@arm.com    unsigned tid = (*inst_it).second->threadNumber;
81712110SRekai.GonzalezAlberquilla@arm.com
81812110SRekai.GonzalezAlberquilla@arm.com    (*inst_it).second->setCanIssue();
8197897Shestness@cs.utexas.edu
8202292SN/A    if (!(*inst_it).second->isMemRef()) {
8211060SN/A        addIfReady((*inst_it).second);
8222292SN/A    } else {
8232292SN/A        memDepUnit[tid].nonSpecInstReady((*inst_it).second);
8241060SN/A    }
8252292SN/A
8262292SN/A    (*inst_it).second = NULL;
8272292SN/A
8282292SN/A    nonSpecInsts.erase(inst_it);
8292292SN/A}
8301060SN/A
8311060SN/Atemplate <class Impl>
8322292SN/Avoid
8331060SN/AInstructionQueue<Impl>::commit(const InstSeqNum &inst, unsigned tid)
8342292SN/A{
8352292SN/A    DPRINTF(IQ, "[tid:%i]: Committing instructions older than [sn:%i]\n",
8362292SN/A            tid,inst);
8371060SN/A
8381060SN/A    ListIt iq_it = instList[tid].begin();
83911365SRekai.GonzalezAlberquilla@arm.com
8409184Sandreas.hansson@arm.com    while (iq_it != instList[tid].end() &&
8416221Snate@binkert.org           (*iq_it)->seqNum <= inst) {
8421060SN/A        ++iq_it;
8432326SN/A        instList[tid].pop_front();
8442326SN/A    }
84512110SRekai.GonzalezAlberquilla@arm.com
84612110SRekai.GonzalezAlberquilla@arm.com    assert(freeEntries == (numEntries - countInsts()));
84712110SRekai.GonzalezAlberquilla@arm.com}
84812110SRekai.GonzalezAlberquilla@arm.com
84912110SRekai.GonzalezAlberquilla@arm.comtemplate <class Impl>
85012110SRekai.GonzalezAlberquilla@arm.comint
85112110SRekai.GonzalezAlberquilla@arm.comInstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
85211365SRekai.GonzalezAlberquilla@arm.com{
8532326SN/A    int dependents = 0;
8541060SN/A
8551060SN/A    DPRINTF(IQ, "Waking dependents of completed instruction.\n");
8561060SN/A
8572348SN/A    assert(!completed_inst->isSquashed());
8582348SN/A
85911365SRekai.GonzalezAlberquilla@arm.com    // Tell the memory dependence unit to wake any dependents on this
8609184Sandreas.hansson@arm.com    // instruction if it is a memory instruction.  Also complete the memory
8612292SN/A    // instruction at this point since we know it executed without issues.
8622333SN/A    // @todo: Might want to rename "completeMemInst" to something that
8631060SN/A    // indicates that it won't need to be replayed, and call this
8642326SN/A    // earlier.  Might not be a big deal.
8652326SN/A    if (completed_inst->isMemRef()) {
8662326SN/A        memDepUnit[completed_inst->threadNumber].wakeDependents(completed_inst);
8672326SN/A        completeMemInst(completed_inst);
8682292SN/A    } else if (completed_inst->isMemBarrier() ||
86910807Snilay@cs.wisc.edu               completed_inst->isWriteBarrier()) {
8702326SN/A        memDepUnit[completed_inst->threadNumber].completeBarrier(completed_inst);
87110511Smitch.hayenga@arm.com    }
8722326SN/A
8732326SN/A    for (int dest_reg_idx = 0;
8741060SN/A         dest_reg_idx < completed_inst->numDestRegs();
8759180Sandreas.hansson@arm.com         dest_reg_idx++)
8769180Sandreas.hansson@arm.com    {
8771060SN/A        PhysRegIndex dest_reg =
87810807Snilay@cs.wisc.edu            completed_inst->renamedDestRegIdx(dest_reg_idx);
8792348SN/A
8802348SN/A        // Special case of uniq or control registers.  They are not
8812326SN/A        // handled by the IQ and thus have no dependency graph entry.
8822292SN/A        // @todo Figure out a cleaner way to handle this.
8832292SN/A        if (dest_reg >= numPhysRegs) {
8842326SN/A            continue;
8852292SN/A        }
8861060SN/A
8871060SN/A        DPRINTF(IQ, "Waking any dependents on register %i.\n",
8887720Sgblack@eecs.umich.edu                (int) dest_reg);
8892292SN/A
8907720Sgblack@eecs.umich.edu        //Go through the dependency chain, marking the registers as
8912292SN/A        //ready within the waiting instructions.
8921060SN/A        DynInstPtr dep_inst = dependGraph.pop(dest_reg);
8932292SN/A
8941061SN/A        while (dep_inst) {
8952292SN/A            DPRINTF(IQ, "Waking up a dependent instruction, PC%#x.\n",
8962292SN/A                    dep_inst->readPC());
8972292SN/A
8982292SN/A            // Might want to give more information to the instruction
8992292SN/A            // so that it knows which of its source registers is
9001060SN/A            // ready.  However that would mean that the dependency
9011060SN/A            // graph entries would need to hold the src_reg_idx.
9022064SN/A            dep_inst->markSrcRegReady();
9032292SN/A
9042064SN/A            addIfReady(dep_inst);
9058471SGiacomo.Gabrielli@arm.com
9069046SAli.Saidi@ARM.com            dep_inst = dependGraph.pop(dest_reg);
9078471SGiacomo.Gabrielli@arm.com
9088471SGiacomo.Gabrielli@arm.com            ++dependents;
9092292SN/A        }
9102292SN/A
9112292SN/A        // Reset the head node now that all of its dependents have
9122292SN/A        // been woken up.
9132301SN/A        assert(dependGraph.empty(dest_reg));
9142731Sktlim@umich.edu        dependGraph.clearInst(dest_reg);
9152292SN/A
9162301SN/A        // Mark the scoreboard as having that register ready.
9172292SN/A        regScoreboard[dest_reg] = true;
9182292SN/A    }
9192292SN/A    return dependents;
9202326SN/A}
9212292SN/A
9222326SN/Atemplate <class Impl>
9232326SN/Avoid
9242292SN/AInstructionQueue<Impl>::addReadyMemInst(DynInstPtr &ready_inst)
9251060SN/A{
9261060SN/A    OpClass op_class = ready_inst->opClass();
9271062SN/A
9282326SN/A    readyInsts[op_class].push(ready_inst);
9292326SN/A
9302307SN/A    // Will need to reorder the list if either a queue is not on the list,
9312348SN/A    // or it has an older instruction than last time.
9328071SAli.Saidi@ARM.com    if (!queueOnList[op_class]) {
9338071SAli.Saidi@ARM.com        addToOrderList(op_class);
9348071SAli.Saidi@ARM.com    } else if (readyInsts[op_class].top()->seqNum  <
93510333Smitch.hayenga@arm.com               (*readyIt[op_class]).oldestInst) {
9362292SN/A        listOrder.erase(readyIt[op_class]);
9372292SN/A        addToOrderList(op_class);
9382292SN/A    }
9392292SN/A
9401060SN/A    DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
9411060SN/A            "the ready list, PC %#x opclass:%i [sn:%lli].\n",
9421061SN/A            ready_inst->readPC(), op_class, ready_inst->seqNum);
9431060SN/A}
9441061SN/A
9451060SN/Atemplate <class Impl>
9462292SN/Avoid
9472292SN/AInstructionQueue<Impl>::rescheduleMemInst(DynInstPtr &resched_inst)
9481062SN/A{
9492292SN/A    memDepUnit[resched_inst->threadNumber].reschedule(resched_inst);
9501060SN/A}
9511061SN/A
9521060SN/Atemplate <class Impl>
9536221Snate@binkert.orgvoid
9542292SN/AInstructionQueue<Impl>::replayMemInst(DynInstPtr &replay_inst)
9554033Sktlim@umich.edu{
9564033Sktlim@umich.edu    memDepUnit[replay_inst->threadNumber].replay(replay_inst);
9571061SN/A}
9581060SN/A
9591062SN/Atemplate <class Impl>
9601062SN/Avoid
9611062SN/AInstructionQueue<Impl>::completeMemInst(DynInstPtr &completed_inst)
9622292SN/A{
9631062SN/A    int tid = completed_inst->threadNumber;
9641060SN/A
9652292SN/A    DPRINTF(IQ, "Completing mem instruction PC:%#x [sn:%lli]\n",
9662292SN/A            completed_inst->readPC(), completed_inst->seqNum);
9671061SN/A
9681060SN/A    ++freeEntries;
9691060SN/A
9701061SN/A    completed_inst->memOpDone = true;
9711061SN/A
9726221Snate@binkert.org    memDepUnit[tid].completed(completed_inst);
9732292SN/A
9742292SN/A    count[tid]--;
9752292SN/A}
9762292SN/A
9772292SN/Atemplate <class Impl>
9782292SN/Avoid
9792292SN/AInstructionQueue<Impl>::violation(DynInstPtr &store,
9802292SN/A                                  DynInstPtr &faulting_load)
9812292SN/A{
9822292SN/A    memDepUnit[store->threadNumber].violation(store, faulting_load);
9832292SN/A}
9842292SN/A
9852292SN/Atemplate <class Impl>
9862292SN/Avoid
9872292SN/AInstructionQueue<Impl>::squash(unsigned tid)
9882292SN/A{
9892301SN/A    DPRINTF(IQ, "[tid:%i]: Starting to squash instructions in "
99013429Srekai.gonzalezalberquilla@arm.com            "the IQ.\n", tid);
9911684SN/A
9922301SN/A    // Read instruction sequence number of last instruction out of the
9932301SN/A    // time buffer.
9947897Shestness@cs.utexas.edu#if THE_ISA == ALPHA_ISA
9957897Shestness@cs.utexas.edu    squashedSeqNum[tid] = fromCommit->commitInfo[tid].doneSeqNum;
99612110SRekai.GonzalezAlberquilla@arm.com#else
99712110SRekai.GonzalezAlberquilla@arm.com    squashedSeqNum[tid] = fromCommit->commitInfo[tid].bdelayDoneSeqNum;
99812110SRekai.GonzalezAlberquilla@arm.com#endif
9997897Shestness@cs.utexas.edu
10007897Shestness@cs.utexas.edu    // Call doSquash if there are insts in the IQ
10017897Shestness@cs.utexas.edu    if (count[tid] > 0) {
10027897Shestness@cs.utexas.edu        doSquash(tid);
10032292SN/A    }
10042292SN/A
10052292SN/A    // Also tell the memory dependence unit to squash.
10061684SN/A    memDepUnit[tid].squash(squashedSeqNum[tid], tid);
10071684SN/A}
10082292SN/A
10092326SN/Atemplate <class Impl>
10102326SN/Avoid
10112326SN/AInstructionQueue<Impl>::doSquash(unsigned tid)
10122326SN/A{
10131684SN/A    // Start at the tail.
10142292SN/A    ListIt squash_it = instList[tid].end();
10152292SN/A    --squash_it;
10162292SN/A
10172292SN/A    DPRINTF(IQ, "[tid:%i]: Squashing until sequence number %i!\n",
10182292SN/A            tid, squashedSeqNum[tid]);
10191684SN/A
10201684SN/A    // Squash any instructions younger than the squashed sequence number
10211684SN/A    // given.
10221684SN/A    while (squash_it != instList[tid].end() &&
10231684SN/A           (*squash_it)->seqNum > squashedSeqNum[tid]) {
10241684SN/A
102512105Snathanael.premillieu@arm.com        DynInstPtr squashed_inst = (*squash_it);
10261684SN/A
10271684SN/A        // Only handle the instruction if it actually is in the IQ and
10281684SN/A        // hasn't already been squashed in the IQ.
10291684SN/A        if (squashed_inst->threadNumber != tid ||
103012105Snathanael.premillieu@arm.com            squashed_inst->isSquashedInIQ()) {
103112105Snathanael.premillieu@arm.com            --squash_it;
103212106SRekai.GonzalezAlberquilla@arm.com            continue;
10331684SN/A        }
10341684SN/A
10351684SN/A        if (!squashed_inst->isIssued() ||
103612105Snathanael.premillieu@arm.com            (squashed_inst->isMemRef() &&
103712106SRekai.GonzalezAlberquilla@arm.com             !squashed_inst->memOpDone)) {
103812106SRekai.GonzalezAlberquilla@arm.com
10391684SN/A            // Remove the instruction from the dependency list.
10402326SN/A            if (!squashed_inst->isNonSpeculative() &&
10412326SN/A                !squashed_inst->isStoreConditional() &&
104212106SRekai.GonzalezAlberquilla@arm.com                !squashed_inst->isMemBarrier() &&
10431684SN/A                !squashed_inst->isWriteBarrier()) {
10442326SN/A
10457599Sminkyu.jeong@arm.com                for (int src_reg_idx = 0;
10467720Sgblack@eecs.umich.edu                     src_reg_idx < squashed_inst->numSrcRegs();
10471684SN/A                     src_reg_idx++)
10481684SN/A                {
10492326SN/A                    PhysRegIndex src_reg =
10502326SN/A                        squashed_inst->renamedSrcRegIdx(src_reg_idx);
10512326SN/A
10522326SN/A                    // Only remove it from the dependency graph if it
10531684SN/A                    // was placed there in the first place.
10542326SN/A
10551684SN/A                    // Instead of doing a linked list traversal, we
105612106SRekai.GonzalezAlberquilla@arm.com                    // can just remove these squashed instructions
10571684SN/A                    // either at issue time, or when the register is
10582301SN/A                    // overwritten.  The only downside to this is it
10591684SN/A                    // leaves more room for error.
10601684SN/A
10612326SN/A                    if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) &&
10622326SN/A                        src_reg < numPhysRegs) {
106312106SRekai.GonzalezAlberquilla@arm.com                        dependGraph.remove(src_reg, squashed_inst);
106412106SRekai.GonzalezAlberquilla@arm.com                    }
10651684SN/A
10661684SN/A
106712106SRekai.GonzalezAlberquilla@arm.com                    ++iqSquashedOperandsExamined;
10681684SN/A                }
10692301SN/A            } else {
10702064SN/A                NonSpecMapIt ns_inst_it =
10712064SN/A                    nonSpecInsts.find(squashed_inst->seqNum);
10722064SN/A                assert(ns_inst_it != nonSpecInsts.end());
10732064SN/A
107413429Srekai.gonzalezalberquilla@arm.com                (*ns_inst_it).second = NULL;
10752064SN/A
10762292SN/A                nonSpecInsts.erase(ns_inst_it);
10772292SN/A
10782292SN/A                ++iqSquashedNonSpecRemoved;
10792292SN/A            }
10802326SN/A
10812326SN/A            // Might want to also clear out the head of the dependency graph.
10822326SN/A
10832326SN/A            // Mark it as squashed within the IQ.
10842326SN/A            squashed_inst->setSquashedInIQ();
10852326SN/A
10862326SN/A            // @todo: Remove this hack where several statuses are set so the
10872326SN/A            // inst will flow through the rest of the pipeline.
10882326SN/A            squashed_inst->setIssued();
10892326SN/A            squashed_inst->setCanCommit();
10902292SN/A            squashed_inst->clearInIQ();
10917720Sgblack@eecs.umich.edu
10927720Sgblack@eecs.umich.edu            //Update Thread IQ Count
10932064SN/A            count[squashed_inst->threadNumber]--;
10942064SN/A
10952064SN/A            ++freeEntries;
10962064SN/A
109713429Srekai.gonzalezalberquilla@arm.com            DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %#x "
10982064SN/A                    "squashed.\n",
10994033Sktlim@umich.edu                    tid, squashed_inst->seqNum, squashed_inst->readPC());
11007944SGiacomo.Gabrielli@arm.com        }
11017944SGiacomo.Gabrielli@arm.com
11029046SAli.Saidi@ARM.com        instList[tid].erase(squash_it--);
11039046SAli.Saidi@ARM.com        ++iqSquashedInstsExamined;
11047944SGiacomo.Gabrielli@arm.com    }
11054033Sktlim@umich.edu}
11062292SN/A
11072064SN/Atemplate <class Impl>
11082064SN/Abool
11092064SN/AInstructionQueue<Impl>::addToDependents(DynInstPtr &new_inst)
11102064SN/A{
111113429Srekai.gonzalezalberquilla@arm.com    // Loop through the instruction's source registers, adding
11122064SN/A    // them to the dependency list if they are not ready.
111310333Smitch.hayenga@arm.com    int8_t total_src_regs = new_inst->numSrcRegs();
11142292SN/A    bool return_val = false;
11152292SN/A
11162292SN/A    for (int src_reg_idx = 0;
11172292SN/A         src_reg_idx < total_src_regs;
111813429Srekai.gonzalezalberquilla@arm.com         src_reg_idx++)
11192292SN/A    {
11206221Snate@binkert.org        // Only add it to the dependency graph if it's not ready.
11212292SN/A        if (!new_inst->isReadySrcRegIdx(src_reg_idx)) {
11227720Sgblack@eecs.umich.edu            PhysRegIndex src_reg = new_inst->renamedSrcRegIdx(src_reg_idx);
11237720Sgblack@eecs.umich.edu
11242292SN/A            // Check the IQ's scoreboard to make sure the register
11252292SN/A            // hasn't become ready while the instruction was in flight
11262292SN/A            // between stages.  Only if it really isn't ready should
11279046SAli.Saidi@ARM.com            // it be added to the dependency graph.
11282292SN/A            if (src_reg >= numPhysRegs) {
11292292SN/A                continue;
11302292SN/A            } else if (regScoreboard[src_reg] == false) {
11311684SN/A                DPRINTF(IQ, "Instruction PC %#x has src reg %i that "
11321684SN/A                        "is being added to the dependency chain.\n",
11331684SN/A                        new_inst->readPC(), src_reg);
11341684SN/A
113513429Srekai.gonzalezalberquilla@arm.com                dependGraph.insert(src_reg, new_inst);
11367944SGiacomo.Gabrielli@arm.com
11377944SGiacomo.Gabrielli@arm.com                // Change the return value to indicate that something
11387944SGiacomo.Gabrielli@arm.com                // was added to the dependency graph.
11397944SGiacomo.Gabrielli@arm.com                return_val = true;
11407944SGiacomo.Gabrielli@arm.com            } else {
114110333Smitch.hayenga@arm.com                DPRINTF(IQ, "Instruction PC %#x has src reg %i that "
114213429Srekai.gonzalezalberquilla@arm.com                        "became ready before it reached the IQ.\n",
114310333Smitch.hayenga@arm.com                        new_inst->readPC(), src_reg);
114410333Smitch.hayenga@arm.com                // Mark a register ready within the instruction.
114510333Smitch.hayenga@arm.com                new_inst->markSrcRegReady(src_reg_idx);
114610333Smitch.hayenga@arm.com            }
114710333Smitch.hayenga@arm.com        }
114810333Smitch.hayenga@arm.com    }
114910333Smitch.hayenga@arm.com
115010333Smitch.hayenga@arm.com    return return_val;
115110333Smitch.hayenga@arm.com}
115210333Smitch.hayenga@arm.com
115310333Smitch.hayenga@arm.comtemplate <class Impl>
115410333Smitch.hayenga@arm.comvoid
115510333Smitch.hayenga@arm.comInstructionQueue<Impl>::addToProducers(DynInstPtr &new_inst)
115610333Smitch.hayenga@arm.com{
115710333Smitch.hayenga@arm.com    // Nothing really needs to be marked when an instruction becomes
115810333Smitch.hayenga@arm.com    // the producer of a register's value, but for convenience a ptr
11597944SGiacomo.Gabrielli@arm.com    // to the producing instruction will be placed in the head node of
11607944SGiacomo.Gabrielli@arm.com    // the dependency links.
11617944SGiacomo.Gabrielli@arm.com    int8_t total_dest_regs = new_inst->numDestRegs();
11627944SGiacomo.Gabrielli@arm.com
11637944SGiacomo.Gabrielli@arm.com    for (int dest_reg_idx = 0;
11649046SAli.Saidi@ARM.com         dest_reg_idx < total_dest_regs;
116513429Srekai.gonzalezalberquilla@arm.com         dest_reg_idx++)
11667944SGiacomo.Gabrielli@arm.com    {
116710333Smitch.hayenga@arm.com        PhysRegIndex dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx);
11687944SGiacomo.Gabrielli@arm.com
11697944SGiacomo.Gabrielli@arm.com        // Instructions that use the misc regs will have a reg number
117010333Smitch.hayenga@arm.com        // higher than the normal physical registers.  In this case these
117110333Smitch.hayenga@arm.com        // registers are not renamed, and there is no need to track
117210333Smitch.hayenga@arm.com        // dependencies as these instructions must be executed at commit.
117310333Smitch.hayenga@arm.com        if (dest_reg >= numPhysRegs) {
117410333Smitch.hayenga@arm.com            continue;
117510333Smitch.hayenga@arm.com        }
117610333Smitch.hayenga@arm.com
117710333Smitch.hayenga@arm.com        if (!dependGraph.empty(dest_reg)) {
117810333Smitch.hayenga@arm.com            dependGraph.dump();
117910333Smitch.hayenga@arm.com            panic("Dependency graph %i not empty!", dest_reg);
118013429Srekai.gonzalezalberquilla@arm.com        }
118110333Smitch.hayenga@arm.com
118210333Smitch.hayenga@arm.com        dependGraph.setInst(dest_reg, new_inst);
118310333Smitch.hayenga@arm.com
11847944SGiacomo.Gabrielli@arm.com        // Mark the scoreboard to say it's not yet ready.
11857944SGiacomo.Gabrielli@arm.com        regScoreboard[dest_reg] = false;
11867944SGiacomo.Gabrielli@arm.com    }
11877944SGiacomo.Gabrielli@arm.com}
118813429Srekai.gonzalezalberquilla@arm.com
118913429Srekai.gonzalezalberquilla@arm.comtemplate <class Impl>
11901061SN/Avoid
11917897Shestness@cs.utexas.eduInstructionQueue<Impl>::addIfReady(DynInstPtr &inst)
11922292SN/A{
11931061SN/A    // If the instruction now has all of its source registers
11941061SN/A    // available, then add it to the list of ready instructions.
11951061SN/A    if (inst->readyToIssue()) {
11961060SN/A
11976221Snate@binkert.org        //Add the instruction to the proper ready list.
11981060SN/A        if (inst->isMemRef()) {
11992292SN/A
12002292SN/A            DPRINTF(IQ, "Checking if memory instruction can issue.\n");
12011060SN/A
12021060SN/A            // Message to the mem dependence unit that this instruction has
12031060SN/A            // its registers ready.
12042292SN/A            memDepUnit[inst->threadNumber].regsReady(inst);
12051060SN/A
120610797Sbrandon.potter@amd.com            return;
12071061SN/A        }
12081061SN/A
12092292SN/A        OpClass op_class = inst->opClass();
12101060SN/A
12111060SN/A        DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
12121061SN/A                "the ready list, PC %#x opclass:%i [sn:%lli].\n",
12131061SN/A                inst->readPC(), op_class, inst->seqNum);
12146221Snate@binkert.org
12151061SN/A        readyInsts[op_class].push(inst);
12162326SN/A
12172326SN/A        // Will need to reorder the list if either a queue is not on the list,
12182326SN/A        // or it has an older instruction than last time.
12191061SN/A        if (!queueOnList[op_class]) {
12202292SN/A            addToOrderList(op_class);
12212292SN/A        } else if (readyInsts[op_class].top()->seqNum  <
12221061SN/A                   (*readyIt[op_class]).oldestInst) {
12231061SN/A            listOrder.erase(readyIt[op_class]);
12241061SN/A            addToOrderList(op_class);
12252326SN/A        }
12262326SN/A    }
12272292SN/A}
12282326SN/A
122912110SRekai.GonzalezAlberquilla@arm.comtemplate <class Impl>
123012110SRekai.GonzalezAlberquilla@arm.comint
123112110SRekai.GonzalezAlberquilla@arm.comInstructionQueue<Impl>::countInsts()
123212110SRekai.GonzalezAlberquilla@arm.com{
123312110SRekai.GonzalezAlberquilla@arm.com#if 0
123412110SRekai.GonzalezAlberquilla@arm.com    //ksewell:This works but definitely could use a cleaner write
123512110SRekai.GonzalezAlberquilla@arm.com    //with a more intuitive way of counting. Right now it's
12361061SN/A    //just brute force ....
12371061SN/A    // Change the #if if you want to use this method.
12381061SN/A    int total_insts = 0;
12392292SN/A
12402292SN/A    for (int i = 0; i < numThreads; ++i) {
12412326SN/A        ListIt count_it = instList[i].begin();
12422292SN/A
12432292SN/A        while (count_it != instList[i].end()) {
12442292SN/A            if (!(*count_it)->isSquashed() && !(*count_it)->isSquashedInIQ()) {
12452292SN/A                if (!(*count_it)->isIssued()) {
12462292SN/A                    ++total_insts;
12479046SAli.Saidi@ARM.com                } else if ((*count_it)->isMemRef() &&
12481062SN/A                           !(*count_it)->memOpDone) {
12497720Sgblack@eecs.umich.edu                    // Loads that have not been marked as executed still count
12507720Sgblack@eecs.umich.edu                    // towards the total instructions.
12512367SN/A                    ++total_insts;
125210032SGiacomo.Gabrielli@arm.com                }
125310032SGiacomo.Gabrielli@arm.com            }
125410032SGiacomo.Gabrielli@arm.com
125510032SGiacomo.Gabrielli@arm.com            ++count_it;
125610032SGiacomo.Gabrielli@arm.com        }
12571061SN/A    }
125810032SGiacomo.Gabrielli@arm.com
125910032SGiacomo.Gabrielli@arm.com    return total_insts;
126010032SGiacomo.Gabrielli@arm.com#else
126110032SGiacomo.Gabrielli@arm.com    return numEntries - freeEntries;
126210032SGiacomo.Gabrielli@arm.com#endif
12631061SN/A}
12641061SN/A
12651681SN/Atemplate <class Impl>
12661061SN/Avoid
12671061SN/AInstructionQueue<Impl>::dumpLists()
126812105Snathanael.premillieu@arm.com{
12691061SN/A    for (int i = 0; i < Num_OpClasses; ++i) {
12701061SN/A        cprintf("Ready list %i size: %i\n", i, readyInsts[i].size());
12712326SN/A
12722326SN/A        cprintf("\n");
12732326SN/A    }
12742326SN/A
12752326SN/A    cprintf("Non speculative list size: %i\n", nonSpecInsts.size());
12762326SN/A
12772326SN/A    NonSpecMapIt non_spec_it = nonSpecInsts.begin();
12782326SN/A    NonSpecMapIt non_spec_end_it = nonSpecInsts.end();
12792292SN/A
12801061SN/A    cprintf("Non speculative list: ");
128112105Snathanael.premillieu@arm.com
128212106SRekai.GonzalezAlberquilla@arm.com    while (non_spec_it != non_spec_end_it) {
128312106SRekai.GonzalezAlberquilla@arm.com        cprintf("%#x [sn:%lli]", (*non_spec_it).second->readPC(),
12841061SN/A                (*non_spec_it).second->seqNum);
12851062SN/A        ++non_spec_it;
12861062SN/A    }
12871061SN/A
128813590Srekai.gonzalezalberquilla@arm.com    cprintf("\n");
12894033Sktlim@umich.edu
12904033Sktlim@umich.edu    ListOrderIt list_order_it = listOrder.begin();
12912292SN/A    ListOrderIt list_order_end_it = listOrder.end();
12922292SN/A    int i = 1;
12938275SAli.Saidi@ARM.com
129410017Sandreas.hansson@arm.com    cprintf("List order: ");
129510017Sandreas.hansson@arm.com
129610017Sandreas.hansson@arm.com    while (list_order_it != list_order_end_it) {
12974033Sktlim@umich.edu        cprintf("%i OpClass:%i [sn:%lli] ", i, (*list_order_it).queueType,
129810017Sandreas.hansson@arm.com                (*list_order_it).oldestInst);
129910017Sandreas.hansson@arm.com
130010017Sandreas.hansson@arm.com        ++list_order_it;
130110017Sandreas.hansson@arm.com        ++i;
130210017Sandreas.hansson@arm.com    }
13034033Sktlim@umich.edu
13041062SN/A    cprintf("\n");
13054033Sktlim@umich.edu}
13061681SN/A
13074033Sktlim@umich.edu
13081062SN/Atemplate <class Impl>
13094033Sktlim@umich.eduvoid
13104033Sktlim@umich.eduInstructionQueue<Impl>::dumpInsts()
13111061SN/A{
13121061SN/A    for (int i = 0; i < numThreads; ++i) {
13131061SN/A        int num = 0;
13141061SN/A        int valid_num = 0;
13151061SN/A        ListIt inst_list_it = instList[i].begin();
13161061SN/A
13171061SN/A        while (inst_list_it != instList[i].end())
13182292SN/A        {
13192292SN/A            cprintf("Instruction:%i\n",
13201681SN/A                    num);
13211681SN/A            if (!(*inst_list_it)->isSquashed()) {
13222731Sktlim@umich.edu                if (!(*inst_list_it)->isIssued()) {
13232292SN/A                    ++valid_num;
13242292SN/A                    cprintf("Count:%i\n", valid_num);
13252292SN/A                } else if ((*inst_list_it)->isMemRef() &&
13261681SN/A                           !(*inst_list_it)->memOpDone) {
13271681SN/A                    // Loads that have not been marked as executed
13281061SN/A                    // still count towards the total instructions.
13291061SN/A                    ++valid_num;
133012833Sjang.hanhwi@gmail.com                    cprintf("Count:%i\n", valid_num);
133112833Sjang.hanhwi@gmail.com                }
133212833Sjang.hanhwi@gmail.com            }
133312833Sjang.hanhwi@gmail.com
133412833Sjang.hanhwi@gmail.com            cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
133512833Sjang.hanhwi@gmail.com                    "Issued:%i\nSquashed:%i\n",
133612833Sjang.hanhwi@gmail.com                    (*inst_list_it)->readPC(),
133712833Sjang.hanhwi@gmail.com                    (*inst_list_it)->seqNum,
133812833Sjang.hanhwi@gmail.com                    (*inst_list_it)->threadNumber,
133912833Sjang.hanhwi@gmail.com                    (*inst_list_it)->isIssued(),
134012833Sjang.hanhwi@gmail.com                    (*inst_list_it)->isSquashed());
134112833Sjang.hanhwi@gmail.com
134212833Sjang.hanhwi@gmail.com            if ((*inst_list_it)->isMemRef()) {
134312833Sjang.hanhwi@gmail.com                cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone);
134412833Sjang.hanhwi@gmail.com            }
134512833Sjang.hanhwi@gmail.com
134612833Sjang.hanhwi@gmail.com            cprintf("\n");
134712833Sjang.hanhwi@gmail.com
134812833Sjang.hanhwi@gmail.com            inst_list_it++;
13492326SN/A            ++num;
13501062SN/A        }
13511061SN/A    }
13521060SN/A
13531060SN/A    cprintf("Insts to Execute list:\n");
13541061SN/A
13551060SN/A    int num = 0;
135613429Srekai.gonzalezalberquilla@arm.com    int valid_num = 0;
13571060SN/A    ListIt inst_list_it = instsToExecute.begin();
13581060SN/A
13591060SN/A    while (inst_list_it != instsToExecute.end())
13601060SN/A    {
13611060SN/A        cprintf("Instruction:%i\n",
13621060SN/A                num);
13631060SN/A        if (!(*inst_list_it)->isSquashed()) {
13641060SN/A            if (!(*inst_list_it)->isIssued()) {
13651060SN/A                ++valid_num;
13661060SN/A                cprintf("Count:%i\n", valid_num);
13671060SN/A            } else if ((*inst_list_it)->isMemRef() &&
13681060SN/A                       !(*inst_list_it)->memOpDone) {
136912105Snathanael.premillieu@arm.com                // Loads that have not been marked as executed
13701060SN/A                // still count towards the total instructions.
13711060SN/A                ++valid_num;
13721060SN/A                cprintf("Count:%i\n", valid_num);
13731060SN/A            }
13741060SN/A        }
137512105Snathanael.premillieu@arm.com
13761061SN/A        cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
137712106SRekai.GonzalezAlberquilla@arm.com                "Issued:%i\nSquashed:%i\n",
137812105Snathanael.premillieu@arm.com                (*inst_list_it)->readPC(),
13791060SN/A                (*inst_list_it)->seqNum,
138012106SRekai.GonzalezAlberquilla@arm.com                (*inst_list_it)->threadNumber,
138112106SRekai.GonzalezAlberquilla@arm.com                (*inst_list_it)->isIssued(),
13821060SN/A                (*inst_list_it)->isSquashed());
138312106SRekai.GonzalezAlberquilla@arm.com
13841060SN/A        if ((*inst_list_it)->isMemRef()) {
13851060SN/A            cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone);
13861060SN/A        }
13871060SN/A
13881060SN/A        cprintf("\n");
138912105Snathanael.premillieu@arm.com
13901060SN/A        inst_list_it++;
139112106SRekai.GonzalezAlberquilla@arm.com        ++num;
139212106SRekai.GonzalezAlberquilla@arm.com    }
13931060SN/A}
13942326SN/A