lsq_impl.hh revision 4985
12292SN/A/* 22727Sktlim@umich.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan 32292SN/A * All rights reserved. 42292SN/A * 52292SN/A * Redistribution and use in source and binary forms, with or without 62292SN/A * modification, are permitted provided that the following conditions are 72292SN/A * met: redistributions of source code must retain the above copyright 82292SN/A * notice, this list of conditions and the following disclaimer; 92292SN/A * redistributions in binary form must reproduce the above copyright 102292SN/A * notice, this list of conditions and the following disclaimer in the 112292SN/A * documentation and/or other materials provided with the distribution; 122292SN/A * neither the name of the copyright holders nor the names of its 132292SN/A * contributors may be used to endorse or promote products derived from 142292SN/A * this software without specific prior written permission. 152292SN/A * 162292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272689Sktlim@umich.edu * 282689Sktlim@umich.edu * Authors: Korey Sewell 292292SN/A */ 302292SN/A 312329SN/A#include <algorithm> 322980Sgblack@eecs.umich.edu#include <list> 332329SN/A#include <string> 342329SN/A 352292SN/A#include "cpu/o3/lsq.hh" 362292SN/A 374192Sktlim@umich.edutemplate<class Impl> 384192Sktlim@umich.eduvoid 394192Sktlim@umich.eduLSQ<Impl>::DcachePort::setPeer(Port *port) 404192Sktlim@umich.edu{ 414192Sktlim@umich.edu Port::setPeer(port); 424192Sktlim@umich.edu 434192Sktlim@umich.edu#if FULL_SYSTEM 444192Sktlim@umich.edu // Update the ThreadContext's memory ports (Functional/Virtual 454192Sktlim@umich.edu // Ports) 464192Sktlim@umich.edu lsq->updateMemPorts(); 474192Sktlim@umich.edu#endif 484192Sktlim@umich.edu} 494192Sktlim@umich.edu 502292SN/Atemplate <class Impl> 512907Sktlim@umich.eduTick 522907Sktlim@umich.eduLSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt) 532907Sktlim@umich.edu{ 542907Sktlim@umich.edu panic("O3CPU model does not work with atomic mode!"); 552907Sktlim@umich.edu return curTick; 562907Sktlim@umich.edu} 572907Sktlim@umich.edu 582907Sktlim@umich.edutemplate <class Impl> 592907Sktlim@umich.eduvoid 602907Sktlim@umich.eduLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt) 612907Sktlim@umich.edu{ 623639Sktlim@umich.edu DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional."); 632907Sktlim@umich.edu} 642907Sktlim@umich.edu 652907Sktlim@umich.edutemplate <class Impl> 662907Sktlim@umich.eduvoid 672907Sktlim@umich.eduLSQ<Impl>::DcachePort::recvStatusChange(Status status) 682907Sktlim@umich.edu{ 693647Srdreslin@umich.edu if (status == RangeChange) { 703647Srdreslin@umich.edu if (!snoopRangeSent) { 713647Srdreslin@umich.edu snoopRangeSent = true; 723647Srdreslin@umich.edu sendStatusChange(Port::RangeChange); 733647Srdreslin@umich.edu } 742907Sktlim@umich.edu return; 753647Srdreslin@umich.edu } 762907Sktlim@umich.edu panic("O3CPU doesn't expect recvStatusChange callback!"); 772907Sktlim@umich.edu} 782907Sktlim@umich.edu 792907Sktlim@umich.edutemplate <class Impl> 802907Sktlim@umich.edubool 812907Sktlim@umich.eduLSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt) 822907Sktlim@umich.edu{ 833310Srdreslin@umich.edu if (pkt->isResponse()) { 843310Srdreslin@umich.edu lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt); 853310Srdreslin@umich.edu } 863310Srdreslin@umich.edu else { 874895Sstever@eecs.umich.edu // must be a snoop 884895Sstever@eecs.umich.edu 894895Sstever@eecs.umich.edu // @TODO someday may need to process invalidations in LSQ here 904895Sstever@eecs.umich.edu // to provide stronger consistency model 913310Srdreslin@umich.edu } 922907Sktlim@umich.edu return true; 932907Sktlim@umich.edu} 942907Sktlim@umich.edu 952907Sktlim@umich.edutemplate <class Impl> 962907Sktlim@umich.eduvoid 972907Sktlim@umich.eduLSQ<Impl>::DcachePort::recvRetry() 982907Sktlim@umich.edu{ 993014Srdreslin@umich.edu if (lsq->retryTid == -1) 1003014Srdreslin@umich.edu { 1013014Srdreslin@umich.edu //Squashed, so drop it 1023014Srdreslin@umich.edu return; 1033014Srdreslin@umich.edu } 1044985Sktlim@umich.edu int curr_retry_tid = lsq->retryTid; 1052907Sktlim@umich.edu // Speculatively clear the retry Tid. This will get set again if 1062907Sktlim@umich.edu // the LSQUnit was unable to complete its access. 1072907Sktlim@umich.edu lsq->retryTid = -1; 1084985Sktlim@umich.edu lsq->thread[curr_retry_tid].recvRetry(); 1092907Sktlim@umich.edu} 1102907Sktlim@umich.edu 1112907Sktlim@umich.edutemplate <class Impl> 1124329Sktlim@umich.eduLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params) 1134329Sktlim@umich.edu : cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this), 1144329Sktlim@umich.edu LQEntries(params->LQEntries), 1154329Sktlim@umich.edu SQEntries(params->SQEntries), 1164329Sktlim@umich.edu numThreads(params->numberOfThreads), 1172907Sktlim@umich.edu retryTid(-1) 1182292SN/A{ 1193647Srdreslin@umich.edu dcachePort.snoopRangeSent = false; 1203647Srdreslin@umich.edu 1212292SN/A //**********************************************/ 1222292SN/A //************ Handle SMT Parameters ***********/ 1232292SN/A //**********************************************/ 1242980Sgblack@eecs.umich.edu std::string policy = params->smtLSQPolicy; 1252292SN/A 1262292SN/A //Convert string to lowercase 1272292SN/A std::transform(policy.begin(), policy.end(), policy.begin(), 1282292SN/A (int(*)(int)) tolower); 1292292SN/A 1302292SN/A //Figure out fetch policy 1312292SN/A if (policy == "dynamic") { 1322292SN/A lsqPolicy = Dynamic; 1332292SN/A 1342292SN/A maxLQEntries = LQEntries; 1352292SN/A maxSQEntries = SQEntries; 1364329Sktlim@umich.edu 1372292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 1382292SN/A } else if (policy == "partitioned") { 1392292SN/A lsqPolicy = Partitioned; 1402292SN/A 1412292SN/A //@todo:make work if part_amt doesnt divide evenly. 1422292SN/A maxLQEntries = LQEntries / numThreads; 1432292SN/A maxSQEntries = SQEntries / numThreads; 1444329Sktlim@umich.edu 1452292SN/A DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 1462292SN/A "%i entries per LQ | %i entries per SQ", 1472292SN/A maxLQEntries,maxSQEntries); 1482292SN/A } else if (policy == "threshold") { 1492292SN/A lsqPolicy = Threshold; 1502292SN/A 1512292SN/A assert(params->smtLSQThreshold > LQEntries); 1522292SN/A assert(params->smtLSQThreshold > SQEntries); 1532292SN/A 1542292SN/A //Divide up by threshold amount 1552292SN/A //@todo: Should threads check the max and the total 1562292SN/A //amount of the LSQ 1572292SN/A maxLQEntries = params->smtLSQThreshold; 1582292SN/A maxSQEntries = params->smtLSQThreshold; 1594329Sktlim@umich.edu 1602292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 1612292SN/A "%i entries per LQ | %i entries per SQ", 1622292SN/A maxLQEntries,maxSQEntries); 1632292SN/A } else { 1642292SN/A assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," 1652292SN/A "Partitioned, Threshold}"); 1662292SN/A } 1672292SN/A 1682292SN/A //Initialize LSQs 1692292SN/A for (int tid=0; tid < numThreads; tid++) { 1704329Sktlim@umich.edu thread[tid].init(cpu, iew_ptr, params, this, 1714329Sktlim@umich.edu maxLQEntries, maxSQEntries, tid); 1722907Sktlim@umich.edu thread[tid].setDcachePort(&dcachePort); 1732292SN/A } 1742292SN/A} 1752292SN/A 1762292SN/A 1772292SN/Atemplate<class Impl> 1782292SN/Astd::string 1792292SN/ALSQ<Impl>::name() const 1802292SN/A{ 1812292SN/A return iewStage->name() + ".lsq"; 1822292SN/A} 1832292SN/A 1842292SN/Atemplate<class Impl> 1852292SN/Avoid 1862727Sktlim@umich.eduLSQ<Impl>::regStats() 1872727Sktlim@umich.edu{ 1882727Sktlim@umich.edu //Initialize LSQs 1892727Sktlim@umich.edu for (int tid=0; tid < numThreads; tid++) { 1902727Sktlim@umich.edu thread[tid].regStats(); 1912727Sktlim@umich.edu } 1922727Sktlim@umich.edu} 1932727Sktlim@umich.edu 1942727Sktlim@umich.edutemplate<class Impl> 1952727Sktlim@umich.eduvoid 1962980Sgblack@eecs.umich.eduLSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) 1972292SN/A{ 1982292SN/A activeThreads = at_ptr; 1992292SN/A assert(activeThreads != 0); 2002292SN/A} 2012292SN/A 2022292SN/Atemplate <class Impl> 2032307SN/Avoid 2042307SN/ALSQ<Impl>::switchOut() 2052307SN/A{ 2062307SN/A for (int tid = 0; tid < numThreads; tid++) { 2072307SN/A thread[tid].switchOut(); 2082307SN/A } 2092307SN/A} 2102307SN/A 2112307SN/Atemplate <class Impl> 2122307SN/Avoid 2132307SN/ALSQ<Impl>::takeOverFrom() 2142307SN/A{ 2152307SN/A for (int tid = 0; tid < numThreads; tid++) { 2162307SN/A thread[tid].takeOverFrom(); 2172307SN/A } 2182307SN/A} 2192307SN/A 2202307SN/Atemplate <class Impl> 2212292SN/Aint 2222292SN/ALSQ<Impl>::entryAmount(int num_threads) 2232292SN/A{ 2242292SN/A if (lsqPolicy == Partitioned) { 2252292SN/A return LQEntries / num_threads; 2262292SN/A } else { 2272292SN/A return 0; 2282292SN/A } 2292292SN/A} 2302292SN/A 2312292SN/Atemplate <class Impl> 2322292SN/Avoid 2332292SN/ALSQ<Impl>::resetEntries() 2342292SN/A{ 2352292SN/A if (lsqPolicy != Dynamic || numThreads > 1) { 2363867Sbinkertn@umich.edu int active_threads = activeThreads->size(); 2372292SN/A 2382292SN/A int maxEntries; 2392292SN/A 2402292SN/A if (lsqPolicy == Partitioned) { 2412292SN/A maxEntries = LQEntries / active_threads; 2422292SN/A } else if (lsqPolicy == Threshold && active_threads == 1) { 2432292SN/A maxEntries = LQEntries; 2442292SN/A } else { 2452292SN/A maxEntries = LQEntries; 2462292SN/A } 2472292SN/A 2483867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 2493867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 2503867Sbinkertn@umich.edu 2513867Sbinkertn@umich.edu while (threads != end) { 2523867Sbinkertn@umich.edu unsigned tid = *threads++; 2533867Sbinkertn@umich.edu 2543867Sbinkertn@umich.edu resizeEntries(maxEntries, tid); 2552292SN/A } 2562292SN/A } 2572292SN/A} 2582292SN/A 2592292SN/Atemplate<class Impl> 2602292SN/Avoid 2612292SN/ALSQ<Impl>::removeEntries(unsigned tid) 2622292SN/A{ 2632292SN/A thread[tid].clearLQ(); 2642292SN/A thread[tid].clearSQ(); 2652292SN/A} 2662292SN/A 2672292SN/Atemplate<class Impl> 2682292SN/Avoid 2692292SN/ALSQ<Impl>::resizeEntries(unsigned size,unsigned tid) 2702292SN/A{ 2712292SN/A thread[tid].resizeLQ(size); 2722292SN/A thread[tid].resizeSQ(size); 2732292SN/A} 2742292SN/A 2752292SN/Atemplate<class Impl> 2762292SN/Avoid 2772292SN/ALSQ<Impl>::tick() 2782292SN/A{ 2793867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 2803867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 2812292SN/A 2823867Sbinkertn@umich.edu while (threads != end) { 2833867Sbinkertn@umich.edu unsigned tid = *threads++; 2842292SN/A 2852292SN/A thread[tid].tick(); 2862292SN/A } 2872292SN/A} 2882292SN/A 2892292SN/Atemplate<class Impl> 2902292SN/Avoid 2912292SN/ALSQ<Impl>::insertLoad(DynInstPtr &load_inst) 2922292SN/A{ 2932292SN/A unsigned tid = load_inst->threadNumber; 2942292SN/A 2952292SN/A thread[tid].insertLoad(load_inst); 2962292SN/A} 2972292SN/A 2982292SN/Atemplate<class Impl> 2992292SN/Avoid 3002292SN/ALSQ<Impl>::insertStore(DynInstPtr &store_inst) 3012292SN/A{ 3022292SN/A unsigned tid = store_inst->threadNumber; 3032292SN/A 3042292SN/A thread[tid].insertStore(store_inst); 3052292SN/A} 3062292SN/A 3072292SN/Atemplate<class Impl> 3082292SN/AFault 3092292SN/ALSQ<Impl>::executeLoad(DynInstPtr &inst) 3102292SN/A{ 3112292SN/A unsigned tid = inst->threadNumber; 3122292SN/A 3132292SN/A return thread[tid].executeLoad(inst); 3142292SN/A} 3152292SN/A 3162292SN/Atemplate<class Impl> 3172292SN/AFault 3182292SN/ALSQ<Impl>::executeStore(DynInstPtr &inst) 3192292SN/A{ 3202292SN/A unsigned tid = inst->threadNumber; 3212292SN/A 3222292SN/A return thread[tid].executeStore(inst); 3232292SN/A} 3242292SN/A 3252292SN/Atemplate<class Impl> 3262292SN/Avoid 3272292SN/ALSQ<Impl>::writebackStores() 3282292SN/A{ 3293867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 3303867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 3312292SN/A 3323867Sbinkertn@umich.edu while (threads != end) { 3333867Sbinkertn@umich.edu unsigned tid = *threads++; 3342292SN/A 3352292SN/A if (numStoresToWB(tid) > 0) { 3362329SN/A DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 3372329SN/A "available for Writeback.\n", tid, numStoresToWB(tid)); 3382292SN/A } 3392292SN/A 3402292SN/A thread[tid].writebackStores(); 3412292SN/A } 3422292SN/A} 3432292SN/A 3442292SN/Atemplate<class Impl> 3452292SN/Abool 3462292SN/ALSQ<Impl>::violation() 3472292SN/A{ 3482292SN/A /* Answers: Does Anybody Have a Violation?*/ 3493867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 3503867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 3512292SN/A 3523867Sbinkertn@umich.edu while (threads != end) { 3533867Sbinkertn@umich.edu unsigned tid = *threads++; 3543867Sbinkertn@umich.edu 3552292SN/A if (thread[tid].violation()) 3562292SN/A return true; 3572292SN/A } 3582292SN/A 3592292SN/A return false; 3602292SN/A} 3612292SN/A 3622292SN/Atemplate<class Impl> 3632292SN/Aint 3642292SN/ALSQ<Impl>::getCount() 3652292SN/A{ 3662292SN/A unsigned total = 0; 3672292SN/A 3683867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 3693867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 3702292SN/A 3713867Sbinkertn@umich.edu while (threads != end) { 3723867Sbinkertn@umich.edu unsigned tid = *threads++; 3733867Sbinkertn@umich.edu 3742292SN/A total += getCount(tid); 3752292SN/A } 3762292SN/A 3772292SN/A return total; 3782292SN/A} 3792292SN/A 3802292SN/Atemplate<class Impl> 3812292SN/Aint 3822292SN/ALSQ<Impl>::numLoads() 3832292SN/A{ 3842292SN/A unsigned total = 0; 3852292SN/A 3863867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 3873867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 3882292SN/A 3893867Sbinkertn@umich.edu while (threads != end) { 3903867Sbinkertn@umich.edu unsigned tid = *threads++; 3913867Sbinkertn@umich.edu 3922292SN/A total += numLoads(tid); 3932292SN/A } 3942292SN/A 3952292SN/A return total; 3962292SN/A} 3972292SN/A 3982292SN/Atemplate<class Impl> 3992292SN/Aint 4002292SN/ALSQ<Impl>::numStores() 4012292SN/A{ 4022292SN/A unsigned total = 0; 4032292SN/A 4043867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 4053867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 4062292SN/A 4073867Sbinkertn@umich.edu while (threads != end) { 4083867Sbinkertn@umich.edu unsigned tid = *threads++; 4093867Sbinkertn@umich.edu 4102292SN/A total += thread[tid].numStores(); 4112292SN/A } 4122292SN/A 4132292SN/A return total; 4142292SN/A} 4152292SN/A 4162292SN/Atemplate<class Impl> 4172292SN/Aint 4182292SN/ALSQ<Impl>::numLoadsReady() 4192292SN/A{ 4202292SN/A unsigned total = 0; 4212292SN/A 4223867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 4233867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 4242292SN/A 4253867Sbinkertn@umich.edu while (threads != end) { 4263867Sbinkertn@umich.edu unsigned tid = *threads++; 4273867Sbinkertn@umich.edu 4282292SN/A total += thread[tid].numLoadsReady(); 4292292SN/A } 4302292SN/A 4312292SN/A return total; 4322292SN/A} 4332292SN/A 4342292SN/Atemplate<class Impl> 4352292SN/Aunsigned 4362292SN/ALSQ<Impl>::numFreeEntries() 4372292SN/A{ 4382292SN/A unsigned total = 0; 4392292SN/A 4403867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 4413867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 4422292SN/A 4433867Sbinkertn@umich.edu while (threads != end) { 4443867Sbinkertn@umich.edu unsigned tid = *threads++; 4453867Sbinkertn@umich.edu 4462292SN/A total += thread[tid].numFreeEntries(); 4472292SN/A } 4482292SN/A 4492292SN/A return total; 4502292SN/A} 4512292SN/A 4522292SN/Atemplate<class Impl> 4532292SN/Aunsigned 4542292SN/ALSQ<Impl>::numFreeEntries(unsigned tid) 4552292SN/A{ 4563870Sbinkertn@umich.edu //if (lsqPolicy == Dynamic) 4572292SN/A //return numFreeEntries(); 4582292SN/A //else 4592292SN/A return thread[tid].numFreeEntries(); 4602292SN/A} 4612292SN/A 4622292SN/Atemplate<class Impl> 4632292SN/Abool 4642292SN/ALSQ<Impl>::isFull() 4652292SN/A{ 4663867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 4673867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 4682292SN/A 4693867Sbinkertn@umich.edu while (threads != end) { 4703867Sbinkertn@umich.edu unsigned tid = *threads++; 4713867Sbinkertn@umich.edu 4723867Sbinkertn@umich.edu if (!(thread[tid].lqFull() || thread[tid].sqFull())) 4732292SN/A return false; 4742292SN/A } 4752292SN/A 4762292SN/A return true; 4772292SN/A} 4782292SN/A 4792292SN/Atemplate<class Impl> 4802292SN/Abool 4812292SN/ALSQ<Impl>::isFull(unsigned tid) 4822292SN/A{ 4832292SN/A //@todo: Change to Calculate All Entries for 4842292SN/A //Dynamic Policy 4853867Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 4862292SN/A return isFull(); 4872292SN/A else 4882292SN/A return thread[tid].lqFull() || thread[tid].sqFull(); 4892292SN/A} 4902292SN/A 4912292SN/Atemplate<class Impl> 4922292SN/Abool 4932292SN/ALSQ<Impl>::lqFull() 4942292SN/A{ 4953867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 4963867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 4972292SN/A 4983867Sbinkertn@umich.edu while (threads != end) { 4993867Sbinkertn@umich.edu unsigned tid = *threads++; 5003867Sbinkertn@umich.edu 5012292SN/A if (!thread[tid].lqFull()) 5022292SN/A return false; 5032292SN/A } 5042292SN/A 5052292SN/A return true; 5062292SN/A} 5072292SN/A 5082292SN/Atemplate<class Impl> 5092292SN/Abool 5102292SN/ALSQ<Impl>::lqFull(unsigned tid) 5112292SN/A{ 5122292SN/A //@todo: Change to Calculate All Entries for 5132292SN/A //Dynamic Policy 5143870Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 5152292SN/A return lqFull(); 5162292SN/A else 5172292SN/A return thread[tid].lqFull(); 5182292SN/A} 5192292SN/A 5202292SN/Atemplate<class Impl> 5212292SN/Abool 5222292SN/ALSQ<Impl>::sqFull() 5232292SN/A{ 5243867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 5253867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 5262292SN/A 5273867Sbinkertn@umich.edu while (threads != end) { 5283867Sbinkertn@umich.edu unsigned tid = *threads++; 5293867Sbinkertn@umich.edu 5302292SN/A if (!sqFull(tid)) 5312292SN/A return false; 5322292SN/A } 5332292SN/A 5342292SN/A return true; 5352292SN/A} 5362292SN/A 5372292SN/Atemplate<class Impl> 5382292SN/Abool 5392292SN/ALSQ<Impl>::sqFull(unsigned tid) 5402292SN/A{ 5412292SN/A //@todo: Change to Calculate All Entries for 5422292SN/A //Dynamic Policy 5433870Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 5442292SN/A return sqFull(); 5452292SN/A else 5462292SN/A return thread[tid].sqFull(); 5472292SN/A} 5482292SN/A 5492292SN/Atemplate<class Impl> 5502292SN/Abool 5512292SN/ALSQ<Impl>::isStalled() 5522292SN/A{ 5533867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 5543867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 5552292SN/A 5563867Sbinkertn@umich.edu while (threads != end) { 5573867Sbinkertn@umich.edu unsigned tid = *threads++; 5583867Sbinkertn@umich.edu 5592292SN/A if (!thread[tid].isStalled()) 5602292SN/A return false; 5612292SN/A } 5622292SN/A 5632292SN/A return true; 5642292SN/A} 5652292SN/A 5662292SN/Atemplate<class Impl> 5672292SN/Abool 5682292SN/ALSQ<Impl>::isStalled(unsigned tid) 5692292SN/A{ 5703870Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 5712292SN/A return isStalled(); 5722292SN/A else 5732292SN/A return thread[tid].isStalled(); 5742292SN/A} 5752292SN/A 5762292SN/Atemplate<class Impl> 5772292SN/Abool 5782292SN/ALSQ<Impl>::hasStoresToWB() 5792292SN/A{ 5803867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 5813867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 5822292SN/A 5833867Sbinkertn@umich.edu if (threads == end) 5842864Sktlim@umich.edu return false; 5852864Sktlim@umich.edu 5863867Sbinkertn@umich.edu while (threads != end) { 5873867Sbinkertn@umich.edu unsigned tid = *threads++; 5883867Sbinkertn@umich.edu 5892292SN/A if (!hasStoresToWB(tid)) 5902292SN/A return false; 5912292SN/A } 5922292SN/A 5932292SN/A return true; 5942292SN/A} 5952292SN/A 5962292SN/Atemplate<class Impl> 5972292SN/Abool 5982292SN/ALSQ<Impl>::willWB() 5992292SN/A{ 6003867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 6013867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 6022292SN/A 6033867Sbinkertn@umich.edu while (threads != end) { 6043867Sbinkertn@umich.edu unsigned tid = *threads++; 6053867Sbinkertn@umich.edu 6062292SN/A if (!willWB(tid)) 6072292SN/A return false; 6082292SN/A } 6092292SN/A 6102292SN/A return true; 6112292SN/A} 6122292SN/A 6132292SN/Atemplate<class Impl> 6142292SN/Avoid 6152292SN/ALSQ<Impl>::dumpInsts() 6162292SN/A{ 6173867Sbinkertn@umich.edu std::list<unsigned>::iterator threads = activeThreads->begin(); 6183867Sbinkertn@umich.edu std::list<unsigned>::iterator end = activeThreads->end(); 6192292SN/A 6203867Sbinkertn@umich.edu while (threads != end) { 6213867Sbinkertn@umich.edu unsigned tid = *threads++; 6223867Sbinkertn@umich.edu 6232292SN/A thread[tid].dumpInsts(); 6242292SN/A } 6252292SN/A} 626