lsq_impl.hh revision 3867
19665Sandreas.hansson@arm.com/*
29665Sandreas.hansson@arm.com * Copyright (c) 2005-2006 The Regents of The University of Michigan
39665Sandreas.hansson@arm.com * All rights reserved.
49665Sandreas.hansson@arm.com *
59665Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
69665Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
79665Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
89665Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
99665Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
109665Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
119665Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
129665Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
135353Svilas.sridharan@gmail.com * contributors may be used to endorse or promote products derived from
143395Shsul@eecs.umich.edu * this software without specific prior written permission.
153395Shsul@eecs.umich.edu *
163395Shsul@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173395Shsul@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183395Shsul@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193395Shsul@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203395Shsul@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213395Shsul@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223395Shsul@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233395Shsul@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243395Shsul@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253395Shsul@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263395Shsul@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273395Shsul@eecs.umich.edu *
283395Shsul@eecs.umich.edu * Authors: Korey Sewell
293395Shsul@eecs.umich.edu */
303395Shsul@eecs.umich.edu
313395Shsul@eecs.umich.edu#include <algorithm>
323395Shsul@eecs.umich.edu#include <list>
333395Shsul@eecs.umich.edu#include <string>
343395Shsul@eecs.umich.edu
353395Shsul@eecs.umich.edu#include "cpu/o3/lsq.hh"
363395Shsul@eecs.umich.edu
373395Shsul@eecs.umich.edutemplate <class Impl>
383395Shsul@eecs.umich.eduTick
393395Shsul@eecs.umich.eduLSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
403395Shsul@eecs.umich.edu{
418920Snilay@cs.wisc.edu    panic("O3CPU model does not work with atomic mode!");
428920Snilay@cs.wisc.edu    return curTick;
438920Snilay@cs.wisc.edu}
4411688Sandreas.hansson@arm.com
457025SBrad.Beckmann@amd.comtemplate <class Impl>
4611688Sandreas.hansson@arm.comvoid
4711688Sandreas.hansson@arm.comLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
4811688Sandreas.hansson@arm.com{
4910747SChris.Emmons@arm.com    DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.");
509520SAndreas.Sandberg@ARM.com}
519520SAndreas.Sandberg@ARM.com
529520SAndreas.Sandberg@ARM.comtemplate <class Impl>
539520SAndreas.Sandberg@ARM.comvoid
549665Sandreas.hansson@arm.comLSQ<Impl>::DcachePort::recvStatusChange(Status status)
559665Sandreas.hansson@arm.com{
569665Sandreas.hansson@arm.com    if (status == RangeChange) {
579665Sandreas.hansson@arm.com        if (!snoopRangeSent) {
5811238Sandreas.sandberg@arm.com            snoopRangeSent = true;
5911238Sandreas.sandberg@arm.com            sendStatusChange(Port::RangeChange);
6011238Sandreas.sandberg@arm.com        }
6111238Sandreas.sandberg@arm.com        return;
6211688Sandreas.hansson@arm.com    }
6311688Sandreas.hansson@arm.com    panic("O3CPU doesn't expect recvStatusChange callback!");
6411688Sandreas.hansson@arm.com}
6511688Sandreas.hansson@arm.com
668920Snilay@cs.wisc.edutemplate <class Impl>
679827Sakash.bagdia@arm.combool
689827Sakash.bagdia@arm.comLSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
699827Sakash.bagdia@arm.com{
709827Sakash.bagdia@arm.com    if (pkt->isResponse()) {
719790Sakash.bagdia@arm.com        lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt);
729790Sakash.bagdia@arm.com    }
739790Sakash.bagdia@arm.com    else {
749790Sakash.bagdia@arm.com    //else it is a coherence request, maybe you need to do something
7511688Sandreas.hansson@arm.com        warn("Recieved a coherence request (Invalidate?), 03CPU doesn't"
7611688Sandreas.hansson@arm.com             "update LSQ for these\n");
7711688Sandreas.hansson@arm.com    }
7811688Sandreas.hansson@arm.com    return true;
7911688Sandreas.hansson@arm.com}
8011837Swendy.elsasser@arm.com
8111688Sandreas.hansson@arm.comtemplate <class Impl>
8211688Sandreas.hansson@arm.comvoid
8311688Sandreas.hansson@arm.comLSQ<Impl>::DcachePort::recvRetry()
8411688Sandreas.hansson@arm.com{
8511688Sandreas.hansson@arm.com    if (lsq->retryTid == -1)
8611688Sandreas.hansson@arm.com    {
8711688Sandreas.hansson@arm.com        //Squashed, so drop it
8811688Sandreas.hansson@arm.com        return;
8911688Sandreas.hansson@arm.com    }
9011688Sandreas.hansson@arm.com    lsq->thread[lsq->retryTid].recvRetry();
9111688Sandreas.hansson@arm.com    // Speculatively clear the retry Tid.  This will get set again if
9211688Sandreas.hansson@arm.com    // the LSQUnit was unable to complete its access.
9311688Sandreas.hansson@arm.com    lsq->retryTid = -1;
9411688Sandreas.hansson@arm.com}
9511688Sandreas.hansson@arm.com
9611688Sandreas.hansson@arm.comtemplate <class Impl>
9711688Sandreas.hansson@arm.comLSQ<Impl>::LSQ(Params *params)
9811688Sandreas.hansson@arm.com    : dcachePort(this), LQEntries(params->LQEntries),
9911688Sandreas.hansson@arm.com      SQEntries(params->SQEntries), numThreads(params->numberOfThreads),
10011688Sandreas.hansson@arm.com      retryTid(-1)
10111688Sandreas.hansson@arm.com{
10211688Sandreas.hansson@arm.com    DPRINTF(LSQ, "Creating LSQ object.\n");
10311688Sandreas.hansson@arm.com
10411688Sandreas.hansson@arm.com    dcachePort.snoopRangeSent = false;
10511688Sandreas.hansson@arm.com
10611688Sandreas.hansson@arm.com    //**********************************************/
10711688Sandreas.hansson@arm.com    //************ Handle SMT Parameters ***********/
10811688Sandreas.hansson@arm.com    //**********************************************/
10911688Sandreas.hansson@arm.com    std::string policy = params->smtLSQPolicy;
11011688Sandreas.hansson@arm.com
11111688Sandreas.hansson@arm.com    //Convert string to lowercase
11211688Sandreas.hansson@arm.com    std::transform(policy.begin(), policy.end(), policy.begin(),
11311688Sandreas.hansson@arm.com                   (int(*)(int)) tolower);
11411688Sandreas.hansson@arm.com
11511688Sandreas.hansson@arm.com    //Figure out fetch policy
11611688Sandreas.hansson@arm.com    if (policy == "dynamic") {
11711688Sandreas.hansson@arm.com        lsqPolicy = Dynamic;
11811688Sandreas.hansson@arm.com
11911688Sandreas.hansson@arm.com        maxLQEntries = LQEntries;
12011688Sandreas.hansson@arm.com        maxSQEntries = SQEntries;
12111688Sandreas.hansson@arm.com
12211688Sandreas.hansson@arm.com        DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
12311688Sandreas.hansson@arm.com
12411688Sandreas.hansson@arm.com    } else if (policy == "partitioned") {
12511688Sandreas.hansson@arm.com        lsqPolicy = Partitioned;
12611688Sandreas.hansson@arm.com
12711688Sandreas.hansson@arm.com        //@todo:make work if part_amt doesnt divide evenly.
12811688Sandreas.hansson@arm.com        maxLQEntries = LQEntries / numThreads;
12911688Sandreas.hansson@arm.com        maxSQEntries = SQEntries / numThreads;
13011688Sandreas.hansson@arm.com
13111688Sandreas.hansson@arm.com        DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
13211688Sandreas.hansson@arm.com                "%i entries per LQ | %i entries per SQ",
13311688Sandreas.hansson@arm.com                maxLQEntries,maxSQEntries);
13411688Sandreas.hansson@arm.com
13511688Sandreas.hansson@arm.com    } else if (policy == "threshold") {
13611688Sandreas.hansson@arm.com        lsqPolicy = Threshold;
13711688Sandreas.hansson@arm.com
13811995Sgabeblack@google.com        assert(params->smtLSQThreshold > LQEntries);
13911688Sandreas.hansson@arm.com        assert(params->smtLSQThreshold > SQEntries);
14011688Sandreas.hansson@arm.com
14111688Sandreas.hansson@arm.com        //Divide up by threshold amount
1429789Sakash.bagdia@arm.com        //@todo: Should threads check the max and the total
1439789Sakash.bagdia@arm.com        //amount of the LSQ
1449789Sakash.bagdia@arm.com        maxLQEntries  = params->smtLSQThreshold;
1459800Snilay@cs.wisc.edu        maxSQEntries  = params->smtLSQThreshold;
1469800Snilay@cs.wisc.edu
1479800Snilay@cs.wisc.edu        DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
1489800Snilay@cs.wisc.edu                "%i entries per LQ | %i entries per SQ",
1499800Snilay@cs.wisc.edu                maxLQEntries,maxSQEntries);
15011251Sradhika.jagtap@ARM.com
15111251Sradhika.jagtap@ARM.com    } else {
15211251Sradhika.jagtap@ARM.com        assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
15311251Sradhika.jagtap@ARM.com                    "Partitioned, Threshold}");
15411251Sradhika.jagtap@ARM.com    }
15511251Sradhika.jagtap@ARM.com
15611251Sradhika.jagtap@ARM.com    //Initialize LSQs
15711251Sradhika.jagtap@ARM.com    for (int tid=0; tid < numThreads; tid++) {
15811251Sradhika.jagtap@ARM.com        thread[tid].init(params, this, maxLQEntries, maxSQEntries, tid);
15911251Sradhika.jagtap@ARM.com        thread[tid].setDcachePort(&dcachePort);
16011251Sradhika.jagtap@ARM.com    }
16111251Sradhika.jagtap@ARM.com}
16211251Sradhika.jagtap@ARM.com
1639800Snilay@cs.wisc.edu
16410037SARM gem5 Developerstemplate<class Impl>
16510037SARM gem5 Developersstd::string
16610037SARM gem5 DevelopersLSQ<Impl>::name() const
1679800Snilay@cs.wisc.edu{
1689800Snilay@cs.wisc.edu    return iewStage->name() + ".lsq";
16911626Smichael.lebeane@amd.com}
17011626Smichael.lebeane@amd.com
17111626Smichael.lebeane@amd.comtemplate<class Impl>
17211703Smichael.lebeane@amd.comvoid
17311703Smichael.lebeane@amd.comLSQ<Impl>::regStats()
17411626Smichael.lebeane@amd.com{
17511626Smichael.lebeane@amd.com    //Initialize LSQs
17611626Smichael.lebeane@amd.com    for (int tid=0; tid < numThreads; tid++) {
17711626Smichael.lebeane@amd.com        thread[tid].regStats();
17811626Smichael.lebeane@amd.com    }
17911626Smichael.lebeane@amd.com}
18011626Smichael.lebeane@amd.com
18111626Smichael.lebeane@amd.comtemplate<class Impl>
18211626Smichael.lebeane@amd.comvoid
18311626Smichael.lebeane@amd.comLSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
18411626Smichael.lebeane@amd.com{
18511626Smichael.lebeane@amd.com    activeThreads = at_ptr;
18611626Smichael.lebeane@amd.com    assert(activeThreads != 0);
18711626Smichael.lebeane@amd.com}
18811626Smichael.lebeane@amd.com
18911626Smichael.lebeane@amd.comtemplate<class Impl>
19011626Smichael.lebeane@amd.comvoid
19111626Smichael.lebeane@amd.comLSQ<Impl>::setCPU(O3CPU *cpu_ptr)
19211626Smichael.lebeane@amd.com{
19311626Smichael.lebeane@amd.com    cpu = cpu_ptr;
19411626Smichael.lebeane@amd.com
19511626Smichael.lebeane@amd.com    dcachePort.setName(name());
19611626Smichael.lebeane@amd.com
19711626Smichael.lebeane@amd.com    for (int tid=0; tid < numThreads; tid++) {
19811626Smichael.lebeane@amd.com        thread[tid].setCPU(cpu_ptr);
19911626Smichael.lebeane@amd.com    }
20011626Smichael.lebeane@amd.com}
20111626Smichael.lebeane@amd.com
20211626Smichael.lebeane@amd.comtemplate<class Impl>
20311626Smichael.lebeane@amd.comvoid
2048920Snilay@cs.wisc.eduLSQ<Impl>::setIEW(IEW *iew_ptr)
2058920Snilay@cs.wisc.edu{
2068920Snilay@cs.wisc.edu    iewStage = iew_ptr;
2078920Snilay@cs.wisc.edu
2088920Snilay@cs.wisc.edu    for (int tid=0; tid < numThreads; tid++) {
2098920Snilay@cs.wisc.edu        thread[tid].setIEW(iew_ptr);
21010159Sgedare@rtems.org    }
21110159Sgedare@rtems.org}
2128920Snilay@cs.wisc.edu
2138920Snilay@cs.wisc.edutemplate <class Impl>
2148920Snilay@cs.wisc.eduvoid
2158920Snilay@cs.wisc.eduLSQ<Impl>::switchOut()
2168920Snilay@cs.wisc.edu{
2178920Snilay@cs.wisc.edu    for (int tid = 0; tid < numThreads; tid++) {
2188920Snilay@cs.wisc.edu        thread[tid].switchOut();
2198920Snilay@cs.wisc.edu    }
2208920Snilay@cs.wisc.edu}
22110757SCurtis.Dunham@arm.com
22210757SCurtis.Dunham@arm.comtemplate <class Impl>
22310757SCurtis.Dunham@arm.comvoid
2246776SBrad.Beckmann@amd.comLSQ<Impl>::takeOverFrom()
2259800Snilay@cs.wisc.edu{
2269800Snilay@cs.wisc.edu    for (int tid = 0; tid < numThreads; tid++) {
2279800Snilay@cs.wisc.edu        thread[tid].takeOverFrom();
2289800Snilay@cs.wisc.edu    }
2299800Snilay@cs.wisc.edu}
23010608Sdam.sunwoo@arm.com
23110608Sdam.sunwoo@arm.comtemplate <class Impl>
23210608Sdam.sunwoo@arm.comint
23310608Sdam.sunwoo@arm.comLSQ<Impl>::entryAmount(int num_threads)
23410608Sdam.sunwoo@arm.com{
2359800Snilay@cs.wisc.edu    if (lsqPolicy == Partitioned) {
2368920Snilay@cs.wisc.edu        return LQEntries / num_threads;
2378920Snilay@cs.wisc.edu    } else {
2388920Snilay@cs.wisc.edu        return 0;
2398920Snilay@cs.wisc.edu    }
2409357Sandreas.hansson@arm.com}
2418920Snilay@cs.wisc.edu
2428920Snilay@cs.wisc.edutemplate <class Impl>
2438920Snilay@cs.wisc.eduvoid
2448920Snilay@cs.wisc.eduLSQ<Impl>::resetEntries()
2458920Snilay@cs.wisc.edu{
2468920Snilay@cs.wisc.edu    if (lsqPolicy != Dynamic || numThreads > 1) {
2478920Snilay@cs.wisc.edu        int active_threads = activeThreads->size();
2488920Snilay@cs.wisc.edu
2498920Snilay@cs.wisc.edu        int maxEntries;
2508920Snilay@cs.wisc.edu
2518920Snilay@cs.wisc.edu        if (lsqPolicy == Partitioned) {
2528920Snilay@cs.wisc.edu            maxEntries = LQEntries / active_threads;
2538920Snilay@cs.wisc.edu        } else if (lsqPolicy == Threshold && active_threads == 1) {
2548920Snilay@cs.wisc.edu            maxEntries = LQEntries;
2558920Snilay@cs.wisc.edu        } else {
25611995Sgabeblack@google.com            maxEntries = LQEntries;
2578920Snilay@cs.wisc.edu        }
2583395Shsul@eecs.umich.edu
2595361Srstrong@cs.ucsd.edu        std::list<unsigned>::iterator threads  = activeThreads->begin();
2608920Snilay@cs.wisc.edu        std::list<unsigned>::iterator end = activeThreads->end();
2618920Snilay@cs.wisc.edu
2628920Snilay@cs.wisc.edu        while (threads != end) {
2639151Satgutier@umich.edu            unsigned tid = *threads++;
2649151Satgutier@umich.edu
2659151Satgutier@umich.edu            resizeEntries(maxEntries, tid);
2669151Satgutier@umich.edu        }
2679151Satgutier@umich.edu    }
2689151Satgutier@umich.edu}
2699562Ssaidi@eecs.umich.edu
2708920Snilay@cs.wisc.edutemplate<class Impl>
2718920Snilay@cs.wisc.eduvoid
2728920Snilay@cs.wisc.eduLSQ<Impl>::removeEntries(unsigned tid)
2738920Snilay@cs.wisc.edu{
2748920Snilay@cs.wisc.edu    thread[tid].clearLQ();
2758920Snilay@cs.wisc.edu    thread[tid].clearSQ();
2768920Snilay@cs.wisc.edu}
2778920Snilay@cs.wisc.edu
2788920Snilay@cs.wisc.edutemplate<class Impl>
2798920Snilay@cs.wisc.eduvoid
2808920Snilay@cs.wisc.eduLSQ<Impl>::resizeEntries(unsigned size,unsigned tid)
2818920Snilay@cs.wisc.edu{
2828920Snilay@cs.wisc.edu    thread[tid].resizeLQ(size);
2838920Snilay@cs.wisc.edu    thread[tid].resizeSQ(size);
2848920Snilay@cs.wisc.edu}
2858920Snilay@cs.wisc.edu
2868920Snilay@cs.wisc.edutemplate<class Impl>
28710037SARM gem5 Developersvoid
28810037SARM gem5 DevelopersLSQ<Impl>::tick()
28910037SARM gem5 Developers{
29010037SARM gem5 Developers    std::list<unsigned>::iterator threads = activeThreads->begin();
29110037SARM gem5 Developers    std::list<unsigned>::iterator end = activeThreads->end();
29210037SARM gem5 Developers
29310037SARM gem5 Developers    while (threads != end) {
29410037SARM gem5 Developers        unsigned tid = *threads++;
2958920Snilay@cs.wisc.edu
2968920Snilay@cs.wisc.edu        thread[tid].tick();
2978920Snilay@cs.wisc.edu    }
2988920Snilay@cs.wisc.edu}
2998920Snilay@cs.wisc.edu
3008920Snilay@cs.wisc.edutemplate<class Impl>
3018920Snilay@cs.wisc.eduvoid
3028920Snilay@cs.wisc.eduLSQ<Impl>::insertLoad(DynInstPtr &load_inst)
30310803Sbrandon.potter@amd.com{
30410803Sbrandon.potter@amd.com    unsigned tid = load_inst->threadNumber;
3058920Snilay@cs.wisc.edu
3068920Snilay@cs.wisc.edu    thread[tid].insertLoad(load_inst);
3078920Snilay@cs.wisc.edu}
3088920Snilay@cs.wisc.edu
3098920Snilay@cs.wisc.edutemplate<class Impl>
3108920Snilay@cs.wisc.eduvoid
3118920Snilay@cs.wisc.eduLSQ<Impl>::insertStore(DynInstPtr &store_inst)
3128920Snilay@cs.wisc.edu{
31311688Sandreas.hansson@arm.com    unsigned tid = store_inst->threadNumber;
31411688Sandreas.hansson@arm.com
3158920Snilay@cs.wisc.edu    thread[tid].insertStore(store_inst);
3168920Snilay@cs.wisc.edu}
3178920Snilay@cs.wisc.edu
3188920Snilay@cs.wisc.edutemplate<class Impl>
3198920Snilay@cs.wisc.eduFault
3208920Snilay@cs.wisc.eduLSQ<Impl>::executeLoad(DynInstPtr &inst)
32110747SChris.Emmons@arm.com{
32210747SChris.Emmons@arm.com    unsigned tid = inst->threadNumber;
32310747SChris.Emmons@arm.com
3248920Snilay@cs.wisc.edu    return thread[tid].executeLoad(inst);
3258920Snilay@cs.wisc.edu}
3268920Snilay@cs.wisc.edu
3278920Snilay@cs.wisc.edutemplate<class Impl>
3288920Snilay@cs.wisc.eduFault
3298920Snilay@cs.wisc.eduLSQ<Impl>::executeStore(DynInstPtr &inst)
3308920Snilay@cs.wisc.edu{
3318920Snilay@cs.wisc.edu    unsigned tid = inst->threadNumber;
33211238Sandreas.sandberg@arm.com
33311238Sandreas.sandberg@arm.com    return thread[tid].executeStore(inst);
33411238Sandreas.sandberg@arm.com}
3358920Snilay@cs.wisc.edu
33611238Sandreas.sandberg@arm.comtemplate<class Impl>
33711238Sandreas.sandberg@arm.comvoid
3389539Satgutier@umich.eduLSQ<Impl>::writebackStores()
3399539Satgutier@umich.edu{
3409539Satgutier@umich.edu    std::list<unsigned>::iterator threads = activeThreads->begin();
3419935Sdam.sunwoo@arm.com    std::list<unsigned>::iterator end = activeThreads->end();
3429935Sdam.sunwoo@arm.com
3439935Sdam.sunwoo@arm.com    while (threads != end) {
3449935Sdam.sunwoo@arm.com        unsigned tid = *threads++;
3458920Snilay@cs.wisc.edu
3468920Snilay@cs.wisc.edu        if (numStoresToWB(tid) > 0) {
3478920Snilay@cs.wisc.edu            DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
3488920Snilay@cs.wisc.edu                "available for Writeback.\n", tid, numStoresToWB(tid));
3498920Snilay@cs.wisc.edu        }
3508920Snilay@cs.wisc.edu
3518920Snilay@cs.wisc.edu        thread[tid].writebackStores();
3528920Snilay@cs.wisc.edu    }
3538920Snilay@cs.wisc.edu}
3548920Snilay@cs.wisc.edu
3558920Snilay@cs.wisc.edutemplate<class Impl>
3568920Snilay@cs.wisc.edubool
3578956Sjayneel@cs.wisc.eduLSQ<Impl>::violation()
3588956Sjayneel@cs.wisc.edu{
3598956Sjayneel@cs.wisc.edu    /* Answers: Does Anybody Have a Violation?*/
3608956Sjayneel@cs.wisc.edu    std::list<unsigned>::iterator threads = activeThreads->begin();
36110697SCurtis.Dunham@arm.com    std::list<unsigned>::iterator end = activeThreads->end();
36210697SCurtis.Dunham@arm.com
36310594Sgabeblack@google.com    while (threads != end) {
36410594Sgabeblack@google.com        unsigned tid = *threads++;
36510594Sgabeblack@google.com
36610594Sgabeblack@google.com        if (thread[tid].violation())
36710594Sgabeblack@google.com            return true;
36810594Sgabeblack@google.com    }
36910594Sgabeblack@google.com
37010594Sgabeblack@google.com    return false;
371}
372
373template<class Impl>
374int
375LSQ<Impl>::getCount()
376{
377    unsigned total = 0;
378
379    std::list<unsigned>::iterator threads = activeThreads->begin();
380    std::list<unsigned>::iterator end = activeThreads->end();
381
382    while (threads != end) {
383        unsigned tid = *threads++;
384
385        total += getCount(tid);
386    }
387
388    return total;
389}
390
391template<class Impl>
392int
393LSQ<Impl>::numLoads()
394{
395    unsigned total = 0;
396
397    std::list<unsigned>::iterator threads = activeThreads->begin();
398    std::list<unsigned>::iterator end = activeThreads->end();
399
400    while (threads != end) {
401        unsigned tid = *threads++;
402
403        total += numLoads(tid);
404    }
405
406    return total;
407}
408
409template<class Impl>
410int
411LSQ<Impl>::numStores()
412{
413    unsigned total = 0;
414
415    std::list<unsigned>::iterator threads = activeThreads->begin();
416    std::list<unsigned>::iterator end = activeThreads->end();
417
418    while (threads != end) {
419        unsigned tid = *threads++;
420
421        total += thread[tid].numStores();
422    }
423
424    return total;
425}
426
427template<class Impl>
428int
429LSQ<Impl>::numLoadsReady()
430{
431    unsigned total = 0;
432
433    std::list<unsigned>::iterator threads = activeThreads->begin();
434    std::list<unsigned>::iterator end = activeThreads->end();
435
436    while (threads != end) {
437        unsigned tid = *threads++;
438
439        total += thread[tid].numLoadsReady();
440    }
441
442    return total;
443}
444
445template<class Impl>
446unsigned
447LSQ<Impl>::numFreeEntries()
448{
449    unsigned total = 0;
450
451    std::list<unsigned>::iterator threads = activeThreads->begin();
452    std::list<unsigned>::iterator end = activeThreads->end();
453
454    while (threads != end) {
455        unsigned tid = *threads++;
456
457        total += thread[tid].numFreeEntries();
458    }
459
460    return total;
461}
462
463template<class Impl>
464unsigned
465LSQ<Impl>::numFreeEntries(unsigned tid)
466{
467    //if( lsqPolicy == Dynamic )
468    //return numFreeEntries();
469    //else
470        return thread[tid].numFreeEntries();
471}
472
473template<class Impl>
474bool
475LSQ<Impl>::isFull()
476{
477    std::list<unsigned>::iterator threads = activeThreads->begin();
478    std::list<unsigned>::iterator end = activeThreads->end();
479
480    while (threads != end) {
481        unsigned tid = *threads++;
482
483        if (!(thread[tid].lqFull() || thread[tid].sqFull()))
484            return false;
485    }
486
487    return true;
488}
489
490template<class Impl>
491bool
492LSQ<Impl>::isFull(unsigned tid)
493{
494    //@todo: Change to Calculate All Entries for
495    //Dynamic Policy
496    if (lsqPolicy == Dynamic)
497        return isFull();
498    else
499        return thread[tid].lqFull() || thread[tid].sqFull();
500}
501
502template<class Impl>
503bool
504LSQ<Impl>::lqFull()
505{
506    std::list<unsigned>::iterator threads = activeThreads->begin();
507    std::list<unsigned>::iterator end = activeThreads->end();
508
509    while (threads != end) {
510        unsigned tid = *threads++;
511
512        if (!thread[tid].lqFull())
513            return false;
514    }
515
516    return true;
517}
518
519template<class Impl>
520bool
521LSQ<Impl>::lqFull(unsigned tid)
522{
523    //@todo: Change to Calculate All Entries for
524    //Dynamic Policy
525    if( lsqPolicy == Dynamic )
526        return lqFull();
527    else
528        return thread[tid].lqFull();
529}
530
531template<class Impl>
532bool
533LSQ<Impl>::sqFull()
534{
535    std::list<unsigned>::iterator threads = activeThreads->begin();
536    std::list<unsigned>::iterator end = activeThreads->end();
537
538    while (threads != end) {
539        unsigned tid = *threads++;
540
541        if (!sqFull(tid))
542            return false;
543    }
544
545    return true;
546}
547
548template<class Impl>
549bool
550LSQ<Impl>::sqFull(unsigned tid)
551{
552     //@todo: Change to Calculate All Entries for
553    //Dynamic Policy
554    if( lsqPolicy == Dynamic )
555        return sqFull();
556    else
557        return thread[tid].sqFull();
558}
559
560template<class Impl>
561bool
562LSQ<Impl>::isStalled()
563{
564    std::list<unsigned>::iterator threads = activeThreads->begin();
565    std::list<unsigned>::iterator end = activeThreads->end();
566
567    while (threads != end) {
568        unsigned tid = *threads++;
569
570        if (!thread[tid].isStalled())
571            return false;
572    }
573
574    return true;
575}
576
577template<class Impl>
578bool
579LSQ<Impl>::isStalled(unsigned tid)
580{
581    if( lsqPolicy == Dynamic )
582        return isStalled();
583    else
584        return thread[tid].isStalled();
585}
586
587template<class Impl>
588bool
589LSQ<Impl>::hasStoresToWB()
590{
591    std::list<unsigned>::iterator threads = activeThreads->begin();
592    std::list<unsigned>::iterator end = activeThreads->end();
593
594    if (threads == end)
595        return false;
596
597    while (threads != end) {
598        unsigned tid = *threads++;
599
600        if (!hasStoresToWB(tid))
601            return false;
602    }
603
604    return true;
605}
606
607template<class Impl>
608bool
609LSQ<Impl>::willWB()
610{
611    std::list<unsigned>::iterator threads = activeThreads->begin();
612    std::list<unsigned>::iterator end = activeThreads->end();
613
614    while (threads != end) {
615        unsigned tid = *threads++;
616
617        if (!willWB(tid))
618            return false;
619    }
620
621    return true;
622}
623
624template<class Impl>
625void
626LSQ<Impl>::dumpInsts()
627{
628    std::list<unsigned>::iterator threads = activeThreads->begin();
629    std::list<unsigned>::iterator end = activeThreads->end();
630
631    while (threads != end) {
632        unsigned tid = *threads++;
633
634        thread[tid].dumpInsts();
635    }
636}
637