lsq_impl.hh revision 13560
12292SN/A/*
210333Smitch.hayenga@arm.com * Copyright (c) 2011-2012, 2014 ARM Limited
310239Sbinhpham@cs.rutgers.edu * Copyright (c) 2013 Advanced Micro Devices, Inc.
48707Sandreas.hansson@arm.com * All rights reserved
58707Sandreas.hansson@arm.com *
68707Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
78707Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
88707Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
98707Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
108707Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
118707Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
128707Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
138707Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
148707Sandreas.hansson@arm.com *
152727Sktlim@umich.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan
162292SN/A * All rights reserved.
172292SN/A *
182292SN/A * Redistribution and use in source and binary forms, with or without
192292SN/A * modification, are permitted provided that the following conditions are
202292SN/A * met: redistributions of source code must retain the above copyright
212292SN/A * notice, this list of conditions and the following disclaimer;
222292SN/A * redistributions in binary form must reproduce the above copyright
232292SN/A * notice, this list of conditions and the following disclaimer in the
242292SN/A * documentation and/or other materials provided with the distribution;
252292SN/A * neither the name of the copyright holders nor the names of its
262292SN/A * contributors may be used to endorse or promote products derived from
272292SN/A * this software without specific prior written permission.
282292SN/A *
292292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402689Sktlim@umich.edu *
412689Sktlim@umich.edu * Authors: Korey Sewell
422292SN/A */
432292SN/A
449944Smatt.horsnell@ARM.com#ifndef __CPU_O3_LSQ_IMPL_HH__
459944Smatt.horsnell@ARM.com#define __CPU_O3_LSQ_IMPL_HH__
469944Smatt.horsnell@ARM.com
472329SN/A#include <algorithm>
482980Sgblack@eecs.umich.edu#include <list>
492329SN/A#include <string>
502329SN/A
5113449Sgabeblack@google.com#include "base/logging.hh"
522292SN/A#include "cpu/o3/lsq.hh"
539444SAndreas.Sandberg@ARM.com#include "debug/Drain.hh"
548232Snate@binkert.org#include "debug/Fetch.hh"
558232Snate@binkert.org#include "debug/LSQ.hh"
568232Snate@binkert.org#include "debug/Writeback.hh"
576221Snate@binkert.org#include "params/DerivO3CPU.hh"
582292SN/A
596221Snate@binkert.orgusing namespace std;
605529Snate@binkert.org
612292SN/Atemplate <class Impl>
625529Snate@binkert.orgLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
638707Sandreas.hansson@arm.com    : cpu(cpu_ptr), iewStage(iew_ptr),
6413560Snikos.nikoleris@arm.com      lsqPolicy(params->smtLSQPolicy),
654329Sktlim@umich.edu      LQEntries(params->LQEntries),
664329Sktlim@umich.edu      SQEntries(params->SQEntries),
6713472Srekai.gonzalezalberquilla@arm.com      maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads,
6813472Srekai.gonzalezalberquilla@arm.com                  params->smtLSQThreshold)),
6913472Srekai.gonzalezalberquilla@arm.com      maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads,
7013472Srekai.gonzalezalberquilla@arm.com                  params->smtLSQThreshold)),
7110333Smitch.hayenga@arm.com      numThreads(params->numThreads)
722292SN/A{
739868Sjthestness@gmail.com    assert(numThreads > 0 && numThreads <= Impl::MaxThreads);
749868Sjthestness@gmail.com
752292SN/A    //**********************************************/
762292SN/A    //************ Handle SMT Parameters ***********/
772292SN/A    //**********************************************/
782292SN/A
792292SN/A    //Figure out fetch policy
8013560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Dynamic) {
812292SN/A        DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
8213560Snikos.nikoleris@arm.com    } else if (lsqPolicy == SMTQueuePolicy::Partitioned) {
832292SN/A        DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
848346Sksewell@umich.edu                "%i entries per LQ | %i entries per SQ\n",
852292SN/A                maxLQEntries,maxSQEntries);
8613560Snikos.nikoleris@arm.com    } else if (lsqPolicy == SMTQueuePolicy::Threshold) {
872292SN/A
882292SN/A        assert(params->smtLSQThreshold > LQEntries);
892292SN/A        assert(params->smtLSQThreshold > SQEntries);
902292SN/A
912292SN/A        DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
928346Sksewell@umich.edu                "%i entries per LQ | %i entries per SQ\n",
932292SN/A                maxLQEntries,maxSQEntries);
942292SN/A    } else {
9513449Sgabeblack@google.com        panic("Invalid LSQ sharing policy. Options are: Dynamic, "
9613449Sgabeblack@google.com                    "Partitioned, Threshold");
972292SN/A    }
982292SN/A
9913472Srekai.gonzalezalberquilla@arm.com    thread.reserve(numThreads);
1006221Snate@binkert.org    for (ThreadID tid = 0; tid < numThreads; tid++) {
10113472Srekai.gonzalezalberquilla@arm.com        thread.emplace_back(maxLQEntries, maxSQEntries);
10213472Srekai.gonzalezalberquilla@arm.com        thread[tid].init(cpu, iew_ptr, params, this, tid);
1038850Sandreas.hansson@arm.com        thread[tid].setDcachePort(&cpu_ptr->getDataPort());
1042292SN/A    }
1052292SN/A}
1062292SN/A
1072292SN/A
1082292SN/Atemplate<class Impl>
1092292SN/Astd::string
1102292SN/ALSQ<Impl>::name() const
1112292SN/A{
1122292SN/A    return iewStage->name() + ".lsq";
1132292SN/A}
1142292SN/A
1152292SN/Atemplate<class Impl>
1162292SN/Avoid
1172727Sktlim@umich.eduLSQ<Impl>::regStats()
1182727Sktlim@umich.edu{
1192727Sktlim@umich.edu    //Initialize LSQs
1206221Snate@binkert.org    for (ThreadID tid = 0; tid < numThreads; tid++) {
1212727Sktlim@umich.edu        thread[tid].regStats();
1222727Sktlim@umich.edu    }
1232727Sktlim@umich.edu}
1242727Sktlim@umich.edu
1252727Sktlim@umich.edutemplate<class Impl>
1262727Sktlim@umich.eduvoid
1276221Snate@binkert.orgLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
1282292SN/A{
1292292SN/A    activeThreads = at_ptr;
1302292SN/A    assert(activeThreads != 0);
1312292SN/A}
1322292SN/A
1332292SN/Atemplate <class Impl>
1342307SN/Avoid
1359444SAndreas.Sandberg@ARM.comLSQ<Impl>::drainSanityCheck() const
1362307SN/A{
1379444SAndreas.Sandberg@ARM.com    assert(isDrained());
1389444SAndreas.Sandberg@ARM.com
1399444SAndreas.Sandberg@ARM.com    for (ThreadID tid = 0; tid < numThreads; tid++)
1409444SAndreas.Sandberg@ARM.com        thread[tid].drainSanityCheck();
1419444SAndreas.Sandberg@ARM.com}
1429444SAndreas.Sandberg@ARM.com
1439444SAndreas.Sandberg@ARM.comtemplate <class Impl>
1449444SAndreas.Sandberg@ARM.combool
1459444SAndreas.Sandberg@ARM.comLSQ<Impl>::isDrained() const
1469444SAndreas.Sandberg@ARM.com{
1479444SAndreas.Sandberg@ARM.com    bool drained(true);
1489444SAndreas.Sandberg@ARM.com
1499444SAndreas.Sandberg@ARM.com    if (!lqEmpty()) {
1509444SAndreas.Sandberg@ARM.com        DPRINTF(Drain, "Not drained, LQ not empty.\n");
1519444SAndreas.Sandberg@ARM.com        drained = false;
1522307SN/A    }
1539444SAndreas.Sandberg@ARM.com
1549444SAndreas.Sandberg@ARM.com    if (!sqEmpty()) {
1559444SAndreas.Sandberg@ARM.com        DPRINTF(Drain, "Not drained, SQ not empty.\n");
1569444SAndreas.Sandberg@ARM.com        drained = false;
1579444SAndreas.Sandberg@ARM.com    }
1589444SAndreas.Sandberg@ARM.com
1599444SAndreas.Sandberg@ARM.com    return drained;
1602307SN/A}
1612307SN/A
1622307SN/Atemplate <class Impl>
1632307SN/Avoid
1642307SN/ALSQ<Impl>::takeOverFrom()
1652307SN/A{
1666221Snate@binkert.org    for (ThreadID tid = 0; tid < numThreads; tid++) {
1672307SN/A        thread[tid].takeOverFrom();
1682307SN/A    }
1692307SN/A}
1702307SN/A
1712307SN/Atemplate <class Impl>
1722292SN/Aint
1736221Snate@binkert.orgLSQ<Impl>::entryAmount(ThreadID num_threads)
1742292SN/A{
17513560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Partitioned) {
1762292SN/A        return LQEntries / num_threads;
1772292SN/A    } else {
1782292SN/A        return 0;
1792292SN/A    }
1802292SN/A}
1812292SN/A
1822292SN/Atemplate <class Impl>
1832292SN/Avoid
1842292SN/ALSQ<Impl>::resetEntries()
1852292SN/A{
18613560Snikos.nikoleris@arm.com    if (lsqPolicy != SMTQueuePolicy::Dynamic || numThreads > 1) {
1873867Sbinkertn@umich.edu        int active_threads = activeThreads->size();
1882292SN/A
1892292SN/A        int maxEntries;
1902292SN/A
19113560Snikos.nikoleris@arm.com        if (lsqPolicy == SMTQueuePolicy::Partitioned) {
1922292SN/A            maxEntries = LQEntries / active_threads;
19313560Snikos.nikoleris@arm.com        } else if (lsqPolicy == SMTQueuePolicy::Threshold &&
19413560Snikos.nikoleris@arm.com                   active_threads == 1) {
1952292SN/A            maxEntries = LQEntries;
1962292SN/A        } else {
1972292SN/A            maxEntries = LQEntries;
1982292SN/A        }
1992292SN/A
2006221Snate@binkert.org        list<ThreadID>::iterator threads  = activeThreads->begin();
2016221Snate@binkert.org        list<ThreadID>::iterator end = activeThreads->end();
2023867Sbinkertn@umich.edu
2033867Sbinkertn@umich.edu        while (threads != end) {
2046221Snate@binkert.org            ThreadID tid = *threads++;
2053867Sbinkertn@umich.edu
2063867Sbinkertn@umich.edu            resizeEntries(maxEntries, tid);
2072292SN/A        }
2082292SN/A    }
2092292SN/A}
2102292SN/A
2112292SN/Atemplate<class Impl>
2122292SN/Avoid
2136221Snate@binkert.orgLSQ<Impl>::removeEntries(ThreadID tid)
2142292SN/A{
2152292SN/A    thread[tid].clearLQ();
2162292SN/A    thread[tid].clearSQ();
2172292SN/A}
2182292SN/A
2192292SN/Atemplate<class Impl>
2202292SN/Avoid
2216221Snate@binkert.orgLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid)
2222292SN/A{
2232292SN/A    thread[tid].resizeLQ(size);
2242292SN/A    thread[tid].resizeSQ(size);
2252292SN/A}
2262292SN/A
2272292SN/Atemplate<class Impl>
2282292SN/Avoid
2292292SN/ALSQ<Impl>::tick()
2302292SN/A{
2316221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
2326221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
2332292SN/A
2343867Sbinkertn@umich.edu    while (threads != end) {
2356221Snate@binkert.org        ThreadID tid = *threads++;
2362292SN/A
2372292SN/A        thread[tid].tick();
2382292SN/A    }
2392292SN/A}
2402292SN/A
2412292SN/Atemplate<class Impl>
2422292SN/Avoid
24313429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::insertLoad(const DynInstPtr &load_inst)
2442292SN/A{
2456221Snate@binkert.org    ThreadID tid = load_inst->threadNumber;
2462292SN/A
2472292SN/A    thread[tid].insertLoad(load_inst);
2482292SN/A}
2492292SN/A
2502292SN/Atemplate<class Impl>
2512292SN/Avoid
25213429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::insertStore(const DynInstPtr &store_inst)
2532292SN/A{
2546221Snate@binkert.org    ThreadID tid = store_inst->threadNumber;
2552292SN/A
2562292SN/A    thread[tid].insertStore(store_inst);
2572292SN/A}
2582292SN/A
2592292SN/Atemplate<class Impl>
2602292SN/AFault
26113429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::executeLoad(const DynInstPtr &inst)
2622292SN/A{
2636221Snate@binkert.org    ThreadID tid = inst->threadNumber;
2642292SN/A
2652292SN/A    return thread[tid].executeLoad(inst);
2662292SN/A}
2672292SN/A
2682292SN/Atemplate<class Impl>
2692292SN/AFault
27013429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::executeStore(const DynInstPtr &inst)
2712292SN/A{
2726221Snate@binkert.org    ThreadID tid = inst->threadNumber;
2732292SN/A
2742292SN/A    return thread[tid].executeStore(inst);
2752292SN/A}
2762292SN/A
2772292SN/Atemplate<class Impl>
2782292SN/Avoid
2792292SN/ALSQ<Impl>::writebackStores()
2802292SN/A{
2816221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
2826221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
2832292SN/A
2843867Sbinkertn@umich.edu    while (threads != end) {
2856221Snate@binkert.org        ThreadID tid = *threads++;
2862292SN/A
2872292SN/A        if (numStoresToWB(tid) > 0) {
2882329SN/A            DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
2892329SN/A                "available for Writeback.\n", tid, numStoresToWB(tid));
2902292SN/A        }
2912292SN/A
2922292SN/A        thread[tid].writebackStores();
2932292SN/A    }
2942292SN/A}
2952292SN/A
2962292SN/Atemplate<class Impl>
2972292SN/Abool
2982292SN/ALSQ<Impl>::violation()
2992292SN/A{
3002292SN/A    /* Answers: Does Anybody Have a Violation?*/
3016221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
3026221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
3032292SN/A
3043867Sbinkertn@umich.edu    while (threads != end) {
3056221Snate@binkert.org        ThreadID tid = *threads++;
3063867Sbinkertn@umich.edu
3072292SN/A        if (thread[tid].violation())
3082292SN/A            return true;
3092292SN/A    }
3102292SN/A
3112292SN/A    return false;
3122292SN/A}
3132292SN/A
3148707Sandreas.hansson@arm.comtemplate <class Impl>
3158707Sandreas.hansson@arm.comvoid
31610713Sandreas.hansson@arm.comLSQ<Impl>::recvReqRetry()
3178707Sandreas.hansson@arm.com{
31810333Smitch.hayenga@arm.com    iewStage->cacheUnblocked();
31910333Smitch.hayenga@arm.com
32010333Smitch.hayenga@arm.com    for (ThreadID tid : *activeThreads) {
32110333Smitch.hayenga@arm.com        thread[tid].recvRetry();
3228707Sandreas.hansson@arm.com    }
3238707Sandreas.hansson@arm.com}
3248707Sandreas.hansson@arm.com
3258707Sandreas.hansson@arm.comtemplate <class Impl>
3268707Sandreas.hansson@arm.combool
3278975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingResp(PacketPtr pkt)
3288707Sandreas.hansson@arm.com{
3298707Sandreas.hansson@arm.com    if (pkt->isError())
3308707Sandreas.hansson@arm.com        DPRINTF(LSQ, "Got error packet back for address: %#X\n",
3318707Sandreas.hansson@arm.com                pkt->getAddr());
33210575SMarco.Elver@ARM.com
33311435Smitch.hayenga@arm.com    thread[cpu->contextToThread(pkt->req->contextId())]
33411435Smitch.hayenga@arm.com        .completeDataAccess(pkt);
33510575SMarco.Elver@ARM.com
33610575SMarco.Elver@ARM.com    if (pkt->isInvalidate()) {
33710575SMarco.Elver@ARM.com        // This response also contains an invalidate; e.g. this can be the case
33810575SMarco.Elver@ARM.com        // if cmd is ReadRespWithInvalidate.
33910575SMarco.Elver@ARM.com        //
34010575SMarco.Elver@ARM.com        // The calling order between completeDataAccess and checkSnoop matters.
34110575SMarco.Elver@ARM.com        // By calling checkSnoop after completeDataAccess, we ensure that the
34210575SMarco.Elver@ARM.com        // fault set by checkSnoop is not lost. Calling writeback (more
34310575SMarco.Elver@ARM.com        // specifically inst->completeAcc) in completeDataAccess overwrites
34410575SMarco.Elver@ARM.com        // fault, and in case this instruction requires squashing (as
34510575SMarco.Elver@ARM.com        // determined by checkSnoop), the ReExec fault set by checkSnoop would
34610575SMarco.Elver@ARM.com        // be lost otherwise.
34710575SMarco.Elver@ARM.com
34810575SMarco.Elver@ARM.com        DPRINTF(LSQ, "received invalidation with response for addr:%#x\n",
34910575SMarco.Elver@ARM.com                pkt->getAddr());
35010575SMarco.Elver@ARM.com
35110575SMarco.Elver@ARM.com        for (ThreadID tid = 0; tid < numThreads; tid++) {
35210575SMarco.Elver@ARM.com            thread[tid].checkSnoop(pkt);
35310575SMarco.Elver@ARM.com        }
35410575SMarco.Elver@ARM.com    }
35510575SMarco.Elver@ARM.com
35610573Sstephan.diestelhorst@arm.com    delete pkt;
3578948Sandreas.hansson@arm.com    return true;
3588948Sandreas.hansson@arm.com}
3598707Sandreas.hansson@arm.com
3608948Sandreas.hansson@arm.comtemplate <class Impl>
3618975Sandreas.hansson@arm.comvoid
3628975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt)
3638948Sandreas.hansson@arm.com{
3648948Sandreas.hansson@arm.com    DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
3658948Sandreas.hansson@arm.com            pkt->cmdString());
3668948Sandreas.hansson@arm.com
3678948Sandreas.hansson@arm.com    // must be a snoop
3688948Sandreas.hansson@arm.com    if (pkt->isInvalidate()) {
3698948Sandreas.hansson@arm.com        DPRINTF(LSQ, "received invalidation for addr:%#x\n",
3708948Sandreas.hansson@arm.com                pkt->getAddr());
3718948Sandreas.hansson@arm.com        for (ThreadID tid = 0; tid < numThreads; tid++) {
3728948Sandreas.hansson@arm.com            thread[tid].checkSnoop(pkt);
3738707Sandreas.hansson@arm.com        }
3748707Sandreas.hansson@arm.com    }
3758707Sandreas.hansson@arm.com}
3768707Sandreas.hansson@arm.com
3772292SN/Atemplate<class Impl>
3782292SN/Aint
3792292SN/ALSQ<Impl>::getCount()
3802292SN/A{
3812292SN/A    unsigned total = 0;
3822292SN/A
3836221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
3846221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
3852292SN/A
3863867Sbinkertn@umich.edu    while (threads != end) {
3876221Snate@binkert.org        ThreadID tid = *threads++;
3883867Sbinkertn@umich.edu
3892292SN/A        total += getCount(tid);
3902292SN/A    }
3912292SN/A
3922292SN/A    return total;
3932292SN/A}
3942292SN/A
3952292SN/Atemplate<class Impl>
3962292SN/Aint
3972292SN/ALSQ<Impl>::numLoads()
3982292SN/A{
3992292SN/A    unsigned total = 0;
4002292SN/A
4016221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
4026221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
4032292SN/A
4043867Sbinkertn@umich.edu    while (threads != end) {
4056221Snate@binkert.org        ThreadID tid = *threads++;
4063867Sbinkertn@umich.edu
4072292SN/A        total += numLoads(tid);
4082292SN/A    }
4092292SN/A
4102292SN/A    return total;
4112292SN/A}
4122292SN/A
4132292SN/Atemplate<class Impl>
4142292SN/Aint
4152292SN/ALSQ<Impl>::numStores()
4162292SN/A{
4172292SN/A    unsigned total = 0;
4182292SN/A
4196221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
4206221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
4212292SN/A
4223867Sbinkertn@umich.edu    while (threads != end) {
4236221Snate@binkert.org        ThreadID tid = *threads++;
4243867Sbinkertn@umich.edu
4252292SN/A        total += thread[tid].numStores();
4262292SN/A    }
4272292SN/A
4282292SN/A    return total;
4292292SN/A}
4302292SN/A
4312292SN/Atemplate<class Impl>
4322292SN/Aunsigned
43310239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries()
4342292SN/A{
4352292SN/A    unsigned total = 0;
4362292SN/A
4376221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
4386221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
4392292SN/A
4403867Sbinkertn@umich.edu    while (threads != end) {
4416221Snate@binkert.org        ThreadID tid = *threads++;
4423867Sbinkertn@umich.edu
44310239Sbinhpham@cs.rutgers.edu        total += thread[tid].numFreeLoadEntries();
4442292SN/A    }
4452292SN/A
4462292SN/A    return total;
4472292SN/A}
4482292SN/A
4492292SN/Atemplate<class Impl>
4502292SN/Aunsigned
45110239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries()
4522292SN/A{
45310239Sbinhpham@cs.rutgers.edu    unsigned total = 0;
45410239Sbinhpham@cs.rutgers.edu
45510239Sbinhpham@cs.rutgers.edu    list<ThreadID>::iterator threads = activeThreads->begin();
45610239Sbinhpham@cs.rutgers.edu    list<ThreadID>::iterator end = activeThreads->end();
45710239Sbinhpham@cs.rutgers.edu
45810239Sbinhpham@cs.rutgers.edu    while (threads != end) {
45910239Sbinhpham@cs.rutgers.edu        ThreadID tid = *threads++;
46010239Sbinhpham@cs.rutgers.edu
46110239Sbinhpham@cs.rutgers.edu        total += thread[tid].numFreeStoreEntries();
46210239Sbinhpham@cs.rutgers.edu    }
46310239Sbinhpham@cs.rutgers.edu
46410239Sbinhpham@cs.rutgers.edu    return total;
46510239Sbinhpham@cs.rutgers.edu}
46610239Sbinhpham@cs.rutgers.edu
46710239Sbinhpham@cs.rutgers.edutemplate<class Impl>
46810239Sbinhpham@cs.rutgers.eduunsigned
46910239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries(ThreadID tid)
47010239Sbinhpham@cs.rutgers.edu{
47110239Sbinhpham@cs.rutgers.edu        return thread[tid].numFreeLoadEntries();
47210239Sbinhpham@cs.rutgers.edu}
47310239Sbinhpham@cs.rutgers.edu
47410239Sbinhpham@cs.rutgers.edutemplate<class Impl>
47510239Sbinhpham@cs.rutgers.eduunsigned
47610239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries(ThreadID tid)
47710239Sbinhpham@cs.rutgers.edu{
47810239Sbinhpham@cs.rutgers.edu        return thread[tid].numFreeStoreEntries();
4792292SN/A}
4802292SN/A
4812292SN/Atemplate<class Impl>
4822292SN/Abool
4832292SN/ALSQ<Impl>::isFull()
4842292SN/A{
4856221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
4866221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
4872292SN/A
4883867Sbinkertn@umich.edu    while (threads != end) {
4896221Snate@binkert.org        ThreadID tid = *threads++;
4903867Sbinkertn@umich.edu
4913867Sbinkertn@umich.edu        if (!(thread[tid].lqFull() || thread[tid].sqFull()))
4922292SN/A            return false;
4932292SN/A    }
4942292SN/A
4952292SN/A    return true;
4962292SN/A}
4972292SN/A
4982292SN/Atemplate<class Impl>
4992292SN/Abool
5006221Snate@binkert.orgLSQ<Impl>::isFull(ThreadID tid)
5012292SN/A{
5022292SN/A    //@todo: Change to Calculate All Entries for
5032292SN/A    //Dynamic Policy
50413560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Dynamic)
5052292SN/A        return isFull();
5062292SN/A    else
5072292SN/A        return thread[tid].lqFull() || thread[tid].sqFull();
5082292SN/A}
5092292SN/A
5102292SN/Atemplate<class Impl>
5112292SN/Abool
5129444SAndreas.Sandberg@ARM.comLSQ<Impl>::isEmpty() const
5139444SAndreas.Sandberg@ARM.com{
5149444SAndreas.Sandberg@ARM.com    return lqEmpty() && sqEmpty();
5159444SAndreas.Sandberg@ARM.com}
5169444SAndreas.Sandberg@ARM.com
5179444SAndreas.Sandberg@ARM.comtemplate<class Impl>
5189444SAndreas.Sandberg@ARM.combool
5199444SAndreas.Sandberg@ARM.comLSQ<Impl>::lqEmpty() const
5209444SAndreas.Sandberg@ARM.com{
5219444SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator threads = activeThreads->begin();
5229444SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator end = activeThreads->end();
5239444SAndreas.Sandberg@ARM.com
5249444SAndreas.Sandberg@ARM.com    while (threads != end) {
5259444SAndreas.Sandberg@ARM.com        ThreadID tid = *threads++;
5269444SAndreas.Sandberg@ARM.com
5279444SAndreas.Sandberg@ARM.com        if (!thread[tid].lqEmpty())
5289444SAndreas.Sandberg@ARM.com            return false;
5299444SAndreas.Sandberg@ARM.com    }
5309444SAndreas.Sandberg@ARM.com
5319444SAndreas.Sandberg@ARM.com    return true;
5329444SAndreas.Sandberg@ARM.com}
5339444SAndreas.Sandberg@ARM.com
5349444SAndreas.Sandberg@ARM.comtemplate<class Impl>
5359444SAndreas.Sandberg@ARM.combool
5369444SAndreas.Sandberg@ARM.comLSQ<Impl>::sqEmpty() const
5379444SAndreas.Sandberg@ARM.com{
5389444SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator threads = activeThreads->begin();
5399444SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator end = activeThreads->end();
5409444SAndreas.Sandberg@ARM.com
5419444SAndreas.Sandberg@ARM.com    while (threads != end) {
5429444SAndreas.Sandberg@ARM.com        ThreadID tid = *threads++;
5439444SAndreas.Sandberg@ARM.com
5449444SAndreas.Sandberg@ARM.com        if (!thread[tid].sqEmpty())
5459444SAndreas.Sandberg@ARM.com            return false;
5469444SAndreas.Sandberg@ARM.com    }
5479444SAndreas.Sandberg@ARM.com
5489444SAndreas.Sandberg@ARM.com    return true;
5499444SAndreas.Sandberg@ARM.com}
5509444SAndreas.Sandberg@ARM.com
5519444SAndreas.Sandberg@ARM.comtemplate<class Impl>
5529444SAndreas.Sandberg@ARM.combool
5532292SN/ALSQ<Impl>::lqFull()
5542292SN/A{
5556221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
5566221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
5572292SN/A
5583867Sbinkertn@umich.edu    while (threads != end) {
5596221Snate@binkert.org        ThreadID tid = *threads++;
5603867Sbinkertn@umich.edu
5612292SN/A        if (!thread[tid].lqFull())
5622292SN/A            return false;
5632292SN/A    }
5642292SN/A
5652292SN/A    return true;
5662292SN/A}
5672292SN/A
5682292SN/Atemplate<class Impl>
5692292SN/Abool
5706221Snate@binkert.orgLSQ<Impl>::lqFull(ThreadID tid)
5712292SN/A{
5722292SN/A    //@todo: Change to Calculate All Entries for
5732292SN/A    //Dynamic Policy
57413560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Dynamic)
5752292SN/A        return lqFull();
5762292SN/A    else
5772292SN/A        return thread[tid].lqFull();
5782292SN/A}
5792292SN/A
5802292SN/Atemplate<class Impl>
5812292SN/Abool
5822292SN/ALSQ<Impl>::sqFull()
5832292SN/A{
5846221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
5856221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
5862292SN/A
5873867Sbinkertn@umich.edu    while (threads != end) {
5886221Snate@binkert.org        ThreadID tid = *threads++;
5893867Sbinkertn@umich.edu
5902292SN/A        if (!sqFull(tid))
5912292SN/A            return false;
5922292SN/A    }
5932292SN/A
5942292SN/A    return true;
5952292SN/A}
5962292SN/A
5972292SN/Atemplate<class Impl>
5982292SN/Abool
5996221Snate@binkert.orgLSQ<Impl>::sqFull(ThreadID tid)
6002292SN/A{
6012292SN/A     //@todo: Change to Calculate All Entries for
6022292SN/A    //Dynamic Policy
60313560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Dynamic)
6042292SN/A        return sqFull();
6052292SN/A    else
6062292SN/A        return thread[tid].sqFull();
6072292SN/A}
6082292SN/A
6092292SN/Atemplate<class Impl>
6102292SN/Abool
6112292SN/ALSQ<Impl>::isStalled()
6122292SN/A{
6136221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
6146221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
6152292SN/A
6163867Sbinkertn@umich.edu    while (threads != end) {
6176221Snate@binkert.org        ThreadID tid = *threads++;
6183867Sbinkertn@umich.edu
6192292SN/A        if (!thread[tid].isStalled())
6202292SN/A            return false;
6212292SN/A    }
6222292SN/A
6232292SN/A    return true;
6242292SN/A}
6252292SN/A
6262292SN/Atemplate<class Impl>
6272292SN/Abool
6286221Snate@binkert.orgLSQ<Impl>::isStalled(ThreadID tid)
6292292SN/A{
63013560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Dynamic)
6312292SN/A        return isStalled();
6322292SN/A    else
6332292SN/A        return thread[tid].isStalled();
6342292SN/A}
6352292SN/A
6362292SN/Atemplate<class Impl>
6372292SN/Abool
6382292SN/ALSQ<Impl>::hasStoresToWB()
6392292SN/A{
6406221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
6416221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
6422292SN/A
6433867Sbinkertn@umich.edu    while (threads != end) {
6446221Snate@binkert.org        ThreadID tid = *threads++;
6453867Sbinkertn@umich.edu
6465557Sktlim@umich.edu        if (hasStoresToWB(tid))
6475557Sktlim@umich.edu            return true;
6482292SN/A    }
6492292SN/A
6505557Sktlim@umich.edu    return false;
6512292SN/A}
6522292SN/A
6532292SN/Atemplate<class Impl>
6542292SN/Abool
6552292SN/ALSQ<Impl>::willWB()
6562292SN/A{
6576221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
6586221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
6592292SN/A
6603867Sbinkertn@umich.edu    while (threads != end) {
6616221Snate@binkert.org        ThreadID tid = *threads++;
6623867Sbinkertn@umich.edu
6635557Sktlim@umich.edu        if (willWB(tid))
6645557Sktlim@umich.edu            return true;
6652292SN/A    }
6662292SN/A
6675557Sktlim@umich.edu    return false;
6682292SN/A}
6692292SN/A
6702292SN/Atemplate<class Impl>
6712292SN/Avoid
6729440SAndreas.Sandberg@ARM.comLSQ<Impl>::dumpInsts() const
6732292SN/A{
6749440SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator threads = activeThreads->begin();
6759440SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator end = activeThreads->end();
6762292SN/A
6773867Sbinkertn@umich.edu    while (threads != end) {
6786221Snate@binkert.org        ThreadID tid = *threads++;
6793867Sbinkertn@umich.edu
6802292SN/A        thread[tid].dumpInsts();
6812292SN/A    }
6822292SN/A}
6839944Smatt.horsnell@ARM.com
6849944Smatt.horsnell@ARM.com#endif//__CPU_O3_LSQ_IMPL_HH__
685