lsq_impl.hh revision 8232
12810SN/A/*
28856Sandreas.hansson@arm.com * Copyright (c) 2005-2006 The Regents of The University of Michigan
38856Sandreas.hansson@arm.com * All rights reserved.
48856Sandreas.hansson@arm.com *
58856Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68856Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78856Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88856Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98856Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108856Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118856Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128856Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138856Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
142810SN/A * this software without specific prior written permission.
152810SN/A *
162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810SN/A *
282810SN/A * Authors: Korey Sewell
292810SN/A */
302810SN/A
312810SN/A#include <algorithm>
322810SN/A#include <list>
332810SN/A#include <string>
342810SN/A
352810SN/A#include "cpu/o3/lsq.hh"
362810SN/A#include "debug/Fetch.hh"
372810SN/A#include "debug/LSQ.hh"
382810SN/A#include "debug/Writeback.hh"
392810SN/A#include "params/DerivO3CPU.hh"
402810SN/A
414458SN/Ausing namespace std;
424458SN/A
432810SN/Atemplate<class Impl>
442810SN/Avoid
452810SN/ALSQ<Impl>::DcachePort::setPeer(Port *port)
462810SN/A{
472810SN/A    Port::setPeer(port);
482810SN/A
492810SN/A#if FULL_SYSTEM
502810SN/A    // Update the ThreadContext's memory ports (Functional/Virtual
512810SN/A    // Ports)
522810SN/A    lsq->updateMemPorts();
537676Snate@binkert.org#endif
547676Snate@binkert.org}
557676Snate@binkert.org
562810SN/Atemplate <class Impl>
572810SN/ATick
582825SN/ALSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
592810SN/A{
602810SN/A    panic("O3CPU model does not work with atomic mode!");
616215Snate@binkert.org    return curTick();
628232Snate@binkert.org}
638232Snate@binkert.org
645338Sstever@gmail.comtemplate <class Impl>
652810SN/Avoid
662810SN/ALSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
678914Sandreas.hansson@arm.com{
688229Snate@binkert.org    DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.");
695034SN/A}
702811SN/A
718786Sgblack@eecs.umich.edutemplate <class Impl>
724626SN/Avoid
738833Sdam.sunwoo@arm.comLSQ<Impl>::DcachePort::recvStatusChange(Status status)
742810SN/A{
753194SN/A    if (status == RangeChange) {
762810SN/A        if (!snoopRangeSent) {
772810SN/A            snoopRangeSent = true;
782810SN/A            sendStatusChange(Port::RangeChange);
792810SN/A        }
802810SN/A        return;
814628SN/A    }
824628SN/A    panic("O3CPU doesn't expect recvStatusChange callback!");
834628SN/A}
844628SN/A
854628SN/Atemplate <class Impl>
864628SN/Abool
874628SN/ALSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
884628SN/A{
898737Skoansin.tan@gmail.com    if (pkt->isError())
904628SN/A        DPRINTF(LSQ, "Got error packet back for address: %#X\n", pkt->getAddr());
914628SN/A    if (pkt->isResponse()) {
924628SN/A        lsq->thread[pkt->req->threadId()].completeDataAccess(pkt);
934628SN/A    }
944628SN/A    else {
954628SN/A        // must be a snoop
964628SN/A
974628SN/A        // @TODO someday may need to process invalidations in LSQ here
984628SN/A        // to provide stronger consistency model
994628SN/A    }
1004628SN/A    return true;
1014628SN/A}
1024628SN/A
1034628SN/Atemplate <class Impl>
1044628SN/Avoid
1054628SN/ALSQ<Impl>::DcachePort::recvRetry()
1064628SN/A{
1074628SN/A    if (lsq->retryTid == -1)
1084628SN/A    {
1094628SN/A        //Squashed, so drop it
1108737Skoansin.tan@gmail.com        return;
1114628SN/A    }
1128856Sandreas.hansson@arm.com    int curr_retry_tid = lsq->retryTid;
1138856Sandreas.hansson@arm.com    // Speculatively clear the retry Tid.  This will get set again if
1148856Sandreas.hansson@arm.com    // the LSQUnit was unable to complete its access.
1158856Sandreas.hansson@arm.com    lsq->retryTid = -1;
1168856Sandreas.hansson@arm.com    lsq->thread[curr_retry_tid].recvRetry();
1178856Sandreas.hansson@arm.com}
1188856Sandreas.hansson@arm.com
1198856Sandreas.hansson@arm.comtemplate <class Impl>
1208856Sandreas.hansson@arm.comLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
1218922Swilliam.wang@arm.com    : cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this),
1222810SN/A      LQEntries(params->LQEntries),
1238856Sandreas.hansson@arm.com      SQEntries(params->SQEntries),
1242844SN/A      numThreads(params->numThreads),
1258856Sandreas.hansson@arm.com      retryTid(-1)
1268856Sandreas.hansson@arm.com{
1278856Sandreas.hansson@arm.com    dcachePort.snoopRangeSent = false;
1288856Sandreas.hansson@arm.com
1298856Sandreas.hansson@arm.com    //**********************************************/
1308856Sandreas.hansson@arm.com    //************ Handle SMT Parameters ***********/
1318856Sandreas.hansson@arm.com    //**********************************************/
1328856Sandreas.hansson@arm.com    std::string policy = params->smtLSQPolicy;
1338856Sandreas.hansson@arm.com
1348914Sandreas.hansson@arm.com    //Convert string to lowercase
1358856Sandreas.hansson@arm.com    std::transform(policy.begin(), policy.end(), policy.begin(),
1368856Sandreas.hansson@arm.com                   (int(*)(int)) tolower);
1373738SN/A
1384458SN/A    //Figure out fetch policy
1398856Sandreas.hansson@arm.com    if (policy == "dynamic") {
1408975Sandreas.hansson@arm.com        lsqPolicy = Dynamic;
1418922Swilliam.wang@arm.com
1428914Sandreas.hansson@arm.com        maxLQEntries = LQEntries;
1432810SN/A        maxSQEntries = SQEntries;
1448856Sandreas.hansson@arm.com
1458856Sandreas.hansson@arm.com        DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
1468856Sandreas.hansson@arm.com    } else if (policy == "partitioned") {
1478914Sandreas.hansson@arm.com        lsqPolicy = Partitioned;
1488856Sandreas.hansson@arm.com
1498922Swilliam.wang@arm.com        //@todo:make work if part_amt doesnt divide evenly.
1508856Sandreas.hansson@arm.com        maxLQEntries = LQEntries / numThreads;
1513013SN/A        maxSQEntries = SQEntries / numThreads;
1528856Sandreas.hansson@arm.com
1538856Sandreas.hansson@arm.com        DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
1548856Sandreas.hansson@arm.com                "%i entries per LQ | %i entries per SQ",
1558856Sandreas.hansson@arm.com                maxLQEntries,maxSQEntries);
1568856Sandreas.hansson@arm.com    } else if (policy == "threshold") {
1578856Sandreas.hansson@arm.com        lsqPolicy = Threshold;
1588856Sandreas.hansson@arm.com
1598856Sandreas.hansson@arm.com        assert(params->smtLSQThreshold > LQEntries);
1608922Swilliam.wang@arm.com        assert(params->smtLSQThreshold > SQEntries);
1618856Sandreas.hansson@arm.com
1625314SN/A        //Divide up by threshold amount
1632811SN/A        //@todo: Should threads check the max and the total
1648856Sandreas.hansson@arm.com        //amount of the LSQ
1658856Sandreas.hansson@arm.com        maxLQEntries  = params->smtLSQThreshold;
1662810SN/A        maxSQEntries  = params->smtLSQThreshold;
1672810SN/A
1688856Sandreas.hansson@arm.com        DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
1692810SN/A                "%i entries per LQ | %i entries per SQ",
1702810SN/A                maxLQEntries,maxSQEntries);
1718856Sandreas.hansson@arm.com    } else {
1728856Sandreas.hansson@arm.com        assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
1738856Sandreas.hansson@arm.com                    "Partitioned, Threshold}");
1748856Sandreas.hansson@arm.com    }
1753606SN/A
1768914Sandreas.hansson@arm.com    //Initialize LSQs
1778975Sandreas.hansson@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
1788914Sandreas.hansson@arm.com        thread[tid].init(cpu, iew_ptr, params, this,
1792810SN/A                         maxLQEntries, maxSQEntries, tid);
1802810SN/A        thread[tid].setDcachePort(&dcachePort);
1812897SN/A    }
1822897SN/A}
1838856Sandreas.hansson@arm.com
1844458SN/A
1859087Sandreas.hansson@arm.comtemplate<class Impl>
1868856Sandreas.hansson@arm.comstd::string
1872811SN/ALSQ<Impl>::name() const
1882810SN/A{
1898856Sandreas.hansson@arm.com    return iewStage->name() + ".lsq";
1908856Sandreas.hansson@arm.com}
1913338SN/A
1924626SN/Atemplate<class Impl>
1934626SN/Avoid
1944626SN/ALSQ<Impl>::regStats()
1954626SN/A{
1964626SN/A    //Initialize LSQs
1974626SN/A    for (ThreadID tid = 0; tid < numThreads; tid++) {
1984626SN/A        thread[tid].regStats();
1994626SN/A    }
2004628SN/A}
2014628SN/A
2024628SN/Atemplate<class Impl>
2034666SN/Avoid
2044628SN/ALSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
2054628SN/A{
2064628SN/A    activeThreads = at_ptr;
2074628SN/A    assert(activeThreads != 0);
2084628SN/A}
2094628SN/A
2104628SN/Atemplate <class Impl>
2114628SN/Avoid
2124628SN/ALSQ<Impl>::switchOut()
2134628SN/A{
2144628SN/A    for (ThreadID tid = 0; tid < numThreads; tid++) {
2154628SN/A        thread[tid].switchOut();
2167667Ssteve.reinhardt@amd.com    }
2174628SN/A}
2184628SN/A
2194628SN/Atemplate <class Impl>
2207667Ssteve.reinhardt@amd.comvoid
2214628SN/ALSQ<Impl>::takeOverFrom()
2224628SN/A{
2234628SN/A    for (ThreadID tid = 0; tid < numThreads; tid++) {
2244628SN/A        thread[tid].takeOverFrom();
2254628SN/A    }
2264626SN/A}
2276227Snate@binkert.org
2284626SN/Atemplate <class Impl>
2294630SN/Aint
2304630SN/ALSQ<Impl>::entryAmount(ThreadID num_threads)
2314630SN/A{
2329288Sandreas.hansson@arm.com    if (lsqPolicy == Partitioned) {
2339263Smrinmoy.ghosh@arm.com        return LQEntries / num_threads;
2349263Smrinmoy.ghosh@arm.com    } else {
2359263Smrinmoy.ghosh@arm.com        return 0;
2369263Smrinmoy.ghosh@arm.com    }
2379263Smrinmoy.ghosh@arm.com}
2389263Smrinmoy.ghosh@arm.com
2399263Smrinmoy.ghosh@arm.comtemplate <class Impl>
2409288Sandreas.hansson@arm.comvoid
2414630SN/ALSQ<Impl>::resetEntries()
2424626SN/A{
2434626SN/A    if (lsqPolicy != Dynamic || numThreads > 1) {
2444626SN/A        int active_threads = activeThreads->size();
2456122SSteve.Reinhardt@amd.com
2466122SSteve.Reinhardt@amd.com        int maxEntries;
2474626SN/A
2488134SAli.Saidi@ARM.com        if (lsqPolicy == Partitioned) {
2498134SAli.Saidi@ARM.com            maxEntries = LQEntries / active_threads;
2508134SAli.Saidi@ARM.com        } else if (lsqPolicy == Threshold && active_threads == 1) {
2518134SAli.Saidi@ARM.com            maxEntries = LQEntries;
2528134SAli.Saidi@ARM.com        } else {
2532810SN/A            maxEntries = LQEntries;
2542810SN/A        }
2552810SN/A
2562810SN/A        list<ThreadID>::iterator threads  = activeThreads->begin();
2572810SN/A        list<ThreadID>::iterator end = activeThreads->end();
2582810SN/A
2596122SSteve.Reinhardt@amd.com        while (threads != end) {
2606122SSteve.Reinhardt@amd.com            ThreadID tid = *threads++;
2616122SSteve.Reinhardt@amd.com
2622810SN/A            resizeEntries(maxEntries, tid);
2639288Sandreas.hansson@arm.com        }
2642810SN/A    }
2654626SN/A}
2664626SN/A
2672810SN/Atemplate<class Impl>
2682810SN/Avoid
2692810SN/ALSQ<Impl>::removeEntries(ThreadID tid)
2702810SN/A{
2713503SN/A    thread[tid].clearLQ();
2723503SN/A    thread[tid].clearSQ();
2733503SN/A}
2746122SSteve.Reinhardt@amd.com
2756122SSteve.Reinhardt@amd.comtemplate<class Impl>
2766122SSteve.Reinhardt@amd.comvoid
2778883SAli.Saidi@ARM.comLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid)
2786122SSteve.Reinhardt@amd.com{
2798833Sdam.sunwoo@arm.com    thread[tid].resizeLQ(size);
2808833Sdam.sunwoo@arm.com    thread[tid].resizeSQ(size);
2818833Sdam.sunwoo@arm.com}
2826978SLisa.Hsu@amd.com
2832810SN/Atemplate<class Impl>
2842810SN/Avoid
2852810SN/ALSQ<Impl>::tick()
2862810SN/A{
2872810SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
2882810SN/A    list<ThreadID>::iterator end = activeThreads->end();
2892810SN/A
2905999Snate@binkert.org    while (threads != end) {
2912810SN/A        ThreadID tid = *threads++;
2922810SN/A
2932810SN/A        thread[tid].tick();
2942810SN/A    }
2952810SN/A}
2962810SN/A
2975999Snate@binkert.orgtemplate<class Impl>
2982810SN/Avoid
2992810SN/ALSQ<Impl>::insertLoad(DynInstPtr &load_inst)
3002810SN/A{
3012810SN/A    ThreadID tid = load_inst->threadNumber;
3022810SN/A
3032810SN/A    thread[tid].insertLoad(load_inst);
3042810SN/A}
3052810SN/A
3062810SN/Atemplate<class Impl>
3075999Snate@binkert.orgvoid
3082810SN/ALSQ<Impl>::insertStore(DynInstPtr &store_inst)
3092810SN/A{
3102810SN/A    ThreadID tid = store_inst->threadNumber;
3112810SN/A
3122810SN/A    thread[tid].insertStore(store_inst);
3132810SN/A}
3144022SN/A
3152810SN/Atemplate<class Impl>
3162810SN/AFault
3172810SN/ALSQ<Impl>::executeLoad(DynInstPtr &inst)
3182810SN/A{
3192810SN/A    ThreadID tid = inst->threadNumber;
3202810SN/A
3214022SN/A    return thread[tid].executeLoad(inst);
3222810SN/A}
3232810SN/A
3242810SN/Atemplate<class Impl>
3252810SN/AFault
3262810SN/ALSQ<Impl>::executeStore(DynInstPtr &inst)
3272810SN/A{
3284022SN/A    ThreadID tid = inst->threadNumber;
3292810SN/A
3302810SN/A    return thread[tid].executeStore(inst);
3312810SN/A}
3322810SN/A
3332810SN/Atemplate<class Impl>
3342810SN/Avoid
3355999Snate@binkert.orgLSQ<Impl>::writebackStores()
3362810SN/A{
3375999Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
3382810SN/A    list<ThreadID>::iterator end = activeThreads->end();
3392810SN/A
3402810SN/A    while (threads != end) {
3412810SN/A        ThreadID tid = *threads++;
3422810SN/A
3435999Snate@binkert.org        if (numStoresToWB(tid) > 0) {
3442810SN/A            DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
3452810SN/A                "available for Writeback.\n", tid, numStoresToWB(tid));
3465999Snate@binkert.org        }
3472810SN/A
3484626SN/A        thread[tid].writebackStores();
3495999Snate@binkert.org    }
3504626SN/A}
3514626SN/A
3525999Snate@binkert.orgtemplate<class Impl>
3534626SN/Abool
3544626SN/ALSQ<Impl>::violation()
3554626SN/A{
3564626SN/A    /* Answers: Does Anybody Have a Violation?*/
3574626SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
3584626SN/A    list<ThreadID>::iterator end = activeThreads->end();
3595999Snate@binkert.org
3604626SN/A    while (threads != end) {
3614626SN/A        ThreadID tid = *threads++;
3624626SN/A
3634626SN/A        if (thread[tid].violation())
3644626SN/A            return true;
3654626SN/A    }
3665999Snate@binkert.org
3674626SN/A    return false;
3684626SN/A}
3694626SN/A
3704626SN/Atemplate<class Impl>
3715999Snate@binkert.orgint
3724626SN/ALSQ<Impl>::getCount()
3734626SN/A{
3744626SN/A    unsigned total = 0;
3754626SN/A
3764626SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
3774626SN/A    list<ThreadID>::iterator end = activeThreads->end();
3785999Snate@binkert.org
3794626SN/A    while (threads != end) {
3804626SN/A        ThreadID tid = *threads++;
3814626SN/A
3827461Snate@binkert.org        total += getCount(tid);
3834626SN/A    }
3844626SN/A
3854626SN/A    return total;
3864626SN/A}
3874626SN/A
3884626SN/Atemplate<class Impl>
3897461Snate@binkert.orgint
3904626SN/ALSQ<Impl>::numLoads()
3914626SN/A{
3924626SN/A    unsigned total = 0;
3934626SN/A
3944626SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
3954626SN/A    list<ThreadID>::iterator end = activeThreads->end();
3964626SN/A
3974626SN/A    while (threads != end) {
3984626SN/A        ThreadID tid = *threads++;
3994626SN/A
4004626SN/A        total += numLoads(tid);
4014626SN/A    }
4024626SN/A
4034626SN/A    return total;
4044626SN/A}
4054626SN/A
4064626SN/Atemplate<class Impl>
4074626SN/Aint
4084626SN/ALSQ<Impl>::numStores()
4094626SN/A{
4104626SN/A    unsigned total = 0;
4115999Snate@binkert.org
4124626SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
4135999Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
4144626SN/A
4155999Snate@binkert.org    while (threads != end) {
4164626SN/A        ThreadID tid = *threads++;
4172810SN/A
4182810SN/A        total += thread[tid].numStores();
4192810SN/A    }
4202810SN/A
4212810SN/A    return total;
4222810SN/A}
4232810SN/A
4242810SN/Atemplate<class Impl>
4252810SN/Aint
4262810SN/ALSQ<Impl>::numLoadsReady()
4275034SN/A{
4285034SN/A    unsigned total = 0;
4295034SN/A
4303606SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
4312858SN/A    list<ThreadID>::iterator end = activeThreads->end();
4322858SN/A
4339294Sandreas.hansson@arm.com    while (threads != end) {
4349294Sandreas.hansson@arm.com        ThreadID tid = *threads++;
4359294Sandreas.hansson@arm.com
4369294Sandreas.hansson@arm.com        total += thread[tid].numLoadsReady();
4378922Swilliam.wang@arm.com    }
4382810SN/A
4392810SN/A    return total;
4402810SN/A}
4412810SN/A
4426227Snate@binkert.orgtemplate<class Impl>
4436227Snate@binkert.orgunsigned
4442810SN/ALSQ<Impl>::numFreeEntries()
4452810SN/A{
4462810SN/A    unsigned total = 0;
4472810SN/A
4484626SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
4496666Ssteve.reinhardt@amd.com    list<ThreadID>::iterator end = activeThreads->end();
4504626SN/A
4514626SN/A    while (threads != end) {
4528883SAli.Saidi@ARM.com        ThreadID tid = *threads++;
4536122SSteve.Reinhardt@amd.com
4544628SN/A        total += thread[tid].numFreeEntries();
4554628SN/A    }
4564902SN/A
4574628SN/A    return total;
4584628SN/A}
4594628SN/A
4604628SN/Atemplate<class Impl>
4614628SN/Aunsigned
4624902SN/ALSQ<Impl>::numFreeEntries(ThreadID tid)
4634628SN/A{
4644902SN/A    //if (lsqPolicy == Dynamic)
4654902SN/A    //return numFreeEntries();
4664902SN/A    //else
4674628SN/A        return thread[tid].numFreeEntries();
4684628SN/A}
4694628SN/A
4704902SN/Atemplate<class Impl>
4714902SN/Abool
4724902SN/ALSQ<Impl>::isFull()
4734902SN/A{
4744902SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
4754902SN/A    list<ThreadID>::iterator end = activeThreads->end();
4764902SN/A
4774902SN/A    while (threads != end) {
4784628SN/A        ThreadID tid = *threads++;
4792810SN/A
4802810SN/A        if (!(thread[tid].lqFull() || thread[tid].sqFull()))
4812810SN/A            return false;
4822810SN/A    }
4832810SN/A
4842810SN/A    return true;
4852810SN/A}
4862810SN/A
4872810SN/Atemplate<class Impl>
4882810SN/Abool
4892810SN/ALSQ<Impl>::isFull(ThreadID tid)
4902810SN/A{
4912810SN/A    //@todo: Change to Calculate All Entries for
4922810SN/A    //Dynamic Policy
4932810SN/A    if (lsqPolicy == Dynamic)
4942810SN/A        return isFull();
4952810SN/A    else
4962810SN/A        return thread[tid].lqFull() || thread[tid].sqFull();
4979288Sandreas.hansson@arm.com}
4984630SN/A
4992810SN/Atemplate<class Impl>
5004630SN/Abool
5014630SN/ALSQ<Impl>::lqFull()
5022810SN/A{
5032810SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
5042810SN/A    list<ThreadID>::iterator end = activeThreads->end();
5052810SN/A
5062810SN/A    while (threads != end) {
5072810SN/A        ThreadID tid = *threads++;
5082810SN/A
5092810SN/A        if (!thread[tid].lqFull())
5102810SN/A            return false;
5112810SN/A    }
5122810SN/A
5132810SN/A    return true;
5144630SN/A}
5154630SN/A
5164630SN/Atemplate<class Impl>
5179288Sandreas.hansson@arm.combool
5184630SN/ALSQ<Impl>::lqFull(ThreadID tid)
5192810SN/A{
5202810SN/A    //@todo: Change to Calculate All Entries for
5212810SN/A    //Dynamic Policy
5222810SN/A    if (lsqPolicy == Dynamic)
5232810SN/A        return lqFull();
5242810SN/A    else
5252810SN/A        return thread[tid].lqFull();
5262810SN/A}
5274458SN/A
5282810SN/Atemplate<class Impl>
5294458SN/Abool
5302810SN/ALSQ<Impl>::sqFull()
5312810SN/A{
5322810SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
5332810SN/A    list<ThreadID>::iterator end = activeThreads->end();
5342810SN/A
5352810SN/A    while (threads != end) {
5364458SN/A        ThreadID tid = *threads++;
5372810SN/A
5385875Ssteve.reinhardt@amd.com        if (!sqFull(tid))
5395875Ssteve.reinhardt@amd.com            return false;
5405875Ssteve.reinhardt@amd.com    }
5415875Ssteve.reinhardt@amd.com
5425875Ssteve.reinhardt@amd.com    return true;
5432811SN/A}
5443503SN/A
5453503SN/Atemplate<class Impl>
5463503SN/Abool
5474626SN/ALSQ<Impl>::sqFull(ThreadID tid)
5484626SN/A{
5494626SN/A     //@todo: Change to Calculate All Entries for
5504626SN/A    //Dynamic Policy
5518833Sdam.sunwoo@arm.com    if (lsqPolicy == Dynamic)
5523503SN/A        return sqFull();
5538833Sdam.sunwoo@arm.com    else
5548833Sdam.sunwoo@arm.com        return thread[tid].sqFull();
5554626SN/A}
5564626SN/A
5574626SN/Atemplate<class Impl>
5584626SN/Abool
5594626SN/ALSQ<Impl>::isStalled()
5603503SN/A{
5613503SN/A    list<ThreadID>::iterator threads = activeThreads->begin();
5628833Sdam.sunwoo@arm.com    list<ThreadID>::iterator end = activeThreads->end();
5636978SLisa.Hsu@amd.com
5648833Sdam.sunwoo@arm.com    while (threads != end) {
5658833Sdam.sunwoo@arm.com        ThreadID tid = *threads++;
5666978SLisa.Hsu@amd.com
5676978SLisa.Hsu@amd.com        if (!thread[tid].isStalled())
5683503SN/A            return false;
5692810SN/A    }
5702810SN/A
5712810SN/A    return true;
572}
573
574template<class Impl>
575bool
576LSQ<Impl>::isStalled(ThreadID tid)
577{
578    if (lsqPolicy == Dynamic)
579        return isStalled();
580    else
581        return thread[tid].isStalled();
582}
583
584template<class Impl>
585bool
586LSQ<Impl>::hasStoresToWB()
587{
588    list<ThreadID>::iterator threads = activeThreads->begin();
589    list<ThreadID>::iterator end = activeThreads->end();
590
591    while (threads != end) {
592        ThreadID tid = *threads++;
593
594        if (hasStoresToWB(tid))
595            return true;
596    }
597
598    return false;
599}
600
601template<class Impl>
602bool
603LSQ<Impl>::willWB()
604{
605    list<ThreadID>::iterator threads = activeThreads->begin();
606    list<ThreadID>::iterator end = activeThreads->end();
607
608    while (threads != end) {
609        ThreadID tid = *threads++;
610
611        if (willWB(tid))
612            return true;
613    }
614
615    return false;
616}
617
618template<class Impl>
619void
620LSQ<Impl>::dumpInsts()
621{
622    list<ThreadID>::iterator threads = activeThreads->begin();
623    list<ThreadID>::iterator end = activeThreads->end();
624
625    while (threads != end) {
626        ThreadID tid = *threads++;
627
628        thread[tid].dumpInsts();
629    }
630}
631