lsq_impl.hh revision 5714
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.edu#include "params/DerivO3CPU.hh"
383395Shsul@eecs.umich.edu
393395Shsul@eecs.umich.edutemplate<class Impl>
403395Shsul@eecs.umich.eduvoid
4113774Sandreas.sandberg@arm.comLSQ<Impl>::DcachePort::setPeer(Port *port)
4213774Sandreas.sandberg@arm.com{
4313774Sandreas.sandberg@arm.com    Port::setPeer(port);
448920Snilay@cs.wisc.edu
458920Snilay@cs.wisc.edu#if FULL_SYSTEM
468920Snilay@cs.wisc.edu    // Update the ThreadContext's memory ports (Functional/Virtual
477025SBrad.Beckmann@amd.com    // Ports)
4813774Sandreas.sandberg@arm.com    lsq->updateMemPorts();
4913774Sandreas.sandberg@arm.com#endif
5013774Sandreas.sandberg@arm.com}
5113876Sjavier.bueno@metempsy.com
5213774Sandreas.sandberg@arm.comtemplate <class Impl>
5313774Sandreas.sandberg@arm.comTick
5410747SChris.Emmons@arm.comLSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
559520SAndreas.Sandberg@ARM.com{
569520SAndreas.Sandberg@ARM.com    panic("O3CPU model does not work with atomic mode!");
579520SAndreas.Sandberg@ARM.com    return curTick;
589520SAndreas.Sandberg@ARM.com}
5913432Spau.cabre@metempsy.com
6013432Spau.cabre@metempsy.comtemplate <class Impl>
6113432Spau.cabre@metempsy.comvoid
6213432Spau.cabre@metempsy.comLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
6313876Sjavier.bueno@metempsy.com{
6413876Sjavier.bueno@metempsy.com    DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.");
6513876Sjavier.bueno@metempsy.com}
6613876Sjavier.bueno@metempsy.com
6713958Sjairo.balart@metempsy.comtemplate <class Impl>
6813958Sjairo.balart@metempsy.comvoid
6913958Sjairo.balart@metempsy.comLSQ<Impl>::DcachePort::recvStatusChange(Status status)
7013958Sjairo.balart@metempsy.com{
719665Sandreas.hansson@arm.com    if (status == RangeChange) {
729665Sandreas.hansson@arm.com        if (!snoopRangeSent) {
739665Sandreas.hansson@arm.com            snoopRangeSent = true;
749665Sandreas.hansson@arm.com            sendStatusChange(Port::RangeChange);
7511238Sandreas.sandberg@arm.com        }
7611238Sandreas.sandberg@arm.com        return;
7711238Sandreas.sandberg@arm.com    }
7811238Sandreas.sandberg@arm.com    panic("O3CPU doesn't expect recvStatusChange callback!");
7911688Sandreas.hansson@arm.com}
8011688Sandreas.hansson@arm.com
8111688Sandreas.hansson@arm.comtemplate <class Impl>
8211688Sandreas.hansson@arm.combool
838920Snilay@cs.wisc.eduLSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
849827Sakash.bagdia@arm.com{
859827Sakash.bagdia@arm.com    if (pkt->isError())
869827Sakash.bagdia@arm.com        DPRINTF(LSQ, "Got error packet back for address: %#X\n", pkt->getAddr());
879827Sakash.bagdia@arm.com    if (pkt->isResponse()) {
889790Sakash.bagdia@arm.com        lsq->thread[pkt->req->threadId()].completeDataAccess(pkt);
899790Sakash.bagdia@arm.com    }
909790Sakash.bagdia@arm.com    else {
919790Sakash.bagdia@arm.com        // must be a snoop
9211688Sandreas.hansson@arm.com
9311688Sandreas.hansson@arm.com        // @TODO someday may need to process invalidations in LSQ here
9411688Sandreas.hansson@arm.com        // to provide stronger consistency model
9511688Sandreas.hansson@arm.com    }
9611688Sandreas.hansson@arm.com    return true;
9711837Swendy.elsasser@arm.com}
9811688Sandreas.hansson@arm.com
9911688Sandreas.hansson@arm.comtemplate <class Impl>
10011688Sandreas.hansson@arm.comvoid
10111688Sandreas.hansson@arm.comLSQ<Impl>::DcachePort::recvRetry()
10211688Sandreas.hansson@arm.com{
10311688Sandreas.hansson@arm.com    if (lsq->retryTid == -1)
10411688Sandreas.hansson@arm.com    {
10511688Sandreas.hansson@arm.com        //Squashed, so drop it
10611688Sandreas.hansson@arm.com        return;
10714038Smatthew.poremba@amd.com    }
10814038Smatthew.poremba@amd.com    int curr_retry_tid = lsq->retryTid;
10911688Sandreas.hansson@arm.com    // Speculatively clear the retry Tid.  This will get set again if
11011688Sandreas.hansson@arm.com    // the LSQUnit was unable to complete its access.
11111688Sandreas.hansson@arm.com    lsq->retryTid = -1;
11211688Sandreas.hansson@arm.com    lsq->thread[curr_retry_tid].recvRetry();
11311688Sandreas.hansson@arm.com}
11411688Sandreas.hansson@arm.com
11511688Sandreas.hansson@arm.comtemplate <class Impl>
11611688Sandreas.hansson@arm.comLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
11711688Sandreas.hansson@arm.com    : cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this),
11811688Sandreas.hansson@arm.com      LQEntries(params->LQEntries),
11911688Sandreas.hansson@arm.com      SQEntries(params->SQEntries),
12011688Sandreas.hansson@arm.com      numThreads(params->numThreads),
12111688Sandreas.hansson@arm.com      retryTid(-1)
12211688Sandreas.hansson@arm.com{
12311688Sandreas.hansson@arm.com    dcachePort.snoopRangeSent = false;
12411688Sandreas.hansson@arm.com
12511688Sandreas.hansson@arm.com    //**********************************************/
12611688Sandreas.hansson@arm.com    //************ Handle SMT Parameters ***********/
12711688Sandreas.hansson@arm.com    //**********************************************/
12811688Sandreas.hansson@arm.com    std::string policy = params->smtLSQPolicy;
12911688Sandreas.hansson@arm.com
13011688Sandreas.hansson@arm.com    //Convert string to lowercase
13111688Sandreas.hansson@arm.com    std::transform(policy.begin(), policy.end(), policy.begin(),
13211688Sandreas.hansson@arm.com                   (int(*)(int)) tolower);
13311688Sandreas.hansson@arm.com
13411688Sandreas.hansson@arm.com    //Figure out fetch policy
13511688Sandreas.hansson@arm.com    if (policy == "dynamic") {
13611688Sandreas.hansson@arm.com        lsqPolicy = Dynamic;
13711688Sandreas.hansson@arm.com
13811688Sandreas.hansson@arm.com        maxLQEntries = LQEntries;
13911688Sandreas.hansson@arm.com        maxSQEntries = SQEntries;
14011688Sandreas.hansson@arm.com
14111688Sandreas.hansson@arm.com        DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
14211688Sandreas.hansson@arm.com    } else if (policy == "partitioned") {
14311688Sandreas.hansson@arm.com        lsqPolicy = Partitioned;
14411688Sandreas.hansson@arm.com
14511688Sandreas.hansson@arm.com        //@todo:make work if part_amt doesnt divide evenly.
14611688Sandreas.hansson@arm.com        maxLQEntries = LQEntries / numThreads;
14713357Sciro.santilli@arm.com        maxSQEntries = SQEntries / numThreads;
14813357Sciro.santilli@arm.com
14913357Sciro.santilli@arm.com        DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
15013357Sciro.santilli@arm.com                "%i entries per LQ | %i entries per SQ",
15113357Sciro.santilli@arm.com                maxLQEntries,maxSQEntries);
15213357Sciro.santilli@arm.com    } else if (policy == "threshold") {
15313357Sciro.santilli@arm.com        lsqPolicy = Threshold;
15413357Sciro.santilli@arm.com
15511688Sandreas.hansson@arm.com        assert(params->smtLSQThreshold > LQEntries);
15611688Sandreas.hansson@arm.com        assert(params->smtLSQThreshold > SQEntries);
15711688Sandreas.hansson@arm.com
15811688Sandreas.hansson@arm.com        //Divide up by threshold amount
15911688Sandreas.hansson@arm.com        //@todo: Should threads check the max and the total
16011688Sandreas.hansson@arm.com        //amount of the LSQ
16111688Sandreas.hansson@arm.com        maxLQEntries  = params->smtLSQThreshold;
16211688Sandreas.hansson@arm.com        maxSQEntries  = params->smtLSQThreshold;
16311688Sandreas.hansson@arm.com
16411688Sandreas.hansson@arm.com        DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
16511995Sgabeblack@google.com                "%i entries per LQ | %i entries per SQ",
16611688Sandreas.hansson@arm.com                maxLQEntries,maxSQEntries);
16711688Sandreas.hansson@arm.com    } else {
16813432Spau.cabre@metempsy.com        assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
16913432Spau.cabre@metempsy.com                    "Partitioned, Threshold}");
17013432Spau.cabre@metempsy.com    }
17113958Sjairo.balart@metempsy.com
17213958Sjairo.balart@metempsy.com    //Initialize LSQs
17313958Sjairo.balart@metempsy.com    for (int tid=0; tid < numThreads; tid++) {
17413432Spau.cabre@metempsy.com        thread[tid].init(cpu, iew_ptr, params, this,
17513432Spau.cabre@metempsy.com                         maxLQEntries, maxSQEntries, tid);
17613432Spau.cabre@metempsy.com        thread[tid].setDcachePort(&dcachePort);
17713432Spau.cabre@metempsy.com    }
17813432Spau.cabre@metempsy.com}
17913432Spau.cabre@metempsy.com
18013958Sjairo.balart@metempsy.com
18113958Sjairo.balart@metempsy.comtemplate<class Impl>
18213958Sjairo.balart@metempsy.comstd::string
18313958Sjairo.balart@metempsy.comLSQ<Impl>::name() const
18413876Sjavier.bueno@metempsy.com{
18513876Sjavier.bueno@metempsy.com    return iewStage->name() + ".lsq";
18613876Sjavier.bueno@metempsy.com}
18713876Sjavier.bueno@metempsy.com
18813876Sjavier.bueno@metempsy.comtemplate<class Impl>
18913876Sjavier.bueno@metempsy.comvoid
19013876Sjavier.bueno@metempsy.comLSQ<Impl>::regStats()
19113876Sjavier.bueno@metempsy.com{
19213876Sjavier.bueno@metempsy.com    //Initialize LSQs
19313876Sjavier.bueno@metempsy.com    for (int tid=0; tid < numThreads; tid++) {
19413876Sjavier.bueno@metempsy.com        thread[tid].regStats();
19513876Sjavier.bueno@metempsy.com    }
19613876Sjavier.bueno@metempsy.com}
19713876Sjavier.bueno@metempsy.com
19813876Sjavier.bueno@metempsy.comtemplate<class Impl>
19913876Sjavier.bueno@metempsy.comvoid
20013876Sjavier.bueno@metempsy.comLSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr)
20113876Sjavier.bueno@metempsy.com{
20213876Sjavier.bueno@metempsy.com    activeThreads = at_ptr;
20313876Sjavier.bueno@metempsy.com    assert(activeThreads != 0);
20413876Sjavier.bueno@metempsy.com}
20513876Sjavier.bueno@metempsy.com
20613876Sjavier.bueno@metempsy.comtemplate <class Impl>
20711688Sandreas.hansson@arm.comvoid
2089789Sakash.bagdia@arm.comLSQ<Impl>::switchOut()
2099789Sakash.bagdia@arm.com{
2109789Sakash.bagdia@arm.com    for (int tid = 0; tid < numThreads; tid++) {
2119800Snilay@cs.wisc.edu        thread[tid].switchOut();
2129800Snilay@cs.wisc.edu    }
2139800Snilay@cs.wisc.edu}
2149800Snilay@cs.wisc.edu
2159800Snilay@cs.wisc.edutemplate <class Impl>
21611251Sradhika.jagtap@ARM.comvoid
21711251Sradhika.jagtap@ARM.comLSQ<Impl>::takeOverFrom()
21811251Sradhika.jagtap@ARM.com{
21911251Sradhika.jagtap@ARM.com    for (int tid = 0; tid < numThreads; tid++) {
22011251Sradhika.jagtap@ARM.com        thread[tid].takeOverFrom();
22111251Sradhika.jagtap@ARM.com    }
22211251Sradhika.jagtap@ARM.com}
22311251Sradhika.jagtap@ARM.com
22411251Sradhika.jagtap@ARM.comtemplate <class Impl>
22511251Sradhika.jagtap@ARM.comint
22611251Sradhika.jagtap@ARM.comLSQ<Impl>::entryAmount(int num_threads)
22711251Sradhika.jagtap@ARM.com{
22811251Sradhika.jagtap@ARM.com    if (lsqPolicy == Partitioned) {
2299800Snilay@cs.wisc.edu        return LQEntries / num_threads;
23010037SARM gem5 Developers    } else {
23110037SARM gem5 Developers        return 0;
23210037SARM gem5 Developers    }
23311626Smichael.lebeane@amd.com}
23411626Smichael.lebeane@amd.com
23511626Smichael.lebeane@amd.comtemplate <class Impl>
23611703Smichael.lebeane@amd.comvoid
23711703Smichael.lebeane@amd.comLSQ<Impl>::resetEntries()
23811626Smichael.lebeane@amd.com{
23911626Smichael.lebeane@amd.com    if (lsqPolicy != Dynamic || numThreads > 1) {
24011626Smichael.lebeane@amd.com        int active_threads = activeThreads->size();
24111626Smichael.lebeane@amd.com
24211626Smichael.lebeane@amd.com        int maxEntries;
24311626Smichael.lebeane@amd.com
24411626Smichael.lebeane@amd.com        if (lsqPolicy == Partitioned) {
24511626Smichael.lebeane@amd.com            maxEntries = LQEntries / active_threads;
24611626Smichael.lebeane@amd.com        } else if (lsqPolicy == Threshold && active_threads == 1) {
24711626Smichael.lebeane@amd.com            maxEntries = LQEntries;
24811626Smichael.lebeane@amd.com        } else {
24911626Smichael.lebeane@amd.com            maxEntries = LQEntries;
25011626Smichael.lebeane@amd.com        }
25111626Smichael.lebeane@amd.com
25211626Smichael.lebeane@amd.com        std::list<unsigned>::iterator threads  = activeThreads->begin();
25311626Smichael.lebeane@amd.com        std::list<unsigned>::iterator end = activeThreads->end();
25411626Smichael.lebeane@amd.com
25511626Smichael.lebeane@amd.com        while (threads != end) {
25611626Smichael.lebeane@amd.com            unsigned tid = *threads++;
25711626Smichael.lebeane@amd.com
25811626Smichael.lebeane@amd.com            resizeEntries(maxEntries, tid);
25911626Smichael.lebeane@amd.com        }
26011626Smichael.lebeane@amd.com    }
26111626Smichael.lebeane@amd.com}
26211626Smichael.lebeane@amd.com
26311626Smichael.lebeane@amd.comtemplate<class Impl>
26411626Smichael.lebeane@amd.comvoid
26511626Smichael.lebeane@amd.comLSQ<Impl>::removeEntries(unsigned tid)
26611626Smichael.lebeane@amd.com{
26711626Smichael.lebeane@amd.com    thread[tid].clearLQ();
2688920Snilay@cs.wisc.edu    thread[tid].clearSQ();
2698920Snilay@cs.wisc.edu}
2708920Snilay@cs.wisc.edu
2718920Snilay@cs.wisc.edutemplate<class Impl>
2728920Snilay@cs.wisc.eduvoid
2738920Snilay@cs.wisc.eduLSQ<Impl>::resizeEntries(unsigned size,unsigned tid)
27410159Sgedare@rtems.org{
27510159Sgedare@rtems.org    thread[tid].resizeLQ(size);
2768920Snilay@cs.wisc.edu    thread[tid].resizeSQ(size);
2778920Snilay@cs.wisc.edu}
2788920Snilay@cs.wisc.edu
2798920Snilay@cs.wisc.edutemplate<class Impl>
2808920Snilay@cs.wisc.eduvoid
2818920Snilay@cs.wisc.eduLSQ<Impl>::tick()
2828920Snilay@cs.wisc.edu{
2838920Snilay@cs.wisc.edu    std::list<unsigned>::iterator threads = activeThreads->begin();
2848920Snilay@cs.wisc.edu    std::list<unsigned>::iterator end = activeThreads->end();
28510757SCurtis.Dunham@arm.com
28610757SCurtis.Dunham@arm.com    while (threads != end) {
28710757SCurtis.Dunham@arm.com        unsigned tid = *threads++;
2886776SBrad.Beckmann@amd.com
2899800Snilay@cs.wisc.edu        thread[tid].tick();
2909800Snilay@cs.wisc.edu    }
2919800Snilay@cs.wisc.edu}
2929800Snilay@cs.wisc.edu
2939800Snilay@cs.wisc.edutemplate<class Impl>
29410608Sdam.sunwoo@arm.comvoid
29510608Sdam.sunwoo@arm.comLSQ<Impl>::insertLoad(DynInstPtr &load_inst)
29610608Sdam.sunwoo@arm.com{
29710608Sdam.sunwoo@arm.com    unsigned tid = load_inst->threadNumber;
29810608Sdam.sunwoo@arm.com
2999800Snilay@cs.wisc.edu    thread[tid].insertLoad(load_inst);
3008920Snilay@cs.wisc.edu}
3018920Snilay@cs.wisc.edu
3028920Snilay@cs.wisc.edutemplate<class Impl>
3038920Snilay@cs.wisc.eduvoid
3049357Sandreas.hansson@arm.comLSQ<Impl>::insertStore(DynInstPtr &store_inst)
3058920Snilay@cs.wisc.edu{
3068920Snilay@cs.wisc.edu    unsigned tid = store_inst->threadNumber;
3078920Snilay@cs.wisc.edu
3088920Snilay@cs.wisc.edu    thread[tid].insertStore(store_inst);
3098920Snilay@cs.wisc.edu}
3108920Snilay@cs.wisc.edu
3118920Snilay@cs.wisc.edutemplate<class Impl>
3128920Snilay@cs.wisc.eduFault
3138920Snilay@cs.wisc.eduLSQ<Impl>::executeLoad(DynInstPtr &inst)
3148920Snilay@cs.wisc.edu{
3158920Snilay@cs.wisc.edu    unsigned tid = inst->threadNumber;
3168920Snilay@cs.wisc.edu
3178920Snilay@cs.wisc.edu    return thread[tid].executeLoad(inst);
3188920Snilay@cs.wisc.edu}
3198920Snilay@cs.wisc.edu
32011995Sgabeblack@google.comtemplate<class Impl>
3218920Snilay@cs.wisc.eduFault
3223395Shsul@eecs.umich.eduLSQ<Impl>::executeStore(DynInstPtr &inst)
3235361Srstrong@cs.ucsd.edu{
3248920Snilay@cs.wisc.edu    unsigned tid = inst->threadNumber;
3258920Snilay@cs.wisc.edu
3268920Snilay@cs.wisc.edu    return thread[tid].executeStore(inst);
3279151Satgutier@umich.edu}
3289151Satgutier@umich.edu
3299151Satgutier@umich.edutemplate<class Impl>
3309151Satgutier@umich.eduvoid
3319151Satgutier@umich.eduLSQ<Impl>::writebackStores()
3329151Satgutier@umich.edu{
3339562Ssaidi@eecs.umich.edu    std::list<unsigned>::iterator threads = activeThreads->begin();
3348920Snilay@cs.wisc.edu    std::list<unsigned>::iterator end = activeThreads->end();
3358920Snilay@cs.wisc.edu
3368920Snilay@cs.wisc.edu    while (threads != end) {
3378920Snilay@cs.wisc.edu        unsigned tid = *threads++;
3388920Snilay@cs.wisc.edu
3398920Snilay@cs.wisc.edu        if (numStoresToWB(tid) > 0) {
3408920Snilay@cs.wisc.edu            DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
3418920Snilay@cs.wisc.edu                "available for Writeback.\n", tid, numStoresToWB(tid));
3428920Snilay@cs.wisc.edu        }
3438920Snilay@cs.wisc.edu
3448920Snilay@cs.wisc.edu        thread[tid].writebackStores();
3458920Snilay@cs.wisc.edu    }
3468920Snilay@cs.wisc.edu}
3478920Snilay@cs.wisc.edu
3488920Snilay@cs.wisc.edutemplate<class Impl>
3498920Snilay@cs.wisc.edubool
3508920Snilay@cs.wisc.eduLSQ<Impl>::violation()
35110037SARM gem5 Developers{
35210037SARM gem5 Developers    /* Answers: Does Anybody Have a Violation?*/
35310037SARM gem5 Developers    std::list<unsigned>::iterator threads = activeThreads->begin();
35410037SARM gem5 Developers    std::list<unsigned>::iterator end = activeThreads->end();
35510037SARM gem5 Developers
35610037SARM gem5 Developers    while (threads != end) {
35710037SARM gem5 Developers        unsigned tid = *threads++;
35810037SARM gem5 Developers
3598920Snilay@cs.wisc.edu        if (thread[tid].violation())
3608920Snilay@cs.wisc.edu            return true;
3618920Snilay@cs.wisc.edu    }
3628920Snilay@cs.wisc.edu
3638920Snilay@cs.wisc.edu    return false;
3648920Snilay@cs.wisc.edu}
3658920Snilay@cs.wisc.edu
3668920Snilay@cs.wisc.edutemplate<class Impl>
36710803Sbrandon.potter@amd.comint
36810803Sbrandon.potter@amd.comLSQ<Impl>::getCount()
3698920Snilay@cs.wisc.edu{
3708920Snilay@cs.wisc.edu    unsigned total = 0;
3718920Snilay@cs.wisc.edu
3728920Snilay@cs.wisc.edu    std::list<unsigned>::iterator threads = activeThreads->begin();
3738920Snilay@cs.wisc.edu    std::list<unsigned>::iterator end = activeThreads->end();
3748920Snilay@cs.wisc.edu
37513883Sdavid.hashe@amd.com    while (threads != end) {
37613883Sdavid.hashe@amd.com        unsigned tid = *threads++;
37713883Sdavid.hashe@amd.com
37813883Sdavid.hashe@amd.com        total += getCount(tid);
37913883Sdavid.hashe@amd.com    }
38013883Sdavid.hashe@amd.com
38113883Sdavid.hashe@amd.com    return total;
38213883Sdavid.hashe@amd.com}
38313883Sdavid.hashe@amd.com
38413883Sdavid.hashe@amd.comtemplate<class Impl>
38513883Sdavid.hashe@amd.comint
38613883Sdavid.hashe@amd.comLSQ<Impl>::numLoads()
38713883Sdavid.hashe@amd.com{
3888920Snilay@cs.wisc.edu    unsigned total = 0;
3898920Snilay@cs.wisc.edu
39013774Sandreas.sandberg@arm.com    std::list<unsigned>::iterator threads = activeThreads->begin();
39111688Sandreas.hansson@arm.com    std::list<unsigned>::iterator end = activeThreads->end();
3928920Snilay@cs.wisc.edu
3938920Snilay@cs.wisc.edu    while (threads != end) {
3948920Snilay@cs.wisc.edu        unsigned tid = *threads++;
3958920Snilay@cs.wisc.edu
3968920Snilay@cs.wisc.edu        total += numLoads(tid);
3978920Snilay@cs.wisc.edu    }
39810747SChris.Emmons@arm.com
39913731Sandreas.sandberg@arm.com    return total;
40013731Sandreas.sandberg@arm.com}
40113731Sandreas.sandberg@arm.com
4028920Snilay@cs.wisc.edutemplate<class Impl>
4038920Snilay@cs.wisc.eduint
4048920Snilay@cs.wisc.eduLSQ<Impl>::numStores()
4058920Snilay@cs.wisc.edu{
4068920Snilay@cs.wisc.edu    unsigned total = 0;
4078920Snilay@cs.wisc.edu
4088920Snilay@cs.wisc.edu    std::list<unsigned>::iterator threads = activeThreads->begin();
4098920Snilay@cs.wisc.edu    std::list<unsigned>::iterator end = activeThreads->end();
41011238Sandreas.sandberg@arm.com
41111238Sandreas.sandberg@arm.com    while (threads != end) {
41211238Sandreas.sandberg@arm.com        unsigned tid = *threads++;
4138920Snilay@cs.wisc.edu
41411238Sandreas.sandberg@arm.com        total += thread[tid].numStores();
41511238Sandreas.sandberg@arm.com    }
4169539Satgutier@umich.edu
4179539Satgutier@umich.edu    return total;
4189539Satgutier@umich.edu}
41912079Sgedare@rtems.org
42012079Sgedare@rtems.orgtemplate<class Impl>
4219935Sdam.sunwoo@arm.comint
4229935Sdam.sunwoo@arm.comLSQ<Impl>::numLoadsReady()
4239935Sdam.sunwoo@arm.com{
4249935Sdam.sunwoo@arm.com    unsigned total = 0;
4258920Snilay@cs.wisc.edu
4268920Snilay@cs.wisc.edu    std::list<unsigned>::iterator threads = activeThreads->begin();
4278920Snilay@cs.wisc.edu    std::list<unsigned>::iterator end = activeThreads->end();
4288920Snilay@cs.wisc.edu
4298920Snilay@cs.wisc.edu    while (threads != end) {
4308920Snilay@cs.wisc.edu        unsigned tid = *threads++;
4318920Snilay@cs.wisc.edu
4328920Snilay@cs.wisc.edu        total += thread[tid].numLoadsReady();
4338920Snilay@cs.wisc.edu    }
4348920Snilay@cs.wisc.edu
4358920Snilay@cs.wisc.edu    return total;
4368920Snilay@cs.wisc.edu}
4378956Sjayneel@cs.wisc.edu
4388956Sjayneel@cs.wisc.edutemplate<class Impl>
4398956Sjayneel@cs.wisc.eduunsigned
4408956Sjayneel@cs.wisc.eduLSQ<Impl>::numFreeEntries()
44110697SCurtis.Dunham@arm.com{
44210697SCurtis.Dunham@arm.com    unsigned total = 0;
44310594Sgabeblack@google.com
44410594Sgabeblack@google.com    std::list<unsigned>::iterator threads = activeThreads->begin();
44510594Sgabeblack@google.com    std::list<unsigned>::iterator end = activeThreads->end();
44610594Sgabeblack@google.com
44710594Sgabeblack@google.com    while (threads != end) {
44810594Sgabeblack@google.com        unsigned tid = *threads++;
44910594Sgabeblack@google.com
45010594Sgabeblack@google.com        total += thread[tid].numFreeEntries();
451    }
452
453    return total;
454}
455
456template<class Impl>
457unsigned
458LSQ<Impl>::numFreeEntries(unsigned tid)
459{
460    //if (lsqPolicy == Dynamic)
461    //return numFreeEntries();
462    //else
463        return thread[tid].numFreeEntries();
464}
465
466template<class Impl>
467bool
468LSQ<Impl>::isFull()
469{
470    std::list<unsigned>::iterator threads = activeThreads->begin();
471    std::list<unsigned>::iterator end = activeThreads->end();
472
473    while (threads != end) {
474        unsigned tid = *threads++;
475
476        if (!(thread[tid].lqFull() || thread[tid].sqFull()))
477            return false;
478    }
479
480    return true;
481}
482
483template<class Impl>
484bool
485LSQ<Impl>::isFull(unsigned tid)
486{
487    //@todo: Change to Calculate All Entries for
488    //Dynamic Policy
489    if (lsqPolicy == Dynamic)
490        return isFull();
491    else
492        return thread[tid].lqFull() || thread[tid].sqFull();
493}
494
495template<class Impl>
496bool
497LSQ<Impl>::lqFull()
498{
499    std::list<unsigned>::iterator threads = activeThreads->begin();
500    std::list<unsigned>::iterator end = activeThreads->end();
501
502    while (threads != end) {
503        unsigned tid = *threads++;
504
505        if (!thread[tid].lqFull())
506            return false;
507    }
508
509    return true;
510}
511
512template<class Impl>
513bool
514LSQ<Impl>::lqFull(unsigned tid)
515{
516    //@todo: Change to Calculate All Entries for
517    //Dynamic Policy
518    if (lsqPolicy == Dynamic)
519        return lqFull();
520    else
521        return thread[tid].lqFull();
522}
523
524template<class Impl>
525bool
526LSQ<Impl>::sqFull()
527{
528    std::list<unsigned>::iterator threads = activeThreads->begin();
529    std::list<unsigned>::iterator end = activeThreads->end();
530
531    while (threads != end) {
532        unsigned tid = *threads++;
533
534        if (!sqFull(tid))
535            return false;
536    }
537
538    return true;
539}
540
541template<class Impl>
542bool
543LSQ<Impl>::sqFull(unsigned tid)
544{
545     //@todo: Change to Calculate All Entries for
546    //Dynamic Policy
547    if (lsqPolicy == Dynamic)
548        return sqFull();
549    else
550        return thread[tid].sqFull();
551}
552
553template<class Impl>
554bool
555LSQ<Impl>::isStalled()
556{
557    std::list<unsigned>::iterator threads = activeThreads->begin();
558    std::list<unsigned>::iterator end = activeThreads->end();
559
560    while (threads != end) {
561        unsigned tid = *threads++;
562
563        if (!thread[tid].isStalled())
564            return false;
565    }
566
567    return true;
568}
569
570template<class Impl>
571bool
572LSQ<Impl>::isStalled(unsigned tid)
573{
574    if (lsqPolicy == Dynamic)
575        return isStalled();
576    else
577        return thread[tid].isStalled();
578}
579
580template<class Impl>
581bool
582LSQ<Impl>::hasStoresToWB()
583{
584    std::list<unsigned>::iterator threads = activeThreads->begin();
585    std::list<unsigned>::iterator end = activeThreads->end();
586
587    while (threads != end) {
588        unsigned tid = *threads++;
589
590        if (hasStoresToWB(tid))
591            return true;
592    }
593
594    return false;
595}
596
597template<class Impl>
598bool
599LSQ<Impl>::willWB()
600{
601    std::list<unsigned>::iterator threads = activeThreads->begin();
602    std::list<unsigned>::iterator end = activeThreads->end();
603
604    while (threads != end) {
605        unsigned tid = *threads++;
606
607        if (willWB(tid))
608            return true;
609    }
610
611    return false;
612}
613
614template<class Impl>
615void
616LSQ<Impl>::dumpInsts()
617{
618    std::list<unsigned>::iterator threads = activeThreads->begin();
619    std::list<unsigned>::iterator end = activeThreads->end();
620
621    while (threads != end) {
622        unsigned tid = *threads++;
623
624        thread[tid].dumpInsts();
625    }
626}
627