lsq_impl.hh revision 10575
16019Shines@cs.fsu.edu/*
26019Shines@cs.fsu.edu * Copyright (c) 2011-2012, 2014 ARM Limited
37178Sgblack@eecs.umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc.
47178Sgblack@eecs.umich.edu * All rights reserved
57178Sgblack@eecs.umich.edu *
67178Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
77178Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
87178Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
97178Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
107178Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
117178Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
127178Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
137178Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
147178Sgblack@eecs.umich.edu *
156019Shines@cs.fsu.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan
166019Shines@cs.fsu.edu * All rights reserved.
176019Shines@cs.fsu.edu *
186019Shines@cs.fsu.edu * Redistribution and use in source and binary forms, with or without
196019Shines@cs.fsu.edu * modification, are permitted provided that the following conditions are
206019Shines@cs.fsu.edu * met: redistributions of source code must retain the above copyright
216019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer;
226019Shines@cs.fsu.edu * redistributions in binary form must reproduce the above copyright
236019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer in the
246019Shines@cs.fsu.edu * documentation and/or other materials provided with the distribution;
256019Shines@cs.fsu.edu * neither the name of the copyright holders nor the names of its
266019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from
276019Shines@cs.fsu.edu * this software without specific prior written permission.
286019Shines@cs.fsu.edu *
296019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
306019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
316019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
326019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
336019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
346019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
356019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
366019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
376019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
386019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
396019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
406019Shines@cs.fsu.edu *
416019Shines@cs.fsu.edu * Authors: Korey Sewell
426019Shines@cs.fsu.edu */
436019Shines@cs.fsu.edu
446019Shines@cs.fsu.edu#ifndef __CPU_O3_LSQ_IMPL_HH__
456019Shines@cs.fsu.edu#define __CPU_O3_LSQ_IMPL_HH__
466019Shines@cs.fsu.edu
476019Shines@cs.fsu.edu#include <algorithm>
486019Shines@cs.fsu.edu#include <list>
496019Shines@cs.fsu.edu#include <string>
506019Shines@cs.fsu.edu
516019Shines@cs.fsu.edu#include "cpu/o3/lsq.hh"
526019Shines@cs.fsu.edu#include "debug/Drain.hh"
536019Shines@cs.fsu.edu#include "debug/Fetch.hh"
546019Shines@cs.fsu.edu#include "debug/LSQ.hh"
556019Shines@cs.fsu.edu#include "debug/Writeback.hh"
566019Shines@cs.fsu.edu#include "params/DerivO3CPU.hh"
576019Shines@cs.fsu.edu
586243Sgblack@eecs.umich.eduusing namespace std;
596243Sgblack@eecs.umich.edu
606243Sgblack@eecs.umich.edutemplate <class Impl>
616243Sgblack@eecs.umich.eduLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
626243Sgblack@eecs.umich.edu    : cpu(cpu_ptr), iewStage(iew_ptr),
636019Shines@cs.fsu.edu      LQEntries(params->LQEntries),
646019Shines@cs.fsu.edu      SQEntries(params->SQEntries),
656019Shines@cs.fsu.edu      numThreads(params->numThreads)
666019Shines@cs.fsu.edu{
676019Shines@cs.fsu.edu    assert(numThreads > 0 && numThreads <= Impl::MaxThreads);
686019Shines@cs.fsu.edu
696019Shines@cs.fsu.edu    //**********************************************/
706019Shines@cs.fsu.edu    //************ Handle SMT Parameters ***********/
716019Shines@cs.fsu.edu    //**********************************************/
726019Shines@cs.fsu.edu    std::string policy = params->smtLSQPolicy;
736019Shines@cs.fsu.edu
746019Shines@cs.fsu.edu    //Convert string to lowercase
756019Shines@cs.fsu.edu    std::transform(policy.begin(), policy.end(), policy.begin(),
766019Shines@cs.fsu.edu                   (int(*)(int)) tolower);
776019Shines@cs.fsu.edu
786019Shines@cs.fsu.edu    //Figure out fetch policy
796019Shines@cs.fsu.edu    if (policy == "dynamic") {
806019Shines@cs.fsu.edu        lsqPolicy = Dynamic;
816019Shines@cs.fsu.edu
826019Shines@cs.fsu.edu        maxLQEntries = LQEntries;
836019Shines@cs.fsu.edu        maxSQEntries = SQEntries;
846019Shines@cs.fsu.edu
856019Shines@cs.fsu.edu        DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
866019Shines@cs.fsu.edu    } else if (policy == "partitioned") {
876019Shines@cs.fsu.edu        lsqPolicy = Partitioned;
886019Shines@cs.fsu.edu
896019Shines@cs.fsu.edu        //@todo:make work if part_amt doesnt divide evenly.
906019Shines@cs.fsu.edu        maxLQEntries = LQEntries / numThreads;
916019Shines@cs.fsu.edu        maxSQEntries = SQEntries / numThreads;
926019Shines@cs.fsu.edu
936019Shines@cs.fsu.edu        DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
946252Sgblack@eecs.umich.edu                "%i entries per LQ | %i entries per SQ\n",
956243Sgblack@eecs.umich.edu                maxLQEntries,maxSQEntries);
966243Sgblack@eecs.umich.edu    } else if (policy == "threshold") {
976243Sgblack@eecs.umich.edu        lsqPolicy = Threshold;
986019Shines@cs.fsu.edu
996019Shines@cs.fsu.edu        assert(params->smtLSQThreshold > LQEntries);
1006019Shines@cs.fsu.edu        assert(params->smtLSQThreshold > SQEntries);
1016019Shines@cs.fsu.edu
1026019Shines@cs.fsu.edu        //Divide up by threshold amount
1036252Sgblack@eecs.umich.edu        //@todo: Should threads check the max and the total
1046243Sgblack@eecs.umich.edu        //amount of the LSQ
1056243Sgblack@eecs.umich.edu        maxLQEntries  = params->smtLSQThreshold;
1066243Sgblack@eecs.umich.edu        maxSQEntries  = params->smtLSQThreshold;
1076019Shines@cs.fsu.edu
1086019Shines@cs.fsu.edu        DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
1096019Shines@cs.fsu.edu                "%i entries per LQ | %i entries per SQ\n",
1106019Shines@cs.fsu.edu                maxLQEntries,maxSQEntries);
1116019Shines@cs.fsu.edu    } else {
1126019Shines@cs.fsu.edu        assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
1136019Shines@cs.fsu.edu                    "Partitioned, Threshold}");
1146252Sgblack@eecs.umich.edu    }
1156243Sgblack@eecs.umich.edu
1166243Sgblack@eecs.umich.edu    //Initialize LSQs
1176243Sgblack@eecs.umich.edu    thread = new LSQUnit[numThreads];
1186019Shines@cs.fsu.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
1196019Shines@cs.fsu.edu        thread[tid].init(cpu, iew_ptr, params, this,
1206019Shines@cs.fsu.edu                         maxLQEntries, maxSQEntries, tid);
1216019Shines@cs.fsu.edu        thread[tid].setDcachePort(&cpu_ptr->getDataPort());
1226019Shines@cs.fsu.edu    }
1236019Shines@cs.fsu.edu}
1246019Shines@cs.fsu.edu
1256019Shines@cs.fsu.edu
1266019Shines@cs.fsu.edutemplate<class Impl>
1276019Shines@cs.fsu.edustd::string
1286019Shines@cs.fsu.eduLSQ<Impl>::name() const
1296019Shines@cs.fsu.edu{
1306019Shines@cs.fsu.edu    return iewStage->name() + ".lsq";
1316019Shines@cs.fsu.edu}
1326019Shines@cs.fsu.edu
1336019Shines@cs.fsu.edutemplate<class Impl>
1346724Sgblack@eecs.umich.eduvoid
1356724Sgblack@eecs.umich.eduLSQ<Impl>::regStats()
1366019Shines@cs.fsu.edu{
1376019Shines@cs.fsu.edu    //Initialize LSQs
1386019Shines@cs.fsu.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
1396019Shines@cs.fsu.edu        thread[tid].regStats();
1406019Shines@cs.fsu.edu    }
1416252Sgblack@eecs.umich.edu}
1426243Sgblack@eecs.umich.edu
1436243Sgblack@eecs.umich.edutemplate<class Impl>
1446243Sgblack@eecs.umich.eduvoid
1456019Shines@cs.fsu.eduLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
1466019Shines@cs.fsu.edu{
1476019Shines@cs.fsu.edu    activeThreads = at_ptr;
1486019Shines@cs.fsu.edu    assert(activeThreads != 0);
1496019Shines@cs.fsu.edu}
1506019Shines@cs.fsu.edu
1517356Sgblack@eecs.umich.edutemplate <class Impl>
1527356Sgblack@eecs.umich.eduvoid
1537356Sgblack@eecs.umich.eduLSQ<Impl>::drainSanityCheck() const
1547356Sgblack@eecs.umich.edu{
1557356Sgblack@eecs.umich.edu    assert(isDrained());
1567356Sgblack@eecs.umich.edu
1577356Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++)
1587356Sgblack@eecs.umich.edu        thread[tid].drainSanityCheck();
1597178Sgblack@eecs.umich.edu}
1607178Sgblack@eecs.umich.edu
1617178Sgblack@eecs.umich.edutemplate <class Impl>
1627337Sgblack@eecs.umich.edubool
1637178Sgblack@eecs.umich.eduLSQ<Impl>::isDrained() const
1647178Sgblack@eecs.umich.edu{
1657178Sgblack@eecs.umich.edu    bool drained(true);
1667178Sgblack@eecs.umich.edu
1677178Sgblack@eecs.umich.edu    if (!lqEmpty()) {
1687178Sgblack@eecs.umich.edu        DPRINTF(Drain, "Not drained, LQ not empty.\n");
1697178Sgblack@eecs.umich.edu        drained = false;
1707178Sgblack@eecs.umich.edu    }
1717178Sgblack@eecs.umich.edu
1727178Sgblack@eecs.umich.edu    if (!sqEmpty()) {
1737178Sgblack@eecs.umich.edu        DPRINTF(Drain, "Not drained, SQ not empty.\n");
1747335Sgblack@eecs.umich.edu        drained = false;
1757335Sgblack@eecs.umich.edu    }
1767335Sgblack@eecs.umich.edu
1777335Sgblack@eecs.umich.edu    return drained;
1787335Sgblack@eecs.umich.edu}
1797335Sgblack@eecs.umich.edu
1807335Sgblack@eecs.umich.edutemplate <class Impl>
1817335Sgblack@eecs.umich.eduvoid
1827335Sgblack@eecs.umich.eduLSQ<Impl>::takeOverFrom()
1837335Sgblack@eecs.umich.edu{
1847335Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
1857335Sgblack@eecs.umich.edu        thread[tid].takeOverFrom();
1867337Sgblack@eecs.umich.edu    }
1877335Sgblack@eecs.umich.edu}
1887335Sgblack@eecs.umich.edu
1897335Sgblack@eecs.umich.edutemplate <class Impl>
1907335Sgblack@eecs.umich.eduint
1917335Sgblack@eecs.umich.eduLSQ<Impl>::entryAmount(ThreadID num_threads)
1927335Sgblack@eecs.umich.edu{
1937335Sgblack@eecs.umich.edu    if (lsqPolicy == Partitioned) {
1947335Sgblack@eecs.umich.edu        return LQEntries / num_threads;
1957335Sgblack@eecs.umich.edu    } else {
1967335Sgblack@eecs.umich.edu        return 0;
1977335Sgblack@eecs.umich.edu    }
1987335Sgblack@eecs.umich.edu}
1997178Sgblack@eecs.umich.edu
2007178Sgblack@eecs.umich.edutemplate <class Impl>
2017178Sgblack@eecs.umich.eduvoid
2027178Sgblack@eecs.umich.eduLSQ<Impl>::resetEntries()
2037178Sgblack@eecs.umich.edu{
2047178Sgblack@eecs.umich.edu    if (lsqPolicy != Dynamic || numThreads > 1) {
2057178Sgblack@eecs.umich.edu        int active_threads = activeThreads->size();
2067178Sgblack@eecs.umich.edu
2077178Sgblack@eecs.umich.edu        int maxEntries;
2087178Sgblack@eecs.umich.edu
2097178Sgblack@eecs.umich.edu        if (lsqPolicy == Partitioned) {
2107178Sgblack@eecs.umich.edu            maxEntries = LQEntries / active_threads;
2117178Sgblack@eecs.umich.edu        } else if (lsqPolicy == Threshold && active_threads == 1) {
2127178Sgblack@eecs.umich.edu            maxEntries = LQEntries;
2137178Sgblack@eecs.umich.edu        } else {
2147178Sgblack@eecs.umich.edu            maxEntries = LQEntries;
2157178Sgblack@eecs.umich.edu        }
2167178Sgblack@eecs.umich.edu
2177178Sgblack@eecs.umich.edu        list<ThreadID>::iterator threads  = activeThreads->begin();
2187178Sgblack@eecs.umich.edu        list<ThreadID>::iterator end = activeThreads->end();
2197178Sgblack@eecs.umich.edu
2207178Sgblack@eecs.umich.edu        while (threads != end) {
2217178Sgblack@eecs.umich.edu            ThreadID tid = *threads++;
2227178Sgblack@eecs.umich.edu
2237178Sgblack@eecs.umich.edu            resizeEntries(maxEntries, tid);
2247178Sgblack@eecs.umich.edu        }
2257178Sgblack@eecs.umich.edu    }
2267178Sgblack@eecs.umich.edu}
2277178Sgblack@eecs.umich.edu
2287346Sgblack@eecs.umich.edutemplate<class Impl>
2297346Sgblack@eecs.umich.eduvoid
2307346Sgblack@eecs.umich.eduLSQ<Impl>::removeEntries(ThreadID tid)
2317346Sgblack@eecs.umich.edu{
2327346Sgblack@eecs.umich.edu    thread[tid].clearLQ();
2337346Sgblack@eecs.umich.edu    thread[tid].clearSQ();
2347346Sgblack@eecs.umich.edu}
2357346Sgblack@eecs.umich.edu
2367346Sgblack@eecs.umich.edutemplate<class Impl>
2377346Sgblack@eecs.umich.eduvoid
2387178Sgblack@eecs.umich.eduLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid)
2397346Sgblack@eecs.umich.edu{
2407346Sgblack@eecs.umich.edu    thread[tid].resizeLQ(size);
2417346Sgblack@eecs.umich.edu    thread[tid].resizeSQ(size);
2427346Sgblack@eecs.umich.edu}
2437346Sgblack@eecs.umich.edu
2447346Sgblack@eecs.umich.edutemplate<class Impl>
2457346Sgblack@eecs.umich.eduvoid
2467346Sgblack@eecs.umich.eduLSQ<Impl>::tick()
2477346Sgblack@eecs.umich.edu{
2487346Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
2497346Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
2507346Sgblack@eecs.umich.edu
2517346Sgblack@eecs.umich.edu    while (threads != end) {
2527346Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
2537346Sgblack@eecs.umich.edu
2547178Sgblack@eecs.umich.edu        thread[tid].tick();
2557337Sgblack@eecs.umich.edu    }
2567337Sgblack@eecs.umich.edu}
2577337Sgblack@eecs.umich.edu
2587337Sgblack@eecs.umich.edutemplate<class Impl>
2597337Sgblack@eecs.umich.eduvoid
2607337Sgblack@eecs.umich.eduLSQ<Impl>::insertLoad(DynInstPtr &load_inst)
2617337Sgblack@eecs.umich.edu{
2627337Sgblack@eecs.umich.edu    ThreadID tid = load_inst->threadNumber;
2637337Sgblack@eecs.umich.edu
2647337Sgblack@eecs.umich.edu    thread[tid].insertLoad(load_inst);
2657337Sgblack@eecs.umich.edu}
2667337Sgblack@eecs.umich.edu
2677337Sgblack@eecs.umich.edutemplate<class Impl>
2687337Sgblack@eecs.umich.eduvoid
2697337Sgblack@eecs.umich.eduLSQ<Impl>::insertStore(DynInstPtr &store_inst)
2707178Sgblack@eecs.umich.edu{
2717178Sgblack@eecs.umich.edu    ThreadID tid = store_inst->threadNumber;
2727178Sgblack@eecs.umich.edu
2737178Sgblack@eecs.umich.edu    thread[tid].insertStore(store_inst);
2747337Sgblack@eecs.umich.edu}
2757337Sgblack@eecs.umich.edu
2767337Sgblack@eecs.umich.edutemplate<class Impl>
2777337Sgblack@eecs.umich.eduFault
2787346Sgblack@eecs.umich.eduLSQ<Impl>::executeLoad(DynInstPtr &inst)
2797346Sgblack@eecs.umich.edu{
2807346Sgblack@eecs.umich.edu    ThreadID tid = inst->threadNumber;
2817346Sgblack@eecs.umich.edu
2827346Sgblack@eecs.umich.edu    return thread[tid].executeLoad(inst);
2837337Sgblack@eecs.umich.edu}
2847178Sgblack@eecs.umich.edu
2857321Sgblack@eecs.umich.edutemplate<class Impl>
2867356Sgblack@eecs.umich.eduFault
2877321Sgblack@eecs.umich.eduLSQ<Impl>::executeStore(DynInstPtr &inst)
2887356Sgblack@eecs.umich.edu{
2897356Sgblack@eecs.umich.edu    ThreadID tid = inst->threadNumber;
2907356Sgblack@eecs.umich.edu
2917356Sgblack@eecs.umich.edu    return thread[tid].executeStore(inst);
2927356Sgblack@eecs.umich.edu}
2937356Sgblack@eecs.umich.edu
2947356Sgblack@eecs.umich.edutemplate<class Impl>
2957356Sgblack@eecs.umich.eduvoid
2967356Sgblack@eecs.umich.eduLSQ<Impl>::writebackStores()
2977356Sgblack@eecs.umich.edu{
2987356Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
2997356Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
3007321Sgblack@eecs.umich.edu
3017321Sgblack@eecs.umich.edu    while (threads != end) {
3027321Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
3037321Sgblack@eecs.umich.edu
3047321Sgblack@eecs.umich.edu        if (numStoresToWB(tid) > 0) {
3057321Sgblack@eecs.umich.edu            DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
3067321Sgblack@eecs.umich.edu                "available for Writeback.\n", tid, numStoresToWB(tid));
3077321Sgblack@eecs.umich.edu        }
3087321Sgblack@eecs.umich.edu
3097321Sgblack@eecs.umich.edu        thread[tid].writebackStores();
3107321Sgblack@eecs.umich.edu    }
3117335Sgblack@eecs.umich.edu}
3127335Sgblack@eecs.umich.edu
3137335Sgblack@eecs.umich.edutemplate<class Impl>
3147335Sgblack@eecs.umich.edubool
3157335Sgblack@eecs.umich.eduLSQ<Impl>::violation()
3167335Sgblack@eecs.umich.edu{
3177335Sgblack@eecs.umich.edu    /* Answers: Does Anybody Have a Violation?*/
3187335Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
3197335Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
3207321Sgblack@eecs.umich.edu
3217323Sgblack@eecs.umich.edu    while (threads != end) {
3227323Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
3237323Sgblack@eecs.umich.edu
3247323Sgblack@eecs.umich.edu        if (thread[tid].violation())
3257323Sgblack@eecs.umich.edu            return true;
3267323Sgblack@eecs.umich.edu    }
3277323Sgblack@eecs.umich.edu
3287323Sgblack@eecs.umich.edu    return false;
3297323Sgblack@eecs.umich.edu}
3307323Sgblack@eecs.umich.edu
3317323Sgblack@eecs.umich.edutemplate <class Impl>
3327323Sgblack@eecs.umich.eduvoid
3337323Sgblack@eecs.umich.eduLSQ<Impl>::recvRetry()
3347323Sgblack@eecs.umich.edu{
3357323Sgblack@eecs.umich.edu    iewStage->cacheUnblocked();
3367323Sgblack@eecs.umich.edu
3377323Sgblack@eecs.umich.edu    for (ThreadID tid : *activeThreads) {
3387321Sgblack@eecs.umich.edu        thread[tid].recvRetry();
3397321Sgblack@eecs.umich.edu    }
3407321Sgblack@eecs.umich.edu}
3417335Sgblack@eecs.umich.edu
3427335Sgblack@eecs.umich.edutemplate <class Impl>
3437335Sgblack@eecs.umich.edubool
3447335Sgblack@eecs.umich.eduLSQ<Impl>::recvTimingResp(PacketPtr pkt)
3457335Sgblack@eecs.umich.edu{
3467335Sgblack@eecs.umich.edu    if (pkt->isError())
3477335Sgblack@eecs.umich.edu        DPRINTF(LSQ, "Got error packet back for address: %#X\n",
3487335Sgblack@eecs.umich.edu                pkt->getAddr());
3497335Sgblack@eecs.umich.edu
3507335Sgblack@eecs.umich.edu    thread[pkt->req->threadId()].completeDataAccess(pkt);
3517335Sgblack@eecs.umich.edu
3527335Sgblack@eecs.umich.edu    if (pkt->isInvalidate()) {
3537335Sgblack@eecs.umich.edu        // This response also contains an invalidate; e.g. this can be the case
3547335Sgblack@eecs.umich.edu        // if cmd is ReadRespWithInvalidate.
3557335Sgblack@eecs.umich.edu        //
3567335Sgblack@eecs.umich.edu        // The calling order between completeDataAccess and checkSnoop matters.
3577335Sgblack@eecs.umich.edu        // By calling checkSnoop after completeDataAccess, we ensure that the
3587335Sgblack@eecs.umich.edu        // fault set by checkSnoop is not lost. Calling writeback (more
3597335Sgblack@eecs.umich.edu        // specifically inst->completeAcc) in completeDataAccess overwrites
3607335Sgblack@eecs.umich.edu        // fault, and in case this instruction requires squashing (as
3617335Sgblack@eecs.umich.edu        // determined by checkSnoop), the ReExec fault set by checkSnoop would
3627335Sgblack@eecs.umich.edu        // be lost otherwise.
3637335Sgblack@eecs.umich.edu
3647335Sgblack@eecs.umich.edu        DPRINTF(LSQ, "received invalidation with response for addr:%#x\n",
3657335Sgblack@eecs.umich.edu                pkt->getAddr());
3667335Sgblack@eecs.umich.edu
3677335Sgblack@eecs.umich.edu        for (ThreadID tid = 0; tid < numThreads; tid++) {
3687335Sgblack@eecs.umich.edu            thread[tid].checkSnoop(pkt);
3697335Sgblack@eecs.umich.edu        }
3707335Sgblack@eecs.umich.edu    }
3717335Sgblack@eecs.umich.edu
3727335Sgblack@eecs.umich.edu    delete pkt->req;
3737335Sgblack@eecs.umich.edu    delete pkt;
3747321Sgblack@eecs.umich.edu    return true;
3757321Sgblack@eecs.umich.edu}
3767321Sgblack@eecs.umich.edu
3777321Sgblack@eecs.umich.edutemplate <class Impl>
3787321Sgblack@eecs.umich.eduvoid
3797321Sgblack@eecs.umich.eduLSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt)
3807335Sgblack@eecs.umich.edu{
3817335Sgblack@eecs.umich.edu    DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
3827335Sgblack@eecs.umich.edu            pkt->cmdString());
3837335Sgblack@eecs.umich.edu
3847335Sgblack@eecs.umich.edu    // must be a snoop
3857335Sgblack@eecs.umich.edu    if (pkt->isInvalidate()) {
3867335Sgblack@eecs.umich.edu        DPRINTF(LSQ, "received invalidation for addr:%#x\n",
3877335Sgblack@eecs.umich.edu                pkt->getAddr());
3887335Sgblack@eecs.umich.edu        for (ThreadID tid = 0; tid < numThreads; tid++) {
3897321Sgblack@eecs.umich.edu            thread[tid].checkSnoop(pkt);
3907326Sgblack@eecs.umich.edu        }
3917326Sgblack@eecs.umich.edu    }
3927326Sgblack@eecs.umich.edu}
3937326Sgblack@eecs.umich.edu
3947326Sgblack@eecs.umich.edutemplate<class Impl>
3957326Sgblack@eecs.umich.eduint
3967326Sgblack@eecs.umich.eduLSQ<Impl>::getCount()
3977326Sgblack@eecs.umich.edu{
3987326Sgblack@eecs.umich.edu    unsigned total = 0;
3997326Sgblack@eecs.umich.edu
4007326Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4017326Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4027326Sgblack@eecs.umich.edu
4037326Sgblack@eecs.umich.edu    while (threads != end) {
4047326Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4057326Sgblack@eecs.umich.edu
4067326Sgblack@eecs.umich.edu        total += getCount(tid);
4077326Sgblack@eecs.umich.edu    }
4087326Sgblack@eecs.umich.edu
4097326Sgblack@eecs.umich.edu    return total;
4107326Sgblack@eecs.umich.edu}
4117326Sgblack@eecs.umich.edu
4127326Sgblack@eecs.umich.edutemplate<class Impl>
4137321Sgblack@eecs.umich.eduint
4147321Sgblack@eecs.umich.eduLSQ<Impl>::numLoads()
4157335Sgblack@eecs.umich.edu{
4167335Sgblack@eecs.umich.edu    unsigned total = 0;
4177335Sgblack@eecs.umich.edu
4187335Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4197335Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4207335Sgblack@eecs.umich.edu
4217335Sgblack@eecs.umich.edu    while (threads != end) {
4227335Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4237335Sgblack@eecs.umich.edu
4247335Sgblack@eecs.umich.edu        total += numLoads(tid);
4257335Sgblack@eecs.umich.edu    }
4267335Sgblack@eecs.umich.edu
4277335Sgblack@eecs.umich.edu    return total;
4287335Sgblack@eecs.umich.edu}
4297335Sgblack@eecs.umich.edu
4307335Sgblack@eecs.umich.edutemplate<class Impl>
4317335Sgblack@eecs.umich.eduint
4327335Sgblack@eecs.umich.eduLSQ<Impl>::numStores()
4337335Sgblack@eecs.umich.edu{
4347335Sgblack@eecs.umich.edu    unsigned total = 0;
4357335Sgblack@eecs.umich.edu
4367335Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4377335Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4387335Sgblack@eecs.umich.edu
4397335Sgblack@eecs.umich.edu    while (threads != end) {
4407335Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4417335Sgblack@eecs.umich.edu
4427335Sgblack@eecs.umich.edu        total += thread[tid].numStores();
4437335Sgblack@eecs.umich.edu    }
4447335Sgblack@eecs.umich.edu
4457335Sgblack@eecs.umich.edu    return total;
4467335Sgblack@eecs.umich.edu}
4477335Sgblack@eecs.umich.edu
4487335Sgblack@eecs.umich.edutemplate<class Impl>
4497335Sgblack@eecs.umich.eduunsigned
4507335Sgblack@eecs.umich.eduLSQ<Impl>::numFreeLoadEntries()
4517335Sgblack@eecs.umich.edu{
4527335Sgblack@eecs.umich.edu    unsigned total = 0;
4537335Sgblack@eecs.umich.edu
4547335Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4557335Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4567335Sgblack@eecs.umich.edu
4577335Sgblack@eecs.umich.edu    while (threads != end) {
4587335Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4597321Sgblack@eecs.umich.edu
4607321Sgblack@eecs.umich.edu        total += thread[tid].numFreeLoadEntries();
4617321Sgblack@eecs.umich.edu    }
4627321Sgblack@eecs.umich.edu
4637321Sgblack@eecs.umich.edu    return total;
4647356Sgblack@eecs.umich.edu}
4657356Sgblack@eecs.umich.edu
4667356Sgblack@eecs.umich.edutemplate<class Impl>
4677356Sgblack@eecs.umich.eduunsigned
4687356Sgblack@eecs.umich.eduLSQ<Impl>::numFreeStoreEntries()
4697356Sgblack@eecs.umich.edu{
4707363Sgblack@eecs.umich.edu    unsigned total = 0;
4717363Sgblack@eecs.umich.edu
4727363Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
4737363Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
4747363Sgblack@eecs.umich.edu
4757363Sgblack@eecs.umich.edu    while (threads != end) {
4767363Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
4777363Sgblack@eecs.umich.edu
4787363Sgblack@eecs.umich.edu        total += thread[tid].numFreeStoreEntries();
4797363Sgblack@eecs.umich.edu    }
4807363Sgblack@eecs.umich.edu
4817363Sgblack@eecs.umich.edu    return total;
4827363Sgblack@eecs.umich.edu}
4837363Sgblack@eecs.umich.edu
4847363Sgblack@eecs.umich.edutemplate<class Impl>
4857363Sgblack@eecs.umich.eduunsigned
4867363Sgblack@eecs.umich.eduLSQ<Impl>::numFreeLoadEntries(ThreadID tid)
4877363Sgblack@eecs.umich.edu{
4887363Sgblack@eecs.umich.edu        return thread[tid].numFreeLoadEntries();
4897364Sgblack@eecs.umich.edu}
4907364Sgblack@eecs.umich.edu
4917364Sgblack@eecs.umich.edutemplate<class Impl>
4927364Sgblack@eecs.umich.eduunsigned
4937364Sgblack@eecs.umich.eduLSQ<Impl>::numFreeStoreEntries(ThreadID tid)
4947364Sgblack@eecs.umich.edu{
4957364Sgblack@eecs.umich.edu        return thread[tid].numFreeStoreEntries();
4967364Sgblack@eecs.umich.edu}
4977364Sgblack@eecs.umich.edu
4987364Sgblack@eecs.umich.edutemplate<class Impl>
4997364Sgblack@eecs.umich.edubool
5007364Sgblack@eecs.umich.eduLSQ<Impl>::isFull()
5017364Sgblack@eecs.umich.edu{
5027364Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
5037364Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
5047364Sgblack@eecs.umich.edu
5057364Sgblack@eecs.umich.edu    while (threads != end) {
5067364Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
5077364Sgblack@eecs.umich.edu
5087363Sgblack@eecs.umich.edu        if (!(thread[tid].lqFull() || thread[tid].sqFull()))
5097363Sgblack@eecs.umich.edu            return false;
5107363Sgblack@eecs.umich.edu    }
5117363Sgblack@eecs.umich.edu
5127363Sgblack@eecs.umich.edu    return true;
5137367Sgblack@eecs.umich.edu}
5147367Sgblack@eecs.umich.edu
5157367Sgblack@eecs.umich.edutemplate<class Impl>
5167367Sgblack@eecs.umich.edubool
5177367Sgblack@eecs.umich.eduLSQ<Impl>::isFull(ThreadID tid)
5187367Sgblack@eecs.umich.edu{
5197367Sgblack@eecs.umich.edu    //@todo: Change to Calculate All Entries for
5207367Sgblack@eecs.umich.edu    //Dynamic Policy
5217367Sgblack@eecs.umich.edu    if (lsqPolicy == Dynamic)
5227367Sgblack@eecs.umich.edu        return isFull();
5237367Sgblack@eecs.umich.edu    else
5247367Sgblack@eecs.umich.edu        return thread[tid].lqFull() || thread[tid].sqFull();
5257367Sgblack@eecs.umich.edu}
5267367Sgblack@eecs.umich.edu
5277367Sgblack@eecs.umich.edutemplate<class Impl>
5287367Sgblack@eecs.umich.edubool
5297367Sgblack@eecs.umich.eduLSQ<Impl>::isEmpty() const
5307367Sgblack@eecs.umich.edu{
5317367Sgblack@eecs.umich.edu    return lqEmpty() && sqEmpty();
5327363Sgblack@eecs.umich.edu}
5337363Sgblack@eecs.umich.edu
5347363Sgblack@eecs.umich.edutemplate<class Impl>
5357363Sgblack@eecs.umich.edubool
5367363Sgblack@eecs.umich.eduLSQ<Impl>::lqEmpty() const
5377363Sgblack@eecs.umich.edu{
5387363Sgblack@eecs.umich.edu    list<ThreadID>::const_iterator threads = activeThreads->begin();
5397363Sgblack@eecs.umich.edu    list<ThreadID>::const_iterator end = activeThreads->end();
5407363Sgblack@eecs.umich.edu
5417363Sgblack@eecs.umich.edu    while (threads != end) {
5427363Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
5437363Sgblack@eecs.umich.edu
5447363Sgblack@eecs.umich.edu        if (!thread[tid].lqEmpty())
5457363Sgblack@eecs.umich.edu            return false;
5467363Sgblack@eecs.umich.edu    }
5477363Sgblack@eecs.umich.edu
5487363Sgblack@eecs.umich.edu    return true;
5497363Sgblack@eecs.umich.edu}
5507363Sgblack@eecs.umich.edu
5517363Sgblack@eecs.umich.edutemplate<class Impl>
5527363Sgblack@eecs.umich.edubool
5537363Sgblack@eecs.umich.eduLSQ<Impl>::sqEmpty() const
5547363Sgblack@eecs.umich.edu{
5557363Sgblack@eecs.umich.edu    list<ThreadID>::const_iterator threads = activeThreads->begin();
5567363Sgblack@eecs.umich.edu    list<ThreadID>::const_iterator end = activeThreads->end();
5577363Sgblack@eecs.umich.edu
5587363Sgblack@eecs.umich.edu    while (threads != end) {
5597363Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
5607363Sgblack@eecs.umich.edu
5617363Sgblack@eecs.umich.edu        if (!thread[tid].sqEmpty())
5627363Sgblack@eecs.umich.edu            return false;
5637363Sgblack@eecs.umich.edu    }
5647363Sgblack@eecs.umich.edu
5657363Sgblack@eecs.umich.edu    return true;
5667363Sgblack@eecs.umich.edu}
5677363Sgblack@eecs.umich.edu
5687363Sgblack@eecs.umich.edutemplate<class Impl>
5697363Sgblack@eecs.umich.edubool
5707363Sgblack@eecs.umich.eduLSQ<Impl>::lqFull()
5717363Sgblack@eecs.umich.edu{
5727363Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
5737363Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
5747363Sgblack@eecs.umich.edu
5757366Sgblack@eecs.umich.edu    while (threads != end) {
5767366Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
5777366Sgblack@eecs.umich.edu
5787366Sgblack@eecs.umich.edu        if (!thread[tid].lqFull())
5797366Sgblack@eecs.umich.edu            return false;
5807366Sgblack@eecs.umich.edu    }
5817366Sgblack@eecs.umich.edu
5827366Sgblack@eecs.umich.edu    return true;
5837366Sgblack@eecs.umich.edu}
5847366Sgblack@eecs.umich.edu
5857366Sgblack@eecs.umich.edutemplate<class Impl>
5867366Sgblack@eecs.umich.edubool
5877366Sgblack@eecs.umich.eduLSQ<Impl>::lqFull(ThreadID tid)
5887366Sgblack@eecs.umich.edu{
5897366Sgblack@eecs.umich.edu    //@todo: Change to Calculate All Entries for
5907363Sgblack@eecs.umich.edu    //Dynamic Policy
5917363Sgblack@eecs.umich.edu    if (lsqPolicy == Dynamic)
5927363Sgblack@eecs.umich.edu        return lqFull();
5937365Sgblack@eecs.umich.edu    else
5947365Sgblack@eecs.umich.edu        return thread[tid].lqFull();
5957365Sgblack@eecs.umich.edu}
5967365Sgblack@eecs.umich.edu
5977365Sgblack@eecs.umich.edutemplate<class Impl>
5987365Sgblack@eecs.umich.edubool
5997365Sgblack@eecs.umich.eduLSQ<Impl>::sqFull()
6007365Sgblack@eecs.umich.edu{
6017365Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
6027365Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
6037365Sgblack@eecs.umich.edu
6047365Sgblack@eecs.umich.edu    while (threads != end) {
6057365Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
6067365Sgblack@eecs.umich.edu
6077365Sgblack@eecs.umich.edu        if (!sqFull(tid))
6087363Sgblack@eecs.umich.edu            return false;
6097363Sgblack@eecs.umich.edu    }
6107363Sgblack@eecs.umich.edu
6117363Sgblack@eecs.umich.edu    return true;
6127363Sgblack@eecs.umich.edu}
6137363Sgblack@eecs.umich.edu
6147363Sgblack@eecs.umich.edutemplate<class Impl>
6157363Sgblack@eecs.umich.edubool
6167363Sgblack@eecs.umich.eduLSQ<Impl>::sqFull(ThreadID tid)
6177363Sgblack@eecs.umich.edu{
6187363Sgblack@eecs.umich.edu     //@todo: Change to Calculate All Entries for
6197363Sgblack@eecs.umich.edu    //Dynamic Policy
6207363Sgblack@eecs.umich.edu    if (lsqPolicy == Dynamic)
6217363Sgblack@eecs.umich.edu        return sqFull();
6227363Sgblack@eecs.umich.edu    else
6237363Sgblack@eecs.umich.edu        return thread[tid].sqFull();
6247363Sgblack@eecs.umich.edu}
6257363Sgblack@eecs.umich.edu
6267363Sgblack@eecs.umich.edutemplate<class Impl>
6277363Sgblack@eecs.umich.edubool
6287363Sgblack@eecs.umich.eduLSQ<Impl>::isStalled()
6297363Sgblack@eecs.umich.edu{
6307363Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
6317363Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
6327363Sgblack@eecs.umich.edu
6337363Sgblack@eecs.umich.edu    while (threads != end) {
6347363Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
6357363Sgblack@eecs.umich.edu
6367363Sgblack@eecs.umich.edu        if (!thread[tid].isStalled())
6377363Sgblack@eecs.umich.edu            return false;
6387363Sgblack@eecs.umich.edu    }
6397363Sgblack@eecs.umich.edu
6407363Sgblack@eecs.umich.edu    return true;
6417363Sgblack@eecs.umich.edu}
6427363Sgblack@eecs.umich.edu
6437363Sgblack@eecs.umich.edutemplate<class Impl>
6447363Sgblack@eecs.umich.edubool
6457363Sgblack@eecs.umich.eduLSQ<Impl>::isStalled(ThreadID tid)
6467363Sgblack@eecs.umich.edu{
6477363Sgblack@eecs.umich.edu    if (lsqPolicy == Dynamic)
6487363Sgblack@eecs.umich.edu        return isStalled();
6497363Sgblack@eecs.umich.edu    else
6507363Sgblack@eecs.umich.edu        return thread[tid].isStalled();
6517363Sgblack@eecs.umich.edu}
652
653template<class Impl>
654bool
655LSQ<Impl>::hasStoresToWB()
656{
657    list<ThreadID>::iterator threads = activeThreads->begin();
658    list<ThreadID>::iterator end = activeThreads->end();
659
660    while (threads != end) {
661        ThreadID tid = *threads++;
662
663        if (hasStoresToWB(tid))
664            return true;
665    }
666
667    return false;
668}
669
670template<class Impl>
671bool
672LSQ<Impl>::willWB()
673{
674    list<ThreadID>::iterator threads = activeThreads->begin();
675    list<ThreadID>::iterator end = activeThreads->end();
676
677    while (threads != end) {
678        ThreadID tid = *threads++;
679
680        if (willWB(tid))
681            return true;
682    }
683
684    return false;
685}
686
687template<class Impl>
688void
689LSQ<Impl>::dumpInsts() const
690{
691    list<ThreadID>::const_iterator threads = activeThreads->begin();
692    list<ThreadID>::const_iterator end = activeThreads->end();
693
694    while (threads != end) {
695        ThreadID tid = *threads++;
696
697        thread[tid].dumpInsts();
698    }
699}
700
701#endif//__CPU_O3_LSQ_IMPL_HH__
702