lsq_impl.hh revision 11435
12292SN/A/* 210333Smitch.hayenga@arm.com * Copyright (c) 2011-2012, 2014 ARM Limited 310239Sbinhpham@cs.rutgers.edu * Copyright (c) 2013 Advanced Micro Devices, Inc. 48707Sandreas.hansson@arm.com * All rights reserved 58707Sandreas.hansson@arm.com * 68707Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 78707Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 88707Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 98707Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 108707Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 118707Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 128707Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 138707Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 148707Sandreas.hansson@arm.com * 152727Sktlim@umich.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan 162292SN/A * All rights reserved. 172292SN/A * 182292SN/A * Redistribution and use in source and binary forms, with or without 192292SN/A * modification, are permitted provided that the following conditions are 202292SN/A * met: redistributions of source code must retain the above copyright 212292SN/A * notice, this list of conditions and the following disclaimer; 222292SN/A * redistributions in binary form must reproduce the above copyright 232292SN/A * notice, this list of conditions and the following disclaimer in the 242292SN/A * documentation and/or other materials provided with the distribution; 252292SN/A * neither the name of the copyright holders nor the names of its 262292SN/A * contributors may be used to endorse or promote products derived from 272292SN/A * this software without specific prior written permission. 282292SN/A * 292292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402689Sktlim@umich.edu * 412689Sktlim@umich.edu * Authors: Korey Sewell 422292SN/A */ 432292SN/A 449944Smatt.horsnell@ARM.com#ifndef __CPU_O3_LSQ_IMPL_HH__ 459944Smatt.horsnell@ARM.com#define __CPU_O3_LSQ_IMPL_HH__ 469944Smatt.horsnell@ARM.com 472329SN/A#include <algorithm> 482980Sgblack@eecs.umich.edu#include <list> 492329SN/A#include <string> 502329SN/A 512292SN/A#include "cpu/o3/lsq.hh" 529444SAndreas.Sandberg@ARM.com#include "debug/Drain.hh" 538232Snate@binkert.org#include "debug/Fetch.hh" 548232Snate@binkert.org#include "debug/LSQ.hh" 558232Snate@binkert.org#include "debug/Writeback.hh" 566221Snate@binkert.org#include "params/DerivO3CPU.hh" 572292SN/A 586221Snate@binkert.orgusing namespace std; 595529Snate@binkert.org 602292SN/Atemplate <class Impl> 615529Snate@binkert.orgLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 628707Sandreas.hansson@arm.com : cpu(cpu_ptr), iewStage(iew_ptr), 634329Sktlim@umich.edu LQEntries(params->LQEntries), 644329Sktlim@umich.edu SQEntries(params->SQEntries), 6510333Smitch.hayenga@arm.com numThreads(params->numThreads) 662292SN/A{ 679868Sjthestness@gmail.com assert(numThreads > 0 && numThreads <= Impl::MaxThreads); 689868Sjthestness@gmail.com 692292SN/A //**********************************************/ 702292SN/A //************ Handle SMT Parameters ***********/ 712292SN/A //**********************************************/ 722980Sgblack@eecs.umich.edu std::string policy = params->smtLSQPolicy; 732292SN/A 742292SN/A //Convert string to lowercase 752292SN/A std::transform(policy.begin(), policy.end(), policy.begin(), 762292SN/A (int(*)(int)) tolower); 772292SN/A 782292SN/A //Figure out fetch policy 792292SN/A if (policy == "dynamic") { 802292SN/A lsqPolicy = Dynamic; 812292SN/A 822292SN/A maxLQEntries = LQEntries; 832292SN/A maxSQEntries = SQEntries; 844329Sktlim@umich.edu 852292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 862292SN/A } else if (policy == "partitioned") { 872292SN/A lsqPolicy = Partitioned; 882292SN/A 892292SN/A //@todo:make work if part_amt doesnt divide evenly. 902292SN/A maxLQEntries = LQEntries / numThreads; 912292SN/A maxSQEntries = SQEntries / numThreads; 924329Sktlim@umich.edu 932292SN/A DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 948346Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 952292SN/A maxLQEntries,maxSQEntries); 962292SN/A } else if (policy == "threshold") { 972292SN/A lsqPolicy = Threshold; 982292SN/A 992292SN/A assert(params->smtLSQThreshold > LQEntries); 1002292SN/A assert(params->smtLSQThreshold > SQEntries); 1012292SN/A 1022292SN/A //Divide up by threshold amount 1032292SN/A //@todo: Should threads check the max and the total 1042292SN/A //amount of the LSQ 1052292SN/A maxLQEntries = params->smtLSQThreshold; 1062292SN/A maxSQEntries = params->smtLSQThreshold; 1074329Sktlim@umich.edu 1082292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 1098346Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 1102292SN/A maxLQEntries,maxSQEntries); 1112292SN/A } else { 1122292SN/A assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," 1132292SN/A "Partitioned, Threshold}"); 1142292SN/A } 1152292SN/A 1162292SN/A //Initialize LSQs 1179868Sjthestness@gmail.com thread = new LSQUnit[numThreads]; 1186221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1194329Sktlim@umich.edu thread[tid].init(cpu, iew_ptr, params, this, 1204329Sktlim@umich.edu maxLQEntries, maxSQEntries, tid); 1218850Sandreas.hansson@arm.com thread[tid].setDcachePort(&cpu_ptr->getDataPort()); 1222292SN/A } 1232292SN/A} 1242292SN/A 1252292SN/A 1262292SN/Atemplate<class Impl> 1272292SN/Astd::string 1282292SN/ALSQ<Impl>::name() const 1292292SN/A{ 1302292SN/A return iewStage->name() + ".lsq"; 1312292SN/A} 1322292SN/A 1332292SN/Atemplate<class Impl> 1342292SN/Avoid 1352727Sktlim@umich.eduLSQ<Impl>::regStats() 1362727Sktlim@umich.edu{ 1372727Sktlim@umich.edu //Initialize LSQs 1386221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1392727Sktlim@umich.edu thread[tid].regStats(); 1402727Sktlim@umich.edu } 1412727Sktlim@umich.edu} 1422727Sktlim@umich.edu 1432727Sktlim@umich.edutemplate<class Impl> 1442727Sktlim@umich.eduvoid 1456221Snate@binkert.orgLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1462292SN/A{ 1472292SN/A activeThreads = at_ptr; 1482292SN/A assert(activeThreads != 0); 1492292SN/A} 1502292SN/A 1512292SN/Atemplate <class Impl> 1522307SN/Avoid 1539444SAndreas.Sandberg@ARM.comLSQ<Impl>::drainSanityCheck() const 1542307SN/A{ 1559444SAndreas.Sandberg@ARM.com assert(isDrained()); 1569444SAndreas.Sandberg@ARM.com 1579444SAndreas.Sandberg@ARM.com for (ThreadID tid = 0; tid < numThreads; tid++) 1589444SAndreas.Sandberg@ARM.com thread[tid].drainSanityCheck(); 1599444SAndreas.Sandberg@ARM.com} 1609444SAndreas.Sandberg@ARM.com 1619444SAndreas.Sandberg@ARM.comtemplate <class Impl> 1629444SAndreas.Sandberg@ARM.combool 1639444SAndreas.Sandberg@ARM.comLSQ<Impl>::isDrained() const 1649444SAndreas.Sandberg@ARM.com{ 1659444SAndreas.Sandberg@ARM.com bool drained(true); 1669444SAndreas.Sandberg@ARM.com 1679444SAndreas.Sandberg@ARM.com if (!lqEmpty()) { 1689444SAndreas.Sandberg@ARM.com DPRINTF(Drain, "Not drained, LQ not empty.\n"); 1699444SAndreas.Sandberg@ARM.com drained = false; 1702307SN/A } 1719444SAndreas.Sandberg@ARM.com 1729444SAndreas.Sandberg@ARM.com if (!sqEmpty()) { 1739444SAndreas.Sandberg@ARM.com DPRINTF(Drain, "Not drained, SQ not empty.\n"); 1749444SAndreas.Sandberg@ARM.com drained = false; 1759444SAndreas.Sandberg@ARM.com } 1769444SAndreas.Sandberg@ARM.com 1779444SAndreas.Sandberg@ARM.com return drained; 1782307SN/A} 1792307SN/A 1802307SN/Atemplate <class Impl> 1812307SN/Avoid 1822307SN/ALSQ<Impl>::takeOverFrom() 1832307SN/A{ 1846221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1852307SN/A thread[tid].takeOverFrom(); 1862307SN/A } 1872307SN/A} 1882307SN/A 1892307SN/Atemplate <class Impl> 1902292SN/Aint 1916221Snate@binkert.orgLSQ<Impl>::entryAmount(ThreadID num_threads) 1922292SN/A{ 1932292SN/A if (lsqPolicy == Partitioned) { 1942292SN/A return LQEntries / num_threads; 1952292SN/A } else { 1962292SN/A return 0; 1972292SN/A } 1982292SN/A} 1992292SN/A 2002292SN/Atemplate <class Impl> 2012292SN/Avoid 2022292SN/ALSQ<Impl>::resetEntries() 2032292SN/A{ 2042292SN/A if (lsqPolicy != Dynamic || numThreads > 1) { 2053867Sbinkertn@umich.edu int active_threads = activeThreads->size(); 2062292SN/A 2072292SN/A int maxEntries; 2082292SN/A 2092292SN/A if (lsqPolicy == Partitioned) { 2102292SN/A maxEntries = LQEntries / active_threads; 2112292SN/A } else if (lsqPolicy == Threshold && active_threads == 1) { 2122292SN/A maxEntries = LQEntries; 2132292SN/A } else { 2142292SN/A maxEntries = LQEntries; 2152292SN/A } 2162292SN/A 2176221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2186221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 2193867Sbinkertn@umich.edu 2203867Sbinkertn@umich.edu while (threads != end) { 2216221Snate@binkert.org ThreadID tid = *threads++; 2223867Sbinkertn@umich.edu 2233867Sbinkertn@umich.edu resizeEntries(maxEntries, tid); 2242292SN/A } 2252292SN/A } 2262292SN/A} 2272292SN/A 2282292SN/Atemplate<class Impl> 2292292SN/Avoid 2306221Snate@binkert.orgLSQ<Impl>::removeEntries(ThreadID tid) 2312292SN/A{ 2322292SN/A thread[tid].clearLQ(); 2332292SN/A thread[tid].clearSQ(); 2342292SN/A} 2352292SN/A 2362292SN/Atemplate<class Impl> 2372292SN/Avoid 2386221Snate@binkert.orgLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid) 2392292SN/A{ 2402292SN/A thread[tid].resizeLQ(size); 2412292SN/A thread[tid].resizeSQ(size); 2422292SN/A} 2432292SN/A 2442292SN/Atemplate<class Impl> 2452292SN/Avoid 2462292SN/ALSQ<Impl>::tick() 2472292SN/A{ 2486221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2496221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 2502292SN/A 2513867Sbinkertn@umich.edu while (threads != end) { 2526221Snate@binkert.org ThreadID tid = *threads++; 2532292SN/A 2542292SN/A thread[tid].tick(); 2552292SN/A } 2562292SN/A} 2572292SN/A 2582292SN/Atemplate<class Impl> 2592292SN/Avoid 2602292SN/ALSQ<Impl>::insertLoad(DynInstPtr &load_inst) 2612292SN/A{ 2626221Snate@binkert.org ThreadID tid = load_inst->threadNumber; 2632292SN/A 2642292SN/A thread[tid].insertLoad(load_inst); 2652292SN/A} 2662292SN/A 2672292SN/Atemplate<class Impl> 2682292SN/Avoid 2692292SN/ALSQ<Impl>::insertStore(DynInstPtr &store_inst) 2702292SN/A{ 2716221Snate@binkert.org ThreadID tid = store_inst->threadNumber; 2722292SN/A 2732292SN/A thread[tid].insertStore(store_inst); 2742292SN/A} 2752292SN/A 2762292SN/Atemplate<class Impl> 2772292SN/AFault 2782292SN/ALSQ<Impl>::executeLoad(DynInstPtr &inst) 2792292SN/A{ 2806221Snate@binkert.org ThreadID tid = inst->threadNumber; 2812292SN/A 2822292SN/A return thread[tid].executeLoad(inst); 2832292SN/A} 2842292SN/A 2852292SN/Atemplate<class Impl> 2862292SN/AFault 2872292SN/ALSQ<Impl>::executeStore(DynInstPtr &inst) 2882292SN/A{ 2896221Snate@binkert.org ThreadID tid = inst->threadNumber; 2902292SN/A 2912292SN/A return thread[tid].executeStore(inst); 2922292SN/A} 2932292SN/A 2942292SN/Atemplate<class Impl> 2952292SN/Avoid 2962292SN/ALSQ<Impl>::writebackStores() 2972292SN/A{ 2986221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2996221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3002292SN/A 3013867Sbinkertn@umich.edu while (threads != end) { 3026221Snate@binkert.org ThreadID tid = *threads++; 3032292SN/A 3042292SN/A if (numStoresToWB(tid) > 0) { 3052329SN/A DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 3062329SN/A "available for Writeback.\n", tid, numStoresToWB(tid)); 3072292SN/A } 3082292SN/A 3092292SN/A thread[tid].writebackStores(); 3102292SN/A } 3112292SN/A} 3122292SN/A 3132292SN/Atemplate<class Impl> 3142292SN/Abool 3152292SN/ALSQ<Impl>::violation() 3162292SN/A{ 3172292SN/A /* Answers: Does Anybody Have a Violation?*/ 3186221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3196221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3202292SN/A 3213867Sbinkertn@umich.edu while (threads != end) { 3226221Snate@binkert.org ThreadID tid = *threads++; 3233867Sbinkertn@umich.edu 3242292SN/A if (thread[tid].violation()) 3252292SN/A return true; 3262292SN/A } 3272292SN/A 3282292SN/A return false; 3292292SN/A} 3302292SN/A 3318707Sandreas.hansson@arm.comtemplate <class Impl> 3328707Sandreas.hansson@arm.comvoid 33310713Sandreas.hansson@arm.comLSQ<Impl>::recvReqRetry() 3348707Sandreas.hansson@arm.com{ 33510333Smitch.hayenga@arm.com iewStage->cacheUnblocked(); 33610333Smitch.hayenga@arm.com 33710333Smitch.hayenga@arm.com for (ThreadID tid : *activeThreads) { 33810333Smitch.hayenga@arm.com thread[tid].recvRetry(); 3398707Sandreas.hansson@arm.com } 3408707Sandreas.hansson@arm.com} 3418707Sandreas.hansson@arm.com 3428707Sandreas.hansson@arm.comtemplate <class Impl> 3438707Sandreas.hansson@arm.combool 3448975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingResp(PacketPtr pkt) 3458707Sandreas.hansson@arm.com{ 3468707Sandreas.hansson@arm.com if (pkt->isError()) 3478707Sandreas.hansson@arm.com DPRINTF(LSQ, "Got error packet back for address: %#X\n", 3488707Sandreas.hansson@arm.com pkt->getAddr()); 34910575SMarco.Elver@ARM.com 35011435Smitch.hayenga@arm.com thread[cpu->contextToThread(pkt->req->contextId())] 35111435Smitch.hayenga@arm.com .completeDataAccess(pkt); 35210575SMarco.Elver@ARM.com 35310575SMarco.Elver@ARM.com if (pkt->isInvalidate()) { 35410575SMarco.Elver@ARM.com // This response also contains an invalidate; e.g. this can be the case 35510575SMarco.Elver@ARM.com // if cmd is ReadRespWithInvalidate. 35610575SMarco.Elver@ARM.com // 35710575SMarco.Elver@ARM.com // The calling order between completeDataAccess and checkSnoop matters. 35810575SMarco.Elver@ARM.com // By calling checkSnoop after completeDataAccess, we ensure that the 35910575SMarco.Elver@ARM.com // fault set by checkSnoop is not lost. Calling writeback (more 36010575SMarco.Elver@ARM.com // specifically inst->completeAcc) in completeDataAccess overwrites 36110575SMarco.Elver@ARM.com // fault, and in case this instruction requires squashing (as 36210575SMarco.Elver@ARM.com // determined by checkSnoop), the ReExec fault set by checkSnoop would 36310575SMarco.Elver@ARM.com // be lost otherwise. 36410575SMarco.Elver@ARM.com 36510575SMarco.Elver@ARM.com DPRINTF(LSQ, "received invalidation with response for addr:%#x\n", 36610575SMarco.Elver@ARM.com pkt->getAddr()); 36710575SMarco.Elver@ARM.com 36810575SMarco.Elver@ARM.com for (ThreadID tid = 0; tid < numThreads; tid++) { 36910575SMarco.Elver@ARM.com thread[tid].checkSnoop(pkt); 37010575SMarco.Elver@ARM.com } 37110575SMarco.Elver@ARM.com } 37210575SMarco.Elver@ARM.com 37310573Sstephan.diestelhorst@arm.com delete pkt->req; 37410573Sstephan.diestelhorst@arm.com delete pkt; 3758948Sandreas.hansson@arm.com return true; 3768948Sandreas.hansson@arm.com} 3778707Sandreas.hansson@arm.com 3788948Sandreas.hansson@arm.comtemplate <class Impl> 3798975Sandreas.hansson@arm.comvoid 3808975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt) 3818948Sandreas.hansson@arm.com{ 3828948Sandreas.hansson@arm.com DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), 3838948Sandreas.hansson@arm.com pkt->cmdString()); 3848948Sandreas.hansson@arm.com 3858948Sandreas.hansson@arm.com // must be a snoop 3868948Sandreas.hansson@arm.com if (pkt->isInvalidate()) { 3878948Sandreas.hansson@arm.com DPRINTF(LSQ, "received invalidation for addr:%#x\n", 3888948Sandreas.hansson@arm.com pkt->getAddr()); 3898948Sandreas.hansson@arm.com for (ThreadID tid = 0; tid < numThreads; tid++) { 3908948Sandreas.hansson@arm.com thread[tid].checkSnoop(pkt); 3918707Sandreas.hansson@arm.com } 3928707Sandreas.hansson@arm.com } 3938707Sandreas.hansson@arm.com} 3948707Sandreas.hansson@arm.com 3952292SN/Atemplate<class Impl> 3962292SN/Aint 3972292SN/ALSQ<Impl>::getCount() 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 += getCount(tid); 4082292SN/A } 4092292SN/A 4102292SN/A return total; 4112292SN/A} 4122292SN/A 4132292SN/Atemplate<class Impl> 4142292SN/Aint 4152292SN/ALSQ<Impl>::numLoads() 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 += numLoads(tid); 4262292SN/A } 4272292SN/A 4282292SN/A return total; 4292292SN/A} 4302292SN/A 4312292SN/Atemplate<class Impl> 4322292SN/Aint 4332292SN/ALSQ<Impl>::numStores() 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].numStores(); 4442292SN/A } 4452292SN/A 4462292SN/A return total; 4472292SN/A} 4482292SN/A 4492292SN/Atemplate<class Impl> 4502292SN/Aunsigned 45110239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries() 4522292SN/A{ 4532292SN/A unsigned total = 0; 4542292SN/A 4556221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4566221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4572292SN/A 4583867Sbinkertn@umich.edu while (threads != end) { 4596221Snate@binkert.org ThreadID tid = *threads++; 4603867Sbinkertn@umich.edu 46110239Sbinhpham@cs.rutgers.edu total += thread[tid].numFreeLoadEntries(); 4622292SN/A } 4632292SN/A 4642292SN/A return total; 4652292SN/A} 4662292SN/A 4672292SN/Atemplate<class Impl> 4682292SN/Aunsigned 46910239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries() 4702292SN/A{ 47110239Sbinhpham@cs.rutgers.edu unsigned total = 0; 47210239Sbinhpham@cs.rutgers.edu 47310239Sbinhpham@cs.rutgers.edu list<ThreadID>::iterator threads = activeThreads->begin(); 47410239Sbinhpham@cs.rutgers.edu list<ThreadID>::iterator end = activeThreads->end(); 47510239Sbinhpham@cs.rutgers.edu 47610239Sbinhpham@cs.rutgers.edu while (threads != end) { 47710239Sbinhpham@cs.rutgers.edu ThreadID tid = *threads++; 47810239Sbinhpham@cs.rutgers.edu 47910239Sbinhpham@cs.rutgers.edu total += thread[tid].numFreeStoreEntries(); 48010239Sbinhpham@cs.rutgers.edu } 48110239Sbinhpham@cs.rutgers.edu 48210239Sbinhpham@cs.rutgers.edu return total; 48310239Sbinhpham@cs.rutgers.edu} 48410239Sbinhpham@cs.rutgers.edu 48510239Sbinhpham@cs.rutgers.edutemplate<class Impl> 48610239Sbinhpham@cs.rutgers.eduunsigned 48710239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries(ThreadID tid) 48810239Sbinhpham@cs.rutgers.edu{ 48910239Sbinhpham@cs.rutgers.edu return thread[tid].numFreeLoadEntries(); 49010239Sbinhpham@cs.rutgers.edu} 49110239Sbinhpham@cs.rutgers.edu 49210239Sbinhpham@cs.rutgers.edutemplate<class Impl> 49310239Sbinhpham@cs.rutgers.eduunsigned 49410239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries(ThreadID tid) 49510239Sbinhpham@cs.rutgers.edu{ 49610239Sbinhpham@cs.rutgers.edu return thread[tid].numFreeStoreEntries(); 4972292SN/A} 4982292SN/A 4992292SN/Atemplate<class Impl> 5002292SN/Abool 5012292SN/ALSQ<Impl>::isFull() 5022292SN/A{ 5036221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5046221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5052292SN/A 5063867Sbinkertn@umich.edu while (threads != end) { 5076221Snate@binkert.org ThreadID tid = *threads++; 5083867Sbinkertn@umich.edu 5093867Sbinkertn@umich.edu if (!(thread[tid].lqFull() || thread[tid].sqFull())) 5102292SN/A return false; 5112292SN/A } 5122292SN/A 5132292SN/A return true; 5142292SN/A} 5152292SN/A 5162292SN/Atemplate<class Impl> 5172292SN/Abool 5186221Snate@binkert.orgLSQ<Impl>::isFull(ThreadID tid) 5192292SN/A{ 5202292SN/A //@todo: Change to Calculate All Entries for 5212292SN/A //Dynamic Policy 5223867Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 5232292SN/A return isFull(); 5242292SN/A else 5252292SN/A return thread[tid].lqFull() || thread[tid].sqFull(); 5262292SN/A} 5272292SN/A 5282292SN/Atemplate<class Impl> 5292292SN/Abool 5309444SAndreas.Sandberg@ARM.comLSQ<Impl>::isEmpty() const 5319444SAndreas.Sandberg@ARM.com{ 5329444SAndreas.Sandberg@ARM.com return lqEmpty() && sqEmpty(); 5339444SAndreas.Sandberg@ARM.com} 5349444SAndreas.Sandberg@ARM.com 5359444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5369444SAndreas.Sandberg@ARM.combool 5379444SAndreas.Sandberg@ARM.comLSQ<Impl>::lqEmpty() const 5389444SAndreas.Sandberg@ARM.com{ 5399444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 5409444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 5419444SAndreas.Sandberg@ARM.com 5429444SAndreas.Sandberg@ARM.com while (threads != end) { 5439444SAndreas.Sandberg@ARM.com ThreadID tid = *threads++; 5449444SAndreas.Sandberg@ARM.com 5459444SAndreas.Sandberg@ARM.com if (!thread[tid].lqEmpty()) 5469444SAndreas.Sandberg@ARM.com return false; 5479444SAndreas.Sandberg@ARM.com } 5489444SAndreas.Sandberg@ARM.com 5499444SAndreas.Sandberg@ARM.com return true; 5509444SAndreas.Sandberg@ARM.com} 5519444SAndreas.Sandberg@ARM.com 5529444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5539444SAndreas.Sandberg@ARM.combool 5549444SAndreas.Sandberg@ARM.comLSQ<Impl>::sqEmpty() const 5559444SAndreas.Sandberg@ARM.com{ 5569444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 5579444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 5589444SAndreas.Sandberg@ARM.com 5599444SAndreas.Sandberg@ARM.com while (threads != end) { 5609444SAndreas.Sandberg@ARM.com ThreadID tid = *threads++; 5619444SAndreas.Sandberg@ARM.com 5629444SAndreas.Sandberg@ARM.com if (!thread[tid].sqEmpty()) 5639444SAndreas.Sandberg@ARM.com return false; 5649444SAndreas.Sandberg@ARM.com } 5659444SAndreas.Sandberg@ARM.com 5669444SAndreas.Sandberg@ARM.com return true; 5679444SAndreas.Sandberg@ARM.com} 5689444SAndreas.Sandberg@ARM.com 5699444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5709444SAndreas.Sandberg@ARM.combool 5712292SN/ALSQ<Impl>::lqFull() 5722292SN/A{ 5736221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5746221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5752292SN/A 5763867Sbinkertn@umich.edu while (threads != end) { 5776221Snate@binkert.org ThreadID tid = *threads++; 5783867Sbinkertn@umich.edu 5792292SN/A if (!thread[tid].lqFull()) 5802292SN/A return false; 5812292SN/A } 5822292SN/A 5832292SN/A return true; 5842292SN/A} 5852292SN/A 5862292SN/Atemplate<class Impl> 5872292SN/Abool 5886221Snate@binkert.orgLSQ<Impl>::lqFull(ThreadID tid) 5892292SN/A{ 5902292SN/A //@todo: Change to Calculate All Entries for 5912292SN/A //Dynamic Policy 5923870Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 5932292SN/A return lqFull(); 5942292SN/A else 5952292SN/A return thread[tid].lqFull(); 5962292SN/A} 5972292SN/A 5982292SN/Atemplate<class Impl> 5992292SN/Abool 6002292SN/ALSQ<Impl>::sqFull() 6012292SN/A{ 6026221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6036221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6042292SN/A 6053867Sbinkertn@umich.edu while (threads != end) { 6066221Snate@binkert.org ThreadID tid = *threads++; 6073867Sbinkertn@umich.edu 6082292SN/A if (!sqFull(tid)) 6092292SN/A return false; 6102292SN/A } 6112292SN/A 6122292SN/A return true; 6132292SN/A} 6142292SN/A 6152292SN/Atemplate<class Impl> 6162292SN/Abool 6176221Snate@binkert.orgLSQ<Impl>::sqFull(ThreadID tid) 6182292SN/A{ 6192292SN/A //@todo: Change to Calculate All Entries for 6202292SN/A //Dynamic Policy 6213870Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 6222292SN/A return sqFull(); 6232292SN/A else 6242292SN/A return thread[tid].sqFull(); 6252292SN/A} 6262292SN/A 6272292SN/Atemplate<class Impl> 6282292SN/Abool 6292292SN/ALSQ<Impl>::isStalled() 6302292SN/A{ 6316221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6326221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6332292SN/A 6343867Sbinkertn@umich.edu while (threads != end) { 6356221Snate@binkert.org ThreadID tid = *threads++; 6363867Sbinkertn@umich.edu 6372292SN/A if (!thread[tid].isStalled()) 6382292SN/A return false; 6392292SN/A } 6402292SN/A 6412292SN/A return true; 6422292SN/A} 6432292SN/A 6442292SN/Atemplate<class Impl> 6452292SN/Abool 6466221Snate@binkert.orgLSQ<Impl>::isStalled(ThreadID tid) 6472292SN/A{ 6483870Sbinkertn@umich.edu if (lsqPolicy == Dynamic) 6492292SN/A return isStalled(); 6502292SN/A else 6512292SN/A return thread[tid].isStalled(); 6522292SN/A} 6532292SN/A 6542292SN/Atemplate<class Impl> 6552292SN/Abool 6562292SN/ALSQ<Impl>::hasStoresToWB() 6572292SN/A{ 6586221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6596221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6602292SN/A 6613867Sbinkertn@umich.edu while (threads != end) { 6626221Snate@binkert.org ThreadID tid = *threads++; 6633867Sbinkertn@umich.edu 6645557Sktlim@umich.edu if (hasStoresToWB(tid)) 6655557Sktlim@umich.edu return true; 6662292SN/A } 6672292SN/A 6685557Sktlim@umich.edu return false; 6692292SN/A} 6702292SN/A 6712292SN/Atemplate<class Impl> 6722292SN/Abool 6732292SN/ALSQ<Impl>::willWB() 6742292SN/A{ 6756221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6766221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6772292SN/A 6783867Sbinkertn@umich.edu while (threads != end) { 6796221Snate@binkert.org ThreadID tid = *threads++; 6803867Sbinkertn@umich.edu 6815557Sktlim@umich.edu if (willWB(tid)) 6825557Sktlim@umich.edu return true; 6832292SN/A } 6842292SN/A 6855557Sktlim@umich.edu return false; 6862292SN/A} 6872292SN/A 6882292SN/Atemplate<class Impl> 6892292SN/Avoid 6909440SAndreas.Sandberg@ARM.comLSQ<Impl>::dumpInsts() const 6912292SN/A{ 6929440SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 6939440SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 6942292SN/A 6953867Sbinkertn@umich.edu while (threads != end) { 6966221Snate@binkert.org ThreadID tid = *threads++; 6973867Sbinkertn@umich.edu 6982292SN/A thread[tid].dumpInsts(); 6992292SN/A } 7002292SN/A} 7019944Smatt.horsnell@ARM.com 7029944Smatt.horsnell@ARM.com#endif//__CPU_O3_LSQ_IMPL_HH__ 703