lsq_impl.hh revision 9868
12292SN/A/* 28948Sandreas.hansson@arm.com * Copyright (c) 2011-2012 ARM Limited 38707Sandreas.hansson@arm.com * All rights reserved 48707Sandreas.hansson@arm.com * 58707Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68707Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78707Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88707Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98707Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108707Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118707Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128707Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 138707Sandreas.hansson@arm.com * 142727Sktlim@umich.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan 152292SN/A * All rights reserved. 162292SN/A * 172292SN/A * Redistribution and use in source and binary forms, with or without 182292SN/A * modification, are permitted provided that the following conditions are 192292SN/A * met: redistributions of source code must retain the above copyright 202292SN/A * notice, this list of conditions and the following disclaimer; 212292SN/A * redistributions in binary form must reproduce the above copyright 222292SN/A * notice, this list of conditions and the following disclaimer in the 232292SN/A * documentation and/or other materials provided with the distribution; 242292SN/A * neither the name of the copyright holders nor the names of its 252292SN/A * contributors may be used to endorse or promote products derived from 262292SN/A * this software without specific prior written permission. 272292SN/A * 282292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392689Sktlim@umich.edu * 402689Sktlim@umich.edu * Authors: Korey Sewell 412292SN/A */ 422292SN/A 432329SN/A#include <algorithm> 442980Sgblack@eecs.umich.edu#include <list> 452329SN/A#include <string> 462329SN/A 472292SN/A#include "cpu/o3/lsq.hh" 489444SAndreas.Sandberg@ARM.com#include "debug/Drain.hh" 498232Snate@binkert.org#include "debug/Fetch.hh" 508232Snate@binkert.org#include "debug/LSQ.hh" 518232Snate@binkert.org#include "debug/Writeback.hh" 526221Snate@binkert.org#include "params/DerivO3CPU.hh" 532292SN/A 546221Snate@binkert.orgusing namespace std; 555529Snate@binkert.org 562292SN/Atemplate <class Impl> 575529Snate@binkert.orgLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 588707Sandreas.hansson@arm.com : cpu(cpu_ptr), iewStage(iew_ptr), 594329Sktlim@umich.edu LQEntries(params->LQEntries), 604329Sktlim@umich.edu SQEntries(params->SQEntries), 615529Snate@binkert.org numThreads(params->numThreads), 622907Sktlim@umich.edu retryTid(-1) 632292SN/A{ 649868Sjthestness@gmail.com assert(numThreads > 0 && numThreads <= Impl::MaxThreads); 659868Sjthestness@gmail.com 662292SN/A //**********************************************/ 672292SN/A //************ Handle SMT Parameters ***********/ 682292SN/A //**********************************************/ 692980Sgblack@eecs.umich.edu std::string policy = params->smtLSQPolicy; 702292SN/A 712292SN/A //Convert string to lowercase 722292SN/A std::transform(policy.begin(), policy.end(), policy.begin(), 732292SN/A (int(*)(int)) tolower); 742292SN/A 752292SN/A //Figure out fetch policy 762292SN/A if (policy == "dynamic") { 772292SN/A lsqPolicy = Dynamic; 782292SN/A 792292SN/A maxLQEntries = LQEntries; 802292SN/A maxSQEntries = SQEntries; 814329Sktlim@umich.edu 822292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 832292SN/A } else if (policy == "partitioned") { 842292SN/A lsqPolicy = Partitioned; 852292SN/A 862292SN/A //@todo:make work if part_amt doesnt divide evenly. 872292SN/A maxLQEntries = LQEntries / numThreads; 882292SN/A maxSQEntries = SQEntries / numThreads; 894329Sktlim@umich.edu 902292SN/A DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 918346Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 922292SN/A maxLQEntries,maxSQEntries); 932292SN/A } else if (policy == "threshold") { 942292SN/A lsqPolicy = Threshold; 952292SN/A 962292SN/A assert(params->smtLSQThreshold > LQEntries); 972292SN/A assert(params->smtLSQThreshold > SQEntries); 982292SN/A 992292SN/A //Divide up by threshold amount 1002292SN/A //@todo: Should threads check the max and the total 1012292SN/A //amount of the LSQ 1022292SN/A maxLQEntries = params->smtLSQThreshold; 1032292SN/A maxSQEntries = params->smtLSQThreshold; 1044329Sktlim@umich.edu 1052292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 1068346Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 1072292SN/A maxLQEntries,maxSQEntries); 1082292SN/A } else { 1092292SN/A assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," 1102292SN/A "Partitioned, Threshold}"); 1112292SN/A } 1122292SN/A 1132292SN/A //Initialize LSQs 1149868Sjthestness@gmail.com thread = new LSQUnit[numThreads]; 1156221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1164329Sktlim@umich.edu thread[tid].init(cpu, iew_ptr, params, this, 1174329Sktlim@umich.edu maxLQEntries, maxSQEntries, tid); 1188850Sandreas.hansson@arm.com thread[tid].setDcachePort(&cpu_ptr->getDataPort()); 1192292SN/A } 1202292SN/A} 1212292SN/A 1222292SN/A 1232292SN/Atemplate<class Impl> 1242292SN/Astd::string 1252292SN/ALSQ<Impl>::name() const 1262292SN/A{ 1272292SN/A return iewStage->name() + ".lsq"; 1282292SN/A} 1292292SN/A 1302292SN/Atemplate<class Impl> 1312292SN/Avoid 1322727Sktlim@umich.eduLSQ<Impl>::regStats() 1332727Sktlim@umich.edu{ 1342727Sktlim@umich.edu //Initialize LSQs 1356221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1362727Sktlim@umich.edu thread[tid].regStats(); 1372727Sktlim@umich.edu } 1382727Sktlim@umich.edu} 1392727Sktlim@umich.edu 1402727Sktlim@umich.edutemplate<class Impl> 1412727Sktlim@umich.eduvoid 1426221Snate@binkert.orgLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1432292SN/A{ 1442292SN/A activeThreads = at_ptr; 1452292SN/A assert(activeThreads != 0); 1462292SN/A} 1472292SN/A 1482292SN/Atemplate <class Impl> 1492307SN/Avoid 1509444SAndreas.Sandberg@ARM.comLSQ<Impl>::drainSanityCheck() const 1512307SN/A{ 1529444SAndreas.Sandberg@ARM.com assert(isDrained()); 1539444SAndreas.Sandberg@ARM.com 1549444SAndreas.Sandberg@ARM.com for (ThreadID tid = 0; tid < numThreads; tid++) 1559444SAndreas.Sandberg@ARM.com thread[tid].drainSanityCheck(); 1569444SAndreas.Sandberg@ARM.com} 1579444SAndreas.Sandberg@ARM.com 1589444SAndreas.Sandberg@ARM.comtemplate <class Impl> 1599444SAndreas.Sandberg@ARM.combool 1609444SAndreas.Sandberg@ARM.comLSQ<Impl>::isDrained() const 1619444SAndreas.Sandberg@ARM.com{ 1629444SAndreas.Sandberg@ARM.com bool drained(true); 1639444SAndreas.Sandberg@ARM.com 1649444SAndreas.Sandberg@ARM.com if (!lqEmpty()) { 1659444SAndreas.Sandberg@ARM.com DPRINTF(Drain, "Not drained, LQ not empty.\n"); 1669444SAndreas.Sandberg@ARM.com drained = false; 1672307SN/A } 1689444SAndreas.Sandberg@ARM.com 1699444SAndreas.Sandberg@ARM.com if (!sqEmpty()) { 1709444SAndreas.Sandberg@ARM.com DPRINTF(Drain, "Not drained, SQ not empty.\n"); 1719444SAndreas.Sandberg@ARM.com drained = false; 1729444SAndreas.Sandberg@ARM.com } 1739444SAndreas.Sandberg@ARM.com 1749444SAndreas.Sandberg@ARM.com if (retryTid != InvalidThreadID) { 1759444SAndreas.Sandberg@ARM.com DPRINTF(Drain, "Not drained, the LSQ has blocked the caches.\n"); 1769444SAndreas.Sandberg@ARM.com drained = false; 1779444SAndreas.Sandberg@ARM.com } 1789444SAndreas.Sandberg@ARM.com 1799444SAndreas.Sandberg@ARM.com return drained; 1802307SN/A} 1812307SN/A 1822307SN/Atemplate <class Impl> 1832307SN/Avoid 1842307SN/ALSQ<Impl>::takeOverFrom() 1852307SN/A{ 1866221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1872307SN/A thread[tid].takeOverFrom(); 1882307SN/A } 1892307SN/A} 1902307SN/A 1912307SN/Atemplate <class Impl> 1922292SN/Aint 1936221Snate@binkert.orgLSQ<Impl>::entryAmount(ThreadID num_threads) 1942292SN/A{ 1952292SN/A if (lsqPolicy == Partitioned) { 1962292SN/A return LQEntries / num_threads; 1972292SN/A } else { 1982292SN/A return 0; 1992292SN/A } 2002292SN/A} 2012292SN/A 2022292SN/Atemplate <class Impl> 2032292SN/Avoid 2042292SN/ALSQ<Impl>::resetEntries() 2052292SN/A{ 2062292SN/A if (lsqPolicy != Dynamic || numThreads > 1) { 2073867Sbinkertn@umich.edu int active_threads = activeThreads->size(); 2082292SN/A 2092292SN/A int maxEntries; 2102292SN/A 2112292SN/A if (lsqPolicy == Partitioned) { 2122292SN/A maxEntries = LQEntries / active_threads; 2132292SN/A } else if (lsqPolicy == Threshold && active_threads == 1) { 2142292SN/A maxEntries = LQEntries; 2152292SN/A } else { 2162292SN/A maxEntries = LQEntries; 2172292SN/A } 2182292SN/A 2196221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2206221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 2213867Sbinkertn@umich.edu 2223867Sbinkertn@umich.edu while (threads != end) { 2236221Snate@binkert.org ThreadID tid = *threads++; 2243867Sbinkertn@umich.edu 2253867Sbinkertn@umich.edu resizeEntries(maxEntries, tid); 2262292SN/A } 2272292SN/A } 2282292SN/A} 2292292SN/A 2302292SN/Atemplate<class Impl> 2312292SN/Avoid 2326221Snate@binkert.orgLSQ<Impl>::removeEntries(ThreadID tid) 2332292SN/A{ 2342292SN/A thread[tid].clearLQ(); 2352292SN/A thread[tid].clearSQ(); 2362292SN/A} 2372292SN/A 2382292SN/Atemplate<class Impl> 2392292SN/Avoid 2406221Snate@binkert.orgLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid) 2412292SN/A{ 2422292SN/A thread[tid].resizeLQ(size); 2432292SN/A thread[tid].resizeSQ(size); 2442292SN/A} 2452292SN/A 2462292SN/Atemplate<class Impl> 2472292SN/Avoid 2482292SN/ALSQ<Impl>::tick() 2492292SN/A{ 2506221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2516221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 2522292SN/A 2533867Sbinkertn@umich.edu while (threads != end) { 2546221Snate@binkert.org ThreadID tid = *threads++; 2552292SN/A 2562292SN/A thread[tid].tick(); 2572292SN/A } 2582292SN/A} 2592292SN/A 2602292SN/Atemplate<class Impl> 2612292SN/Avoid 2622292SN/ALSQ<Impl>::insertLoad(DynInstPtr &load_inst) 2632292SN/A{ 2646221Snate@binkert.org ThreadID tid = load_inst->threadNumber; 2652292SN/A 2662292SN/A thread[tid].insertLoad(load_inst); 2672292SN/A} 2682292SN/A 2692292SN/Atemplate<class Impl> 2702292SN/Avoid 2712292SN/ALSQ<Impl>::insertStore(DynInstPtr &store_inst) 2722292SN/A{ 2736221Snate@binkert.org ThreadID tid = store_inst->threadNumber; 2742292SN/A 2752292SN/A thread[tid].insertStore(store_inst); 2762292SN/A} 2772292SN/A 2782292SN/Atemplate<class Impl> 2792292SN/AFault 2802292SN/ALSQ<Impl>::executeLoad(DynInstPtr &inst) 2812292SN/A{ 2826221Snate@binkert.org ThreadID tid = inst->threadNumber; 2832292SN/A 2842292SN/A return thread[tid].executeLoad(inst); 2852292SN/A} 2862292SN/A 2872292SN/Atemplate<class Impl> 2882292SN/AFault 2892292SN/ALSQ<Impl>::executeStore(DynInstPtr &inst) 2902292SN/A{ 2916221Snate@binkert.org ThreadID tid = inst->threadNumber; 2922292SN/A 2932292SN/A return thread[tid].executeStore(inst); 2942292SN/A} 2952292SN/A 2962292SN/Atemplate<class Impl> 2972292SN/Avoid 2982292SN/ALSQ<Impl>::writebackStores() 2992292SN/A{ 3006221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3016221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3022292SN/A 3033867Sbinkertn@umich.edu while (threads != end) { 3046221Snate@binkert.org ThreadID tid = *threads++; 3052292SN/A 3062292SN/A if (numStoresToWB(tid) > 0) { 3072329SN/A DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 3082329SN/A "available for Writeback.\n", tid, numStoresToWB(tid)); 3092292SN/A } 3102292SN/A 3112292SN/A thread[tid].writebackStores(); 3122292SN/A } 3132292SN/A} 3142292SN/A 3152292SN/Atemplate<class Impl> 3162292SN/Abool 3172292SN/ALSQ<Impl>::violation() 3182292SN/A{ 3192292SN/A /* Answers: Does Anybody Have a Violation?*/ 3206221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3216221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3222292SN/A 3233867Sbinkertn@umich.edu while (threads != end) { 3246221Snate@binkert.org ThreadID tid = *threads++; 3253867Sbinkertn@umich.edu 3262292SN/A if (thread[tid].violation()) 3272292SN/A return true; 3282292SN/A } 3292292SN/A 3302292SN/A return false; 3312292SN/A} 3322292SN/A 3338707Sandreas.hansson@arm.comtemplate <class Impl> 3348707Sandreas.hansson@arm.comvoid 3358707Sandreas.hansson@arm.comLSQ<Impl>::recvRetry() 3368707Sandreas.hansson@arm.com{ 3378707Sandreas.hansson@arm.com if (retryTid == InvalidThreadID) 3388707Sandreas.hansson@arm.com { 3398707Sandreas.hansson@arm.com //Squashed, so drop it 3408707Sandreas.hansson@arm.com return; 3418707Sandreas.hansson@arm.com } 3428707Sandreas.hansson@arm.com int curr_retry_tid = retryTid; 3438707Sandreas.hansson@arm.com // Speculatively clear the retry Tid. This will get set again if 3448707Sandreas.hansson@arm.com // the LSQUnit was unable to complete its access. 3458707Sandreas.hansson@arm.com retryTid = -1; 3468707Sandreas.hansson@arm.com thread[curr_retry_tid].recvRetry(); 3478707Sandreas.hansson@arm.com} 3488707Sandreas.hansson@arm.com 3498707Sandreas.hansson@arm.comtemplate <class Impl> 3508707Sandreas.hansson@arm.combool 3518975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingResp(PacketPtr pkt) 3528707Sandreas.hansson@arm.com{ 3538707Sandreas.hansson@arm.com if (pkt->isError()) 3548707Sandreas.hansson@arm.com DPRINTF(LSQ, "Got error packet back for address: %#X\n", 3558707Sandreas.hansson@arm.com pkt->getAddr()); 3568948Sandreas.hansson@arm.com thread[pkt->req->threadId()].completeDataAccess(pkt); 3578948Sandreas.hansson@arm.com return true; 3588948Sandreas.hansson@arm.com} 3598707Sandreas.hansson@arm.com 3608948Sandreas.hansson@arm.comtemplate <class Impl> 3618975Sandreas.hansson@arm.comvoid 3628975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt) 3638948Sandreas.hansson@arm.com{ 3648948Sandreas.hansson@arm.com DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), 3658948Sandreas.hansson@arm.com pkt->cmdString()); 3668948Sandreas.hansson@arm.com 3678948Sandreas.hansson@arm.com // must be a snoop 3688948Sandreas.hansson@arm.com if (pkt->isInvalidate()) { 3698948Sandreas.hansson@arm.com DPRINTF(LSQ, "received invalidation for addr:%#x\n", 3708948Sandreas.hansson@arm.com pkt->getAddr()); 3718948Sandreas.hansson@arm.com for (ThreadID tid = 0; tid < numThreads; tid++) { 3728948Sandreas.hansson@arm.com thread[tid].checkSnoop(pkt); 3738707Sandreas.hansson@arm.com } 3748707Sandreas.hansson@arm.com } 3758707Sandreas.hansson@arm.com} 3768707Sandreas.hansson@arm.com 3772292SN/Atemplate<class Impl> 3782292SN/Aint 3792292SN/ALSQ<Impl>::getCount() 3802292SN/A{ 3812292SN/A unsigned total = 0; 3822292SN/A 3836221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3846221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3852292SN/A 3863867Sbinkertn@umich.edu while (threads != end) { 3876221Snate@binkert.org ThreadID tid = *threads++; 3883867Sbinkertn@umich.edu 3892292SN/A total += getCount(tid); 3902292SN/A } 3912292SN/A 3922292SN/A return total; 3932292SN/A} 3942292SN/A 3952292SN/Atemplate<class Impl> 3962292SN/Aint 3972292SN/ALSQ<Impl>::numLoads() 3982292SN/A{ 3992292SN/A unsigned total = 0; 4002292SN/A 4016221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4026221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4032292SN/A 4043867Sbinkertn@umich.edu while (threads != end) { 4056221Snate@binkert.org ThreadID tid = *threads++; 4063867Sbinkertn@umich.edu 4072292SN/A total += numLoads(tid); 4082292SN/A } 4092292SN/A 4102292SN/A return total; 4112292SN/A} 4122292SN/A 4132292SN/Atemplate<class Impl> 4142292SN/Aint 4152292SN/ALSQ<Impl>::numStores() 4162292SN/A{ 4172292SN/A unsigned total = 0; 4182292SN/A 4196221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4206221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4212292SN/A 4223867Sbinkertn@umich.edu while (threads != end) { 4236221Snate@binkert.org ThreadID tid = *threads++; 4243867Sbinkertn@umich.edu 4252292SN/A total += thread[tid].numStores(); 4262292SN/A } 4272292SN/A 4282292SN/A return total; 4292292SN/A} 4302292SN/A 4312292SN/Atemplate<class Impl> 4322292SN/Aunsigned 4332292SN/ALSQ<Impl>::numFreeEntries() 4342292SN/A{ 4352292SN/A unsigned total = 0; 4362292SN/A 4376221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4386221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4392292SN/A 4403867Sbinkertn@umich.edu while (threads != end) { 4416221Snate@binkert.org ThreadID tid = *threads++; 4423867Sbinkertn@umich.edu 4432292SN/A total += thread[tid].numFreeEntries(); 4442292SN/A } 4452292SN/A 4462292SN/A return total; 4472292SN/A} 4482292SN/A 4492292SN/Atemplate<class Impl> 4502292SN/Aunsigned 4516221Snate@binkert.orgLSQ<Impl>::numFreeEntries(ThreadID tid) 4522292SN/A{ 4533870Sbinkertn@umich.edu //if (lsqPolicy == Dynamic) 4542292SN/A //return numFreeEntries(); 4552292SN/A //else 4562292SN/A return thread[tid].numFreeEntries(); 4572292SN/A} 4582292SN/A 4592292SN/Atemplate<class Impl> 4602292SN/Abool 4612292SN/ALSQ<Impl>::isFull() 4622292SN/A{ 4636221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4646221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4652292SN/A 4663867Sbinkertn@umich.edu while (threads != end) { 4676221Snate@binkert.org ThreadID tid = *threads++; 4683867Sbinkertn@umich.edu 4693867Sbinkertn@umich.edu if (!(thread[tid].lqFull() || thread[tid].sqFull())) 4702292SN/A return false; 4712292SN/A } 4722292SN/A 4732292SN/A return true; 4742292SN/A} 4752292SN/A 4762292SN/Atemplate<class Impl> 4772292SN/Abool 4786221Snate@binkert.orgLSQ<Impl>::isFull(ThreadID tid) 4792292SN/A{ 4802292SN/A //@todo: Change to Calculate All Entries for 4812292SN/A //Dynamic Policy 4823867Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 4832292SN/A return isFull(); 4842292SN/A else 4852292SN/A return thread[tid].lqFull() || thread[tid].sqFull(); 4862292SN/A} 4872292SN/A 4882292SN/Atemplate<class Impl> 4892292SN/Abool 4909444SAndreas.Sandberg@ARM.comLSQ<Impl>::isEmpty() const 4919444SAndreas.Sandberg@ARM.com{ 4929444SAndreas.Sandberg@ARM.com return lqEmpty() && sqEmpty(); 4939444SAndreas.Sandberg@ARM.com} 4949444SAndreas.Sandberg@ARM.com 4959444SAndreas.Sandberg@ARM.comtemplate<class Impl> 4969444SAndreas.Sandberg@ARM.combool 4979444SAndreas.Sandberg@ARM.comLSQ<Impl>::lqEmpty() const 4989444SAndreas.Sandberg@ARM.com{ 4999444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 5009444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 5019444SAndreas.Sandberg@ARM.com 5029444SAndreas.Sandberg@ARM.com while (threads != end) { 5039444SAndreas.Sandberg@ARM.com ThreadID tid = *threads++; 5049444SAndreas.Sandberg@ARM.com 5059444SAndreas.Sandberg@ARM.com if (!thread[tid].lqEmpty()) 5069444SAndreas.Sandberg@ARM.com return false; 5079444SAndreas.Sandberg@ARM.com } 5089444SAndreas.Sandberg@ARM.com 5099444SAndreas.Sandberg@ARM.com return true; 5109444SAndreas.Sandberg@ARM.com} 5119444SAndreas.Sandberg@ARM.com 5129444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5139444SAndreas.Sandberg@ARM.combool 5149444SAndreas.Sandberg@ARM.comLSQ<Impl>::sqEmpty() const 5159444SAndreas.Sandberg@ARM.com{ 5169444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 5179444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 5189444SAndreas.Sandberg@ARM.com 5199444SAndreas.Sandberg@ARM.com while (threads != end) { 5209444SAndreas.Sandberg@ARM.com ThreadID tid = *threads++; 5219444SAndreas.Sandberg@ARM.com 5229444SAndreas.Sandberg@ARM.com if (!thread[tid].sqEmpty()) 5239444SAndreas.Sandberg@ARM.com return false; 5249444SAndreas.Sandberg@ARM.com } 5259444SAndreas.Sandberg@ARM.com 5269444SAndreas.Sandberg@ARM.com return true; 5279444SAndreas.Sandberg@ARM.com} 5289444SAndreas.Sandberg@ARM.com 5299444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5309444SAndreas.Sandberg@ARM.combool 5312292SN/ALSQ<Impl>::lqFull() 5322292SN/A{ 5336221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5346221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5352292SN/A 5363867Sbinkertn@umich.edu while (threads != end) { 5376221Snate@binkert.org ThreadID tid = *threads++; 5383867Sbinkertn@umich.edu 5392292SN/A if (!thread[tid].lqFull()) 5402292SN/A return false; 5412292SN/A } 5422292SN/A 5432292SN/A return true; 5442292SN/A} 5452292SN/A 5462292SN/Atemplate<class Impl> 5472292SN/Abool 5486221Snate@binkert.orgLSQ<Impl>::lqFull(ThreadID tid) 5492292SN/A{ 5502292SN/A //@todo: Change to Calculate All Entries for 5512292SN/A //Dynamic Policy 5523870Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 5532292SN/A return lqFull(); 5542292SN/A else 5552292SN/A return thread[tid].lqFull(); 5562292SN/A} 5572292SN/A 5582292SN/Atemplate<class Impl> 5592292SN/Abool 5602292SN/ALSQ<Impl>::sqFull() 5612292SN/A{ 5626221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5636221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5642292SN/A 5653867Sbinkertn@umich.edu while (threads != end) { 5666221Snate@binkert.org ThreadID tid = *threads++; 5673867Sbinkertn@umich.edu 5682292SN/A if (!sqFull(tid)) 5692292SN/A return false; 5702292SN/A } 5712292SN/A 5722292SN/A return true; 5732292SN/A} 5742292SN/A 5752292SN/Atemplate<class Impl> 5762292SN/Abool 5776221Snate@binkert.orgLSQ<Impl>::sqFull(ThreadID tid) 5782292SN/A{ 5792292SN/A //@todo: Change to Calculate All Entries for 5802292SN/A //Dynamic Policy 5813870Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 5822292SN/A return sqFull(); 5832292SN/A else 5842292SN/A return thread[tid].sqFull(); 5852292SN/A} 5862292SN/A 5872292SN/Atemplate<class Impl> 5882292SN/Abool 5892292SN/ALSQ<Impl>::isStalled() 5902292SN/A{ 5916221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5926221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5932292SN/A 5943867Sbinkertn@umich.edu while (threads != end) { 5956221Snate@binkert.org ThreadID tid = *threads++; 5963867Sbinkertn@umich.edu 5972292SN/A if (!thread[tid].isStalled()) 5982292SN/A return false; 5992292SN/A } 6002292SN/A 6012292SN/A return true; 6022292SN/A} 6032292SN/A 6042292SN/Atemplate<class Impl> 6052292SN/Abool 6066221Snate@binkert.orgLSQ<Impl>::isStalled(ThreadID tid) 6072292SN/A{ 6083870Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 6092292SN/A return isStalled(); 6102292SN/A else 6112292SN/A return thread[tid].isStalled(); 6122292SN/A} 6132292SN/A 6142292SN/Atemplate<class Impl> 6152292SN/Abool 6162292SN/ALSQ<Impl>::hasStoresToWB() 6172292SN/A{ 6186221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6196221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6202292SN/A 6213867Sbinkertn@umich.edu while (threads != end) { 6226221Snate@binkert.org ThreadID tid = *threads++; 6233867Sbinkertn@umich.edu 6245557Sktlim@umich.edu if (hasStoresToWB(tid)) 6255557Sktlim@umich.edu return true; 6262292SN/A } 6272292SN/A 6285557Sktlim@umich.edu return false; 6292292SN/A} 6302292SN/A 6312292SN/Atemplate<class Impl> 6322292SN/Abool 6332292SN/ALSQ<Impl>::willWB() 6342292SN/A{ 6356221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6366221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6372292SN/A 6383867Sbinkertn@umich.edu while (threads != end) { 6396221Snate@binkert.org ThreadID tid = *threads++; 6403867Sbinkertn@umich.edu 6415557Sktlim@umich.edu if (willWB(tid)) 6425557Sktlim@umich.edu return true; 6432292SN/A } 6442292SN/A 6455557Sktlim@umich.edu return false; 6462292SN/A} 6472292SN/A 6482292SN/Atemplate<class Impl> 6492292SN/Avoid 6509440SAndreas.Sandberg@ARM.comLSQ<Impl>::dumpInsts() const 6512292SN/A{ 6529440SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 6539440SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 6542292SN/A 6553867Sbinkertn@umich.edu while (threads != end) { 6566221Snate@binkert.org ThreadID tid = *threads++; 6573867Sbinkertn@umich.edu 6582292SN/A thread[tid].dumpInsts(); 6592292SN/A } 6602292SN/A} 661