lsq_impl.hh revision 9868
15434Sgblack@eecs.umich.edu/*
24276Sgblack@eecs.umich.edu * Copyright (c) 2011-2012 ARM Limited
34276Sgblack@eecs.umich.edu * All rights reserved
47087Snate@binkert.org *
57087Snate@binkert.org * The license below extends only to copyright in the software and shall
67087Snate@binkert.org * not be construed as granting a license to any other intellectual
77087Snate@binkert.org * property including but not limited to intellectual property relating
87087Snate@binkert.org * to a hardware implementation of the functionality of the software
97087Snate@binkert.org * licensed hereunder.  You may use the software subject to the license
107087Snate@binkert.org * terms below provided that you ensure that this notice is replicated
117087Snate@binkert.org * unmodified and in its entirety in all distributions of the software,
124276Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
137087Snate@binkert.org *
147087Snate@binkert.org * Copyright (c) 2005-2006 The Regents of The University of Michigan
157087Snate@binkert.org * All rights reserved.
167087Snate@binkert.org *
177087Snate@binkert.org * Redistribution and use in source and binary forms, with or without
187087Snate@binkert.org * modification, are permitted provided that the following conditions are
197087Snate@binkert.org * met: redistributions of source code must retain the above copyright
207087Snate@binkert.org * notice, this list of conditions and the following disclaimer;
214276Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
227087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
234276Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
244276Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
254276Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
264276Sgblack@eecs.umich.edu * this software without specific prior written permission.
274276Sgblack@eecs.umich.edu *
284276Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
294276Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
304276Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
314276Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
324276Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
334276Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
344276Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
354276Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
364276Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
374276Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
384276Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
394276Sgblack@eecs.umich.edu *
404276Sgblack@eecs.umich.edu * Authors: Korey Sewell
414276Sgblack@eecs.umich.edu */
424276Sgblack@eecs.umich.edu
434276Sgblack@eecs.umich.edu#include <algorithm>
445162Sgblack@eecs.umich.edu#include <list>
454276Sgblack@eecs.umich.edu#include <string>
464592Sgblack@eecs.umich.edu
475162Sgblack@eecs.umich.edu#include "cpu/o3/lsq.hh"
485162Sgblack@eecs.umich.edu#include "debug/Drain.hh"
494592Sgblack@eecs.umich.edu#include "debug/Fetch.hh"
504592Sgblack@eecs.umich.edu#include "debug/LSQ.hh"
515162Sgblack@eecs.umich.edu#include "debug/Writeback.hh"
525162Sgblack@eecs.umich.edu#include "params/DerivO3CPU.hh"
534592Sgblack@eecs.umich.edu
544725Sgblack@eecs.umich.eduusing namespace std;
554725Sgblack@eecs.umich.edu
564725Sgblack@eecs.umich.edutemplate <class Impl>
574746Sgblack@eecs.umich.eduLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
584276Sgblack@eecs.umich.edu    : cpu(cpu_ptr), iewStage(iew_ptr),
594276Sgblack@eecs.umich.edu      LQEntries(params->LQEntries),
604592Sgblack@eecs.umich.edu      SQEntries(params->SQEntries),
615162Sgblack@eecs.umich.edu      numThreads(params->numThreads),
625162Sgblack@eecs.umich.edu      retryTid(-1)
634592Sgblack@eecs.umich.edu{
644276Sgblack@eecs.umich.edu    assert(numThreads > 0 && numThreads <= Impl::MaxThreads);
654276Sgblack@eecs.umich.edu
664276Sgblack@eecs.umich.edu    //**********************************************/
674725Sgblack@eecs.umich.edu    //************ Handle SMT Parameters ***********/
684725Sgblack@eecs.umich.edu    //**********************************************/
694725Sgblack@eecs.umich.edu    std::string policy = params->smtLSQPolicy;
704746Sgblack@eecs.umich.edu
714276Sgblack@eecs.umich.edu    //Convert string to lowercase
724276Sgblack@eecs.umich.edu    std::transform(policy.begin(), policy.end(), policy.begin(),
734592Sgblack@eecs.umich.edu                   (int(*)(int)) tolower);
745162Sgblack@eecs.umich.edu
755162Sgblack@eecs.umich.edu    //Figure out fetch policy
764592Sgblack@eecs.umich.edu    if (policy == "dynamic") {
774592Sgblack@eecs.umich.edu        lsqPolicy = Dynamic;
785162Sgblack@eecs.umich.edu
795162Sgblack@eecs.umich.edu        maxLQEntries = LQEntries;
804592Sgblack@eecs.umich.edu        maxSQEntries = SQEntries;
814728Sgblack@eecs.umich.edu
824728Sgblack@eecs.umich.edu        DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
834728Sgblack@eecs.umich.edu    } else if (policy == "partitioned") {
844746Sgblack@eecs.umich.edu        lsqPolicy = Partitioned;
854276Sgblack@eecs.umich.edu
864276Sgblack@eecs.umich.edu        //@todo:make work if part_amt doesnt divide evenly.
874592Sgblack@eecs.umich.edu        maxLQEntries = LQEntries / numThreads;
885162Sgblack@eecs.umich.edu        maxSQEntries = SQEntries / numThreads;
895162Sgblack@eecs.umich.edu
904592Sgblack@eecs.umich.edu        DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
914592Sgblack@eecs.umich.edu                "%i entries per LQ | %i entries per SQ\n",
925162Sgblack@eecs.umich.edu                maxLQEntries,maxSQEntries);
935162Sgblack@eecs.umich.edu    } else if (policy == "threshold") {
944592Sgblack@eecs.umich.edu        lsqPolicy = Threshold;
954728Sgblack@eecs.umich.edu
964728Sgblack@eecs.umich.edu        assert(params->smtLSQThreshold > LQEntries);
974728Sgblack@eecs.umich.edu        assert(params->smtLSQThreshold > SQEntries);
984746Sgblack@eecs.umich.edu
994276Sgblack@eecs.umich.edu        //Divide up by threshold amount
1004276Sgblack@eecs.umich.edu        //@todo: Should threads check the max and the total
1014276Sgblack@eecs.umich.edu        //amount of the LSQ
1024276Sgblack@eecs.umich.edu        maxLQEntries  = params->smtLSQThreshold;
1034592Sgblack@eecs.umich.edu        maxSQEntries  = params->smtLSQThreshold;
1045162Sgblack@eecs.umich.edu
1055162Sgblack@eecs.umich.edu        DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
1064592Sgblack@eecs.umich.edu                "%i entries per LQ | %i entries per SQ\n",
1074725Sgblack@eecs.umich.edu                maxLQEntries,maxSQEntries);
1084725Sgblack@eecs.umich.edu    } else {
1094725Sgblack@eecs.umich.edu        assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
1104746Sgblack@eecs.umich.edu                    "Partitioned, Threshold}");
1114276Sgblack@eecs.umich.edu    }
1124276Sgblack@eecs.umich.edu
1134276Sgblack@eecs.umich.edu    //Initialize LSQs
1144276Sgblack@eecs.umich.edu    thread = new LSQUnit[numThreads];
1155162Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
1165162Sgblack@eecs.umich.edu        thread[tid].init(cpu, iew_ptr, params, this,
1175162Sgblack@eecs.umich.edu                         maxLQEntries, maxSQEntries, tid);
1185162Sgblack@eecs.umich.edu        thread[tid].setDcachePort(&cpu_ptr->getDataPort());
1194725Sgblack@eecs.umich.edu    }
1204725Sgblack@eecs.umich.edu}
1214725Sgblack@eecs.umich.edu
1224746Sgblack@eecs.umich.edu
1234276Sgblack@eecs.umich.edutemplate<class Impl>
1244276Sgblack@eecs.umich.edustd::string
1254276Sgblack@eecs.umich.eduLSQ<Impl>::name() const
1264276Sgblack@eecs.umich.edu{
1274592Sgblack@eecs.umich.edu    return iewStage->name() + ".lsq";
1285162Sgblack@eecs.umich.edu}
1295162Sgblack@eecs.umich.edu
1304592Sgblack@eecs.umich.edutemplate<class Impl>
1314527Sgblack@eecs.umich.eduvoid
1324527Sgblack@eecs.umich.eduLSQ<Impl>::regStats()
1334725Sgblack@eecs.umich.edu{
1344746Sgblack@eecs.umich.edu    //Initialize LSQs
1354276Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
1364276Sgblack@eecs.umich.edu        thread[tid].regStats();
1374276Sgblack@eecs.umich.edu    }
1384276Sgblack@eecs.umich.edu}
1394592Sgblack@eecs.umich.edu
1405162Sgblack@eecs.umich.edutemplate<class Impl>
1415162Sgblack@eecs.umich.eduvoid
1424592Sgblack@eecs.umich.eduLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
1434725Sgblack@eecs.umich.edu{
1444725Sgblack@eecs.umich.edu    activeThreads = at_ptr;
1454725Sgblack@eecs.umich.edu    assert(activeThreads != 0);
1464746Sgblack@eecs.umich.edu}
1474276Sgblack@eecs.umich.edu
1485162Sgblack@eecs.umich.edutemplate <class Impl>
1495162Sgblack@eecs.umich.eduvoid
1505162Sgblack@eecs.umich.eduLSQ<Impl>::drainSanityCheck() const
1515162Sgblack@eecs.umich.edu{
1524276Sgblack@eecs.umich.edu    assert(isDrained());
1535162Sgblack@eecs.umich.edu
1545162Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++)
1555162Sgblack@eecs.umich.edu        thread[tid].drainSanityCheck();
1565162Sgblack@eecs.umich.edu}
1575162Sgblack@eecs.umich.edu
1585162Sgblack@eecs.umich.edutemplate <class Impl>
1595162Sgblack@eecs.umich.edubool
1604276Sgblack@eecs.umich.eduLSQ<Impl>::isDrained() const
1614592Sgblack@eecs.umich.edu{
1625162Sgblack@eecs.umich.edu    bool drained(true);
1635162Sgblack@eecs.umich.edu
1644592Sgblack@eecs.umich.edu    if (!lqEmpty()) {
1654592Sgblack@eecs.umich.edu        DPRINTF(Drain, "Not drained, LQ not empty.\n");
1665162Sgblack@eecs.umich.edu        drained = false;
1675162Sgblack@eecs.umich.edu    }
1684592Sgblack@eecs.umich.edu
1694592Sgblack@eecs.umich.edu    if (!sqEmpty()) {
1705162Sgblack@eecs.umich.edu        DPRINTF(Drain, "Not drained, SQ not empty.\n");
1715164Sgblack@eecs.umich.edu        drained = false;
1724592Sgblack@eecs.umich.edu    }
1734595Sgblack@eecs.umich.edu
1744746Sgblack@eecs.umich.edu    if (retryTid != InvalidThreadID) {
1754746Sgblack@eecs.umich.edu        DPRINTF(Drain, "Not drained, the LSQ has blocked the caches.\n");
1764746Sgblack@eecs.umich.edu        drained = false;
1775162Sgblack@eecs.umich.edu    }
1785162Sgblack@eecs.umich.edu
1794595Sgblack@eecs.umich.edu    return drained;
1804276Sgblack@eecs.umich.edu}
1814276Sgblack@eecs.umich.edu
1824276Sgblack@eecs.umich.edutemplate <class Impl>
1834276Sgblack@eecs.umich.eduvoid
1844276Sgblack@eecs.umich.eduLSQ<Impl>::takeOverFrom()
1854276Sgblack@eecs.umich.edu{
1864276Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
1874276Sgblack@eecs.umich.edu        thread[tid].takeOverFrom();
1884276Sgblack@eecs.umich.edu    }
1894276Sgblack@eecs.umich.edu}
1905162Sgblack@eecs.umich.edu
1915162Sgblack@eecs.umich.edutemplate <class Impl>
1925162Sgblack@eecs.umich.eduint
1935162Sgblack@eecs.umich.eduLSQ<Impl>::entryAmount(ThreadID num_threads)
1945167Sgblack@eecs.umich.edu{
1955167Sgblack@eecs.umich.edu    if (lsqPolicy == Partitioned) {
1965167Sgblack@eecs.umich.edu        return LQEntries / num_threads;
1975167Sgblack@eecs.umich.edu    } else {
1984276Sgblack@eecs.umich.edu        return 0;
1995162Sgblack@eecs.umich.edu    }
2005162Sgblack@eecs.umich.edu}
2015162Sgblack@eecs.umich.edu
2025162Sgblack@eecs.umich.edutemplate <class Impl>
2035162Sgblack@eecs.umich.eduvoid
2045162Sgblack@eecs.umich.eduLSQ<Impl>::resetEntries()
2055162Sgblack@eecs.umich.edu{
2065162Sgblack@eecs.umich.edu    if (lsqPolicy != Dynamic || numThreads > 1) {
2075162Sgblack@eecs.umich.edu        int active_threads = activeThreads->size();
2085162Sgblack@eecs.umich.edu
2095162Sgblack@eecs.umich.edu        int maxEntries;
2105162Sgblack@eecs.umich.edu
2115162Sgblack@eecs.umich.edu        if (lsqPolicy == Partitioned) {
2125162Sgblack@eecs.umich.edu            maxEntries = LQEntries / active_threads;
2135162Sgblack@eecs.umich.edu        } else if (lsqPolicy == Threshold && active_threads == 1) {
2145162Sgblack@eecs.umich.edu            maxEntries = LQEntries;
2155162Sgblack@eecs.umich.edu        } else {
2165162Sgblack@eecs.umich.edu            maxEntries = LQEntries;
2175162Sgblack@eecs.umich.edu        }
2185162Sgblack@eecs.umich.edu
2195162Sgblack@eecs.umich.edu        list<ThreadID>::iterator threads  = activeThreads->begin();
2205162Sgblack@eecs.umich.edu        list<ThreadID>::iterator end = activeThreads->end();
2215162Sgblack@eecs.umich.edu
2225162Sgblack@eecs.umich.edu        while (threads != end) {
2235162Sgblack@eecs.umich.edu            ThreadID tid = *threads++;
2245162Sgblack@eecs.umich.edu
2255162Sgblack@eecs.umich.edu            resizeEntries(maxEntries, tid);
2265162Sgblack@eecs.umich.edu        }
2275162Sgblack@eecs.umich.edu    }
2285162Sgblack@eecs.umich.edu}
2295162Sgblack@eecs.umich.edu
2304727Sgblack@eecs.umich.edutemplate<class Impl>
2315162Sgblack@eecs.umich.eduvoid
2325162Sgblack@eecs.umich.eduLSQ<Impl>::removeEntries(ThreadID tid)
2335162Sgblack@eecs.umich.edu{
2345162Sgblack@eecs.umich.edu    thread[tid].clearLQ();
2355162Sgblack@eecs.umich.edu    thread[tid].clearSQ();
2365162Sgblack@eecs.umich.edu}
2375162Sgblack@eecs.umich.edu
2385162Sgblack@eecs.umich.edutemplate<class Impl>
2395162Sgblack@eecs.umich.eduvoid
2405162Sgblack@eecs.umich.eduLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid)
2414727Sgblack@eecs.umich.edu{
2425162Sgblack@eecs.umich.edu    thread[tid].resizeLQ(size);
2435162Sgblack@eecs.umich.edu    thread[tid].resizeSQ(size);
2445162Sgblack@eecs.umich.edu}
2455162Sgblack@eecs.umich.edu
2464728Sgblack@eecs.umich.edutemplate<class Impl>
2474728Sgblack@eecs.umich.eduvoid
2484728Sgblack@eecs.umich.eduLSQ<Impl>::tick()
2494728Sgblack@eecs.umich.edu{
2504728Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
2514728Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
2524728Sgblack@eecs.umich.edu
2534728Sgblack@eecs.umich.edu    while (threads != end) {
2544725Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
2554575Sgblack@eecs.umich.edu
2565162Sgblack@eecs.umich.edu        thread[tid].tick();
2575162Sgblack@eecs.umich.edu    }
2585162Sgblack@eecs.umich.edu}
2595162Sgblack@eecs.umich.edu
2605162Sgblack@eecs.umich.edutemplate<class Impl>
2615162Sgblack@eecs.umich.eduvoid
2625162Sgblack@eecs.umich.eduLSQ<Impl>::insertLoad(DynInstPtr &load_inst)
2635162Sgblack@eecs.umich.edu{
2645162Sgblack@eecs.umich.edu    ThreadID tid = load_inst->threadNumber;
2655162Sgblack@eecs.umich.edu
2665162Sgblack@eecs.umich.edu    thread[tid].insertLoad(load_inst);
2675162Sgblack@eecs.umich.edu}
2685162Sgblack@eecs.umich.edu
2695162Sgblack@eecs.umich.edutemplate<class Impl>
2705162Sgblack@eecs.umich.eduvoid
2714276Sgblack@eecs.umich.eduLSQ<Impl>::insertStore(DynInstPtr &store_inst)
2724276Sgblack@eecs.umich.edu{
2735162Sgblack@eecs.umich.edu    ThreadID tid = store_inst->threadNumber;
2745162Sgblack@eecs.umich.edu
2755162Sgblack@eecs.umich.edu    thread[tid].insertStore(store_inst);
2765162Sgblack@eecs.umich.edu}
2775294Sgblack@eecs.umich.edu
2785294Sgblack@eecs.umich.edutemplate<class Impl>
2795294Sgblack@eecs.umich.eduFault
2805294Sgblack@eecs.umich.eduLSQ<Impl>::executeLoad(DynInstPtr &inst)
2815162Sgblack@eecs.umich.edu{
2825294Sgblack@eecs.umich.edu    ThreadID tid = inst->threadNumber;
2835294Sgblack@eecs.umich.edu
2845294Sgblack@eecs.umich.edu    return thread[tid].executeLoad(inst);
2855294Sgblack@eecs.umich.edu}
2865294Sgblack@eecs.umich.edu
2875294Sgblack@eecs.umich.edutemplate<class Impl>
2885294Sgblack@eecs.umich.eduFault
2895294Sgblack@eecs.umich.eduLSQ<Impl>::executeStore(DynInstPtr &inst)
2905294Sgblack@eecs.umich.edu{
2915294Sgblack@eecs.umich.edu    ThreadID tid = inst->threadNumber;
2925168Sgblack@eecs.umich.edu
2935168Sgblack@eecs.umich.edu    return thread[tid].executeStore(inst);
2945168Sgblack@eecs.umich.edu}
2955168Sgblack@eecs.umich.edu
2965168Sgblack@eecs.umich.edutemplate<class Impl>
2974276Sgblack@eecs.umich.eduvoid
2984276Sgblack@eecs.umich.eduLSQ<Impl>::writebackStores()
2995162Sgblack@eecs.umich.edu{
3005162Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
3014276Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
3024276Sgblack@eecs.umich.edu
3035162Sgblack@eecs.umich.edu    while (threads != end) {
3045162Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
3054592Sgblack@eecs.umich.edu
3065162Sgblack@eecs.umich.edu        if (numStoresToWB(tid) > 0) {
3075162Sgblack@eecs.umich.edu            DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
3084592Sgblack@eecs.umich.edu                "available for Writeback.\n", tid, numStoresToWB(tid));
3095162Sgblack@eecs.umich.edu        }
3105174Sgblack@eecs.umich.edu
3115174Sgblack@eecs.umich.edu        thread[tid].writebackStores();
3125174Sgblack@eecs.umich.edu    }
3135174Sgblack@eecs.umich.edu}
3145174Sgblack@eecs.umich.edu
3156460Sgblack@eecs.umich.edutemplate<class Impl>
3166460Sgblack@eecs.umich.edubool
3174276Sgblack@eecs.umich.eduLSQ<Impl>::violation()
3185162Sgblack@eecs.umich.edu{
3195162Sgblack@eecs.umich.edu    /* Answers: Does Anybody Have a Violation?*/
3205162Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
3215162Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
3225162Sgblack@eecs.umich.edu
3235162Sgblack@eecs.umich.edu    while (threads != end) {
3245162Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
3255162Sgblack@eecs.umich.edu
3265162Sgblack@eecs.umich.edu        if (thread[tid].violation())
3275162Sgblack@eecs.umich.edu            return true;
3285162Sgblack@eecs.umich.edu    }
3295162Sgblack@eecs.umich.edu
3305162Sgblack@eecs.umich.edu    return false;
3315162Sgblack@eecs.umich.edu}
3325162Sgblack@eecs.umich.edu
3335162Sgblack@eecs.umich.edutemplate <class Impl>
3345162Sgblack@eecs.umich.eduvoid
3355162Sgblack@eecs.umich.eduLSQ<Impl>::recvRetry()
3365162Sgblack@eecs.umich.edu{
3375162Sgblack@eecs.umich.edu    if (retryTid == InvalidThreadID)
3385162Sgblack@eecs.umich.edu    {
3395162Sgblack@eecs.umich.edu        //Squashed, so drop it
3405162Sgblack@eecs.umich.edu        return;
3415162Sgblack@eecs.umich.edu    }
3425162Sgblack@eecs.umich.edu    int curr_retry_tid = retryTid;
3435162Sgblack@eecs.umich.edu    // Speculatively clear the retry Tid.  This will get set again if
3445162Sgblack@eecs.umich.edu    // the LSQUnit was unable to complete its access.
3455162Sgblack@eecs.umich.edu    retryTid = -1;
3465162Sgblack@eecs.umich.edu    thread[curr_retry_tid].recvRetry();
3475162Sgblack@eecs.umich.edu}
3485162Sgblack@eecs.umich.edu
3495162Sgblack@eecs.umich.edutemplate <class Impl>
3505162Sgblack@eecs.umich.edubool
3515151Sgblack@eecs.umich.eduLSQ<Impl>::recvTimingResp(PacketPtr pkt)
3525162Sgblack@eecs.umich.edu{
3535162Sgblack@eecs.umich.edu    if (pkt->isError())
3545162Sgblack@eecs.umich.edu        DPRINTF(LSQ, "Got error packet back for address: %#X\n",
3555162Sgblack@eecs.umich.edu                pkt->getAddr());
3565162Sgblack@eecs.umich.edu    thread[pkt->req->threadId()].completeDataAccess(pkt);
3575162Sgblack@eecs.umich.edu    return true;
3585162Sgblack@eecs.umich.edu}
3595162Sgblack@eecs.umich.edu
3605162Sgblack@eecs.umich.edutemplate <class Impl>
3615162Sgblack@eecs.umich.eduvoid
3625150Sgblack@eecs.umich.eduLSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt)
3635162Sgblack@eecs.umich.edu{
3645162Sgblack@eecs.umich.edu    DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
3655162Sgblack@eecs.umich.edu            pkt->cmdString());
3665162Sgblack@eecs.umich.edu
3675162Sgblack@eecs.umich.edu    // must be a snoop
3685162Sgblack@eecs.umich.edu    if (pkt->isInvalidate()) {
3695162Sgblack@eecs.umich.edu        DPRINTF(LSQ, "received invalidation for addr:%#x\n",
3705162Sgblack@eecs.umich.edu                pkt->getAddr());
3715162Sgblack@eecs.umich.edu        for (ThreadID tid = 0; tid < numThreads; tid++) {
3725162Sgblack@eecs.umich.edu            thread[tid].checkSnoop(pkt);
3735162Sgblack@eecs.umich.edu        }
3745162Sgblack@eecs.umich.edu    }
3755162Sgblack@eecs.umich.edu}
3765162Sgblack@eecs.umich.edu
3775162Sgblack@eecs.umich.edutemplate<class Impl>
3785162Sgblack@eecs.umich.eduint
3795162Sgblack@eecs.umich.eduLSQ<Impl>::getCount()
3805162Sgblack@eecs.umich.edu{
3815162Sgblack@eecs.umich.edu    unsigned total = 0;
3824575Sgblack@eecs.umich.edu
3834276Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
3845162Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
3855162Sgblack@eecs.umich.edu
3865171Sgblack@eecs.umich.edu    while (threads != end) {
3875171Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
3885171Sgblack@eecs.umich.edu
3895171Sgblack@eecs.umich.edu        total += getCount(tid);
3905162Sgblack@eecs.umich.edu    }
3915162Sgblack@eecs.umich.edu
3925295Sgblack@eecs.umich.edu    return total;
3935295Sgblack@eecs.umich.edu}
3945295Sgblack@eecs.umich.edu
3955295Sgblack@eecs.umich.edutemplate<class Impl>
3965162Sgblack@eecs.umich.eduint
3975957Sgblack@eecs.umich.eduLSQ<Impl>::numLoads()
3985162Sgblack@eecs.umich.edu{
3995957Sgblack@eecs.umich.edu    unsigned total = 0;
4005957Sgblack@eecs.umich.edu
4015957Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4025957Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4035957Sgblack@eecs.umich.edu
4046867Snate@binkert.org    while (threads != end) {
4055957Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4065957Sgblack@eecs.umich.edu
4075957Sgblack@eecs.umich.edu        total += numLoads(tid);
4085957Sgblack@eecs.umich.edu    }
4095162Sgblack@eecs.umich.edu
4105162Sgblack@eecs.umich.edu    return total;
4115162Sgblack@eecs.umich.edu}
4125162Sgblack@eecs.umich.edu
4135434Sgblack@eecs.umich.edutemplate<class Impl>
4145434Sgblack@eecs.umich.eduint
4155434Sgblack@eecs.umich.eduLSQ<Impl>::numStores()
4165434Sgblack@eecs.umich.edu{
4175434Sgblack@eecs.umich.edu    unsigned total = 0;
4184592Sgblack@eecs.umich.edu
4194276Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4204276Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4215162Sgblack@eecs.umich.edu
4225162Sgblack@eecs.umich.edu    while (threads != end) {
4235162Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4245162Sgblack@eecs.umich.edu
4255162Sgblack@eecs.umich.edu        total += thread[tid].numStores();
4265162Sgblack@eecs.umich.edu    }
4275162Sgblack@eecs.umich.edu
4285162Sgblack@eecs.umich.edu    return total;
4295162Sgblack@eecs.umich.edu}
4305162Sgblack@eecs.umich.edu
4315162Sgblack@eecs.umich.edutemplate<class Impl>
4325162Sgblack@eecs.umich.eduunsigned
4335162Sgblack@eecs.umich.eduLSQ<Impl>::numFreeEntries()
4345162Sgblack@eecs.umich.edu{
4355162Sgblack@eecs.umich.edu    unsigned total = 0;
4365162Sgblack@eecs.umich.edu
4375162Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4385162Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4395162Sgblack@eecs.umich.edu
4405162Sgblack@eecs.umich.edu    while (threads != end) {
4415162Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4425162Sgblack@eecs.umich.edu
4435162Sgblack@eecs.umich.edu        total += thread[tid].numFreeEntries();
4445162Sgblack@eecs.umich.edu    }
4455162Sgblack@eecs.umich.edu
4465162Sgblack@eecs.umich.edu    return total;
4475162Sgblack@eecs.umich.edu}
4485162Sgblack@eecs.umich.edu
4495162Sgblack@eecs.umich.edutemplate<class Impl>
4505162Sgblack@eecs.umich.eduunsigned
4515162Sgblack@eecs.umich.eduLSQ<Impl>::numFreeEntries(ThreadID tid)
4525162Sgblack@eecs.umich.edu{
4535162Sgblack@eecs.umich.edu    //if (lsqPolicy == Dynamic)
4545162Sgblack@eecs.umich.edu    //return numFreeEntries();
4555162Sgblack@eecs.umich.edu    //else
4565162Sgblack@eecs.umich.edu        return thread[tid].numFreeEntries();
4575162Sgblack@eecs.umich.edu}
4585162Sgblack@eecs.umich.edu
4595162Sgblack@eecs.umich.edutemplate<class Impl>
4605162Sgblack@eecs.umich.edubool
4615162Sgblack@eecs.umich.eduLSQ<Impl>::isFull()
4625162Sgblack@eecs.umich.edu{
4635162Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4645162Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4655162Sgblack@eecs.umich.edu
4665162Sgblack@eecs.umich.edu    while (threads != end) {
4674760Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4684592Sgblack@eecs.umich.edu
4695162Sgblack@eecs.umich.edu        if (!(thread[tid].lqFull() || thread[tid].sqFull()))
4705162Sgblack@eecs.umich.edu            return false;
4714592Sgblack@eecs.umich.edu    }
4724592Sgblack@eecs.umich.edu
4735162Sgblack@eecs.umich.edu    return true;
4745162Sgblack@eecs.umich.edu}
4754592Sgblack@eecs.umich.edu
4764592Sgblack@eecs.umich.edutemplate<class Impl>
4775162Sgblack@eecs.umich.edubool
4785166Sgblack@eecs.umich.eduLSQ<Impl>::isFull(ThreadID tid)
4794592Sgblack@eecs.umich.edu{
4805165Sgblack@eecs.umich.edu    //@todo: Change to Calculate All Entries for
4814276Sgblack@eecs.umich.edu    //Dynamic Policy
4824825Sgblack@eecs.umich.edu    if (lsqPolicy == Dynamic)
4834276Sgblack@eecs.umich.edu        return isFull();
4845162Sgblack@eecs.umich.edu    else
4855162Sgblack@eecs.umich.edu        return thread[tid].lqFull() || thread[tid].sqFull();
4865162Sgblack@eecs.umich.edu}
4875162Sgblack@eecs.umich.edu
4885162Sgblack@eecs.umich.edutemplate<class Impl>
4895162Sgblack@eecs.umich.edubool
4905162Sgblack@eecs.umich.eduLSQ<Impl>::isEmpty() const
4915162Sgblack@eecs.umich.edu{
4924276Sgblack@eecs.umich.edu    return lqEmpty() && sqEmpty();
4934276Sgblack@eecs.umich.edu}
4945162Sgblack@eecs.umich.edu
4955162Sgblack@eecs.umich.edutemplate<class Impl>
4964592Sgblack@eecs.umich.edubool
4975162Sgblack@eecs.umich.eduLSQ<Impl>::lqEmpty() const
4986060Sgblack@eecs.umich.edu{
4996060Sgblack@eecs.umich.edu    list<ThreadID>::const_iterator threads = activeThreads->begin();
5006060Sgblack@eecs.umich.edu    list<ThreadID>::const_iterator end = activeThreads->end();
5016060Sgblack@eecs.umich.edu
5024592Sgblack@eecs.umich.edu    while (threads != end) {
5035162Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
5045162Sgblack@eecs.umich.edu
5055162Sgblack@eecs.umich.edu        if (!thread[tid].lqEmpty())
5065162Sgblack@eecs.umich.edu            return false;
5075162Sgblack@eecs.umich.edu    }
5084276Sgblack@eecs.umich.edu
5094276Sgblack@eecs.umich.edu    return true;
5104276Sgblack@eecs.umich.edu}
5114276Sgblack@eecs.umich.edu
5125162Sgblack@eecs.umich.edutemplate<class Impl>
5134276Sgblack@eecs.umich.edubool
5144276Sgblack@eecs.umich.eduLSQ<Impl>::sqEmpty() const
5154276Sgblack@eecs.umich.edu{
5164276Sgblack@eecs.umich.edu    list<ThreadID>::const_iterator threads = activeThreads->begin();
5175173Sgblack@eecs.umich.edu    list<ThreadID>::const_iterator end = activeThreads->end();
5185162Sgblack@eecs.umich.edu
5195162Sgblack@eecs.umich.edu    while (threads != end) {
5205162Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
5215162Sgblack@eecs.umich.edu
5225162Sgblack@eecs.umich.edu        if (!thread[tid].sqEmpty())
5235162Sgblack@eecs.umich.edu            return false;
5245162Sgblack@eecs.umich.edu    }
5255162Sgblack@eecs.umich.edu
5265162Sgblack@eecs.umich.edu    return true;
5275162Sgblack@eecs.umich.edu}
5285162Sgblack@eecs.umich.edu
5296484Sgblack@eecs.umich.edutemplate<class Impl>
5305162Sgblack@eecs.umich.edubool
5315162Sgblack@eecs.umich.eduLSQ<Impl>::lqFull()
5325162Sgblack@eecs.umich.edu{
5335162Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
5345162Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
5355162Sgblack@eecs.umich.edu
5365162Sgblack@eecs.umich.edu    while (threads != end) {
5375162Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
5385162Sgblack@eecs.umich.edu
5395162Sgblack@eecs.umich.edu        if (!thread[tid].lqFull())
5405162Sgblack@eecs.umich.edu            return false;
5414746Sgblack@eecs.umich.edu    }
5424276Sgblack@eecs.umich.edu
5434276Sgblack@eecs.umich.edu    return true;
5445162Sgblack@eecs.umich.edu}
5455162Sgblack@eecs.umich.edu
5465448Sgblack@eecs.umich.edutemplate<class Impl>
5475448Sgblack@eecs.umich.edubool
5485162Sgblack@eecs.umich.eduLSQ<Impl>::lqFull(ThreadID tid)
5495162Sgblack@eecs.umich.edu{
5505162Sgblack@eecs.umich.edu    //@todo: Change to Calculate All Entries for
5515162Sgblack@eecs.umich.edu    //Dynamic Policy
5525162Sgblack@eecs.umich.edu    if (lsqPolicy == Dynamic)
5535162Sgblack@eecs.umich.edu        return lqFull();
5545162Sgblack@eecs.umich.edu    else
5555162Sgblack@eecs.umich.edu        return thread[tid].lqFull();
5565162Sgblack@eecs.umich.edu}
5575162Sgblack@eecs.umich.edu
5585162Sgblack@eecs.umich.edutemplate<class Impl>
5595162Sgblack@eecs.umich.edubool
5605162Sgblack@eecs.umich.eduLSQ<Impl>::sqFull()
5615162Sgblack@eecs.umich.edu{
5625162Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
5636060Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
5646060Sgblack@eecs.umich.edu
5656060Sgblack@eecs.umich.edu    while (threads != end) {
5666060Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
5676060Sgblack@eecs.umich.edu
5686060Sgblack@eecs.umich.edu        if (!sqFull(tid))
5696060Sgblack@eecs.umich.edu            return false;
5705162Sgblack@eecs.umich.edu    }
5715162Sgblack@eecs.umich.edu
5724724Sgblack@eecs.umich.edu    return true;
5734276Sgblack@eecs.umich.edu}
5744276Sgblack@eecs.umich.edu
5754276Sgblack@eecs.umich.edutemplate<class Impl>
5764276Sgblack@eecs.umich.edubool
577LSQ<Impl>::sqFull(ThreadID tid)
578{
579     //@todo: Change to Calculate All Entries for
580    //Dynamic Policy
581    if (lsqPolicy == Dynamic)
582        return sqFull();
583    else
584        return thread[tid].sqFull();
585}
586
587template<class Impl>
588bool
589LSQ<Impl>::isStalled()
590{
591    list<ThreadID>::iterator threads = activeThreads->begin();
592    list<ThreadID>::iterator end = activeThreads->end();
593
594    while (threads != end) {
595        ThreadID tid = *threads++;
596
597        if (!thread[tid].isStalled())
598            return false;
599    }
600
601    return true;
602}
603
604template<class Impl>
605bool
606LSQ<Impl>::isStalled(ThreadID tid)
607{
608    if (lsqPolicy == Dynamic)
609        return isStalled();
610    else
611        return thread[tid].isStalled();
612}
613
614template<class Impl>
615bool
616LSQ<Impl>::hasStoresToWB()
617{
618    list<ThreadID>::iterator threads = activeThreads->begin();
619    list<ThreadID>::iterator end = activeThreads->end();
620
621    while (threads != end) {
622        ThreadID tid = *threads++;
623
624        if (hasStoresToWB(tid))
625            return true;
626    }
627
628    return false;
629}
630
631template<class Impl>
632bool
633LSQ<Impl>::willWB()
634{
635    list<ThreadID>::iterator threads = activeThreads->begin();
636    list<ThreadID>::iterator end = activeThreads->end();
637
638    while (threads != end) {
639        ThreadID tid = *threads++;
640
641        if (willWB(tid))
642            return true;
643    }
644
645    return false;
646}
647
648template<class Impl>
649void
650LSQ<Impl>::dumpInsts() const
651{
652    list<ThreadID>::const_iterator threads = activeThreads->begin();
653    list<ThreadID>::const_iterator end = activeThreads->end();
654
655    while (threads != end) {
656        ThreadID tid = *threads++;
657
658        thread[tid].dumpInsts();
659    }
660}
661