lsq_impl.hh revision 13560
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 5113449Sgabeblack@google.com#include "base/logging.hh" 522292SN/A#include "cpu/o3/lsq.hh" 539444SAndreas.Sandberg@ARM.com#include "debug/Drain.hh" 548232Snate@binkert.org#include "debug/Fetch.hh" 558232Snate@binkert.org#include "debug/LSQ.hh" 568232Snate@binkert.org#include "debug/Writeback.hh" 576221Snate@binkert.org#include "params/DerivO3CPU.hh" 582292SN/A 596221Snate@binkert.orgusing namespace std; 605529Snate@binkert.org 612292SN/Atemplate <class Impl> 625529Snate@binkert.orgLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 638707Sandreas.hansson@arm.com : cpu(cpu_ptr), iewStage(iew_ptr), 6413560Snikos.nikoleris@arm.com lsqPolicy(params->smtLSQPolicy), 654329Sktlim@umich.edu LQEntries(params->LQEntries), 664329Sktlim@umich.edu SQEntries(params->SQEntries), 6713472Srekai.gonzalezalberquilla@arm.com maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads, 6813472Srekai.gonzalezalberquilla@arm.com params->smtLSQThreshold)), 6913472Srekai.gonzalezalberquilla@arm.com maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads, 7013472Srekai.gonzalezalberquilla@arm.com params->smtLSQThreshold)), 7110333Smitch.hayenga@arm.com numThreads(params->numThreads) 722292SN/A{ 739868Sjthestness@gmail.com assert(numThreads > 0 && numThreads <= Impl::MaxThreads); 749868Sjthestness@gmail.com 752292SN/A //**********************************************/ 762292SN/A //************ Handle SMT Parameters ***********/ 772292SN/A //**********************************************/ 782292SN/A 792292SN/A //Figure out fetch policy 8013560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) { 812292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 8213560Snikos.nikoleris@arm.com } else if (lsqPolicy == SMTQueuePolicy::Partitioned) { 832292SN/A DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 848346Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 852292SN/A maxLQEntries,maxSQEntries); 8613560Snikos.nikoleris@arm.com } else if (lsqPolicy == SMTQueuePolicy::Threshold) { 872292SN/A 882292SN/A assert(params->smtLSQThreshold > LQEntries); 892292SN/A assert(params->smtLSQThreshold > SQEntries); 902292SN/A 912292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 928346Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 932292SN/A maxLQEntries,maxSQEntries); 942292SN/A } else { 9513449Sgabeblack@google.com panic("Invalid LSQ sharing policy. Options are: Dynamic, " 9613449Sgabeblack@google.com "Partitioned, Threshold"); 972292SN/A } 982292SN/A 9913472Srekai.gonzalezalberquilla@arm.com thread.reserve(numThreads); 1006221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 10113472Srekai.gonzalezalberquilla@arm.com thread.emplace_back(maxLQEntries, maxSQEntries); 10213472Srekai.gonzalezalberquilla@arm.com thread[tid].init(cpu, iew_ptr, params, this, tid); 1038850Sandreas.hansson@arm.com thread[tid].setDcachePort(&cpu_ptr->getDataPort()); 1042292SN/A } 1052292SN/A} 1062292SN/A 1072292SN/A 1082292SN/Atemplate<class Impl> 1092292SN/Astd::string 1102292SN/ALSQ<Impl>::name() const 1112292SN/A{ 1122292SN/A return iewStage->name() + ".lsq"; 1132292SN/A} 1142292SN/A 1152292SN/Atemplate<class Impl> 1162292SN/Avoid 1172727Sktlim@umich.eduLSQ<Impl>::regStats() 1182727Sktlim@umich.edu{ 1192727Sktlim@umich.edu //Initialize LSQs 1206221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1212727Sktlim@umich.edu thread[tid].regStats(); 1222727Sktlim@umich.edu } 1232727Sktlim@umich.edu} 1242727Sktlim@umich.edu 1252727Sktlim@umich.edutemplate<class Impl> 1262727Sktlim@umich.eduvoid 1276221Snate@binkert.orgLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1282292SN/A{ 1292292SN/A activeThreads = at_ptr; 1302292SN/A assert(activeThreads != 0); 1312292SN/A} 1322292SN/A 1332292SN/Atemplate <class Impl> 1342307SN/Avoid 1359444SAndreas.Sandberg@ARM.comLSQ<Impl>::drainSanityCheck() const 1362307SN/A{ 1379444SAndreas.Sandberg@ARM.com assert(isDrained()); 1389444SAndreas.Sandberg@ARM.com 1399444SAndreas.Sandberg@ARM.com for (ThreadID tid = 0; tid < numThreads; tid++) 1409444SAndreas.Sandberg@ARM.com thread[tid].drainSanityCheck(); 1419444SAndreas.Sandberg@ARM.com} 1429444SAndreas.Sandberg@ARM.com 1439444SAndreas.Sandberg@ARM.comtemplate <class Impl> 1449444SAndreas.Sandberg@ARM.combool 1459444SAndreas.Sandberg@ARM.comLSQ<Impl>::isDrained() const 1469444SAndreas.Sandberg@ARM.com{ 1479444SAndreas.Sandberg@ARM.com bool drained(true); 1489444SAndreas.Sandberg@ARM.com 1499444SAndreas.Sandberg@ARM.com if (!lqEmpty()) { 1509444SAndreas.Sandberg@ARM.com DPRINTF(Drain, "Not drained, LQ not empty.\n"); 1519444SAndreas.Sandberg@ARM.com drained = false; 1522307SN/A } 1539444SAndreas.Sandberg@ARM.com 1549444SAndreas.Sandberg@ARM.com if (!sqEmpty()) { 1559444SAndreas.Sandberg@ARM.com DPRINTF(Drain, "Not drained, SQ not empty.\n"); 1569444SAndreas.Sandberg@ARM.com drained = false; 1579444SAndreas.Sandberg@ARM.com } 1589444SAndreas.Sandberg@ARM.com 1599444SAndreas.Sandberg@ARM.com return drained; 1602307SN/A} 1612307SN/A 1622307SN/Atemplate <class Impl> 1632307SN/Avoid 1642307SN/ALSQ<Impl>::takeOverFrom() 1652307SN/A{ 1666221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1672307SN/A thread[tid].takeOverFrom(); 1682307SN/A } 1692307SN/A} 1702307SN/A 1712307SN/Atemplate <class Impl> 1722292SN/Aint 1736221Snate@binkert.orgLSQ<Impl>::entryAmount(ThreadID num_threads) 1742292SN/A{ 17513560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Partitioned) { 1762292SN/A return LQEntries / num_threads; 1772292SN/A } else { 1782292SN/A return 0; 1792292SN/A } 1802292SN/A} 1812292SN/A 1822292SN/Atemplate <class Impl> 1832292SN/Avoid 1842292SN/ALSQ<Impl>::resetEntries() 1852292SN/A{ 18613560Snikos.nikoleris@arm.com if (lsqPolicy != SMTQueuePolicy::Dynamic || numThreads > 1) { 1873867Sbinkertn@umich.edu int active_threads = activeThreads->size(); 1882292SN/A 1892292SN/A int maxEntries; 1902292SN/A 19113560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Partitioned) { 1922292SN/A maxEntries = LQEntries / active_threads; 19313560Snikos.nikoleris@arm.com } else if (lsqPolicy == SMTQueuePolicy::Threshold && 19413560Snikos.nikoleris@arm.com active_threads == 1) { 1952292SN/A maxEntries = LQEntries; 1962292SN/A } else { 1972292SN/A maxEntries = LQEntries; 1982292SN/A } 1992292SN/A 2006221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2016221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 2023867Sbinkertn@umich.edu 2033867Sbinkertn@umich.edu while (threads != end) { 2046221Snate@binkert.org ThreadID tid = *threads++; 2053867Sbinkertn@umich.edu 2063867Sbinkertn@umich.edu resizeEntries(maxEntries, tid); 2072292SN/A } 2082292SN/A } 2092292SN/A} 2102292SN/A 2112292SN/Atemplate<class Impl> 2122292SN/Avoid 2136221Snate@binkert.orgLSQ<Impl>::removeEntries(ThreadID tid) 2142292SN/A{ 2152292SN/A thread[tid].clearLQ(); 2162292SN/A thread[tid].clearSQ(); 2172292SN/A} 2182292SN/A 2192292SN/Atemplate<class Impl> 2202292SN/Avoid 2216221Snate@binkert.orgLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid) 2222292SN/A{ 2232292SN/A thread[tid].resizeLQ(size); 2242292SN/A thread[tid].resizeSQ(size); 2252292SN/A} 2262292SN/A 2272292SN/Atemplate<class Impl> 2282292SN/Avoid 2292292SN/ALSQ<Impl>::tick() 2302292SN/A{ 2316221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2326221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 2332292SN/A 2343867Sbinkertn@umich.edu while (threads != end) { 2356221Snate@binkert.org ThreadID tid = *threads++; 2362292SN/A 2372292SN/A thread[tid].tick(); 2382292SN/A } 2392292SN/A} 2402292SN/A 2412292SN/Atemplate<class Impl> 2422292SN/Avoid 24313429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::insertLoad(const DynInstPtr &load_inst) 2442292SN/A{ 2456221Snate@binkert.org ThreadID tid = load_inst->threadNumber; 2462292SN/A 2472292SN/A thread[tid].insertLoad(load_inst); 2482292SN/A} 2492292SN/A 2502292SN/Atemplate<class Impl> 2512292SN/Avoid 25213429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::insertStore(const DynInstPtr &store_inst) 2532292SN/A{ 2546221Snate@binkert.org ThreadID tid = store_inst->threadNumber; 2552292SN/A 2562292SN/A thread[tid].insertStore(store_inst); 2572292SN/A} 2582292SN/A 2592292SN/Atemplate<class Impl> 2602292SN/AFault 26113429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::executeLoad(const DynInstPtr &inst) 2622292SN/A{ 2636221Snate@binkert.org ThreadID tid = inst->threadNumber; 2642292SN/A 2652292SN/A return thread[tid].executeLoad(inst); 2662292SN/A} 2672292SN/A 2682292SN/Atemplate<class Impl> 2692292SN/AFault 27013429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::executeStore(const DynInstPtr &inst) 2712292SN/A{ 2726221Snate@binkert.org ThreadID tid = inst->threadNumber; 2732292SN/A 2742292SN/A return thread[tid].executeStore(inst); 2752292SN/A} 2762292SN/A 2772292SN/Atemplate<class Impl> 2782292SN/Avoid 2792292SN/ALSQ<Impl>::writebackStores() 2802292SN/A{ 2816221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2826221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 2832292SN/A 2843867Sbinkertn@umich.edu while (threads != end) { 2856221Snate@binkert.org ThreadID tid = *threads++; 2862292SN/A 2872292SN/A if (numStoresToWB(tid) > 0) { 2882329SN/A DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 2892329SN/A "available for Writeback.\n", tid, numStoresToWB(tid)); 2902292SN/A } 2912292SN/A 2922292SN/A thread[tid].writebackStores(); 2932292SN/A } 2942292SN/A} 2952292SN/A 2962292SN/Atemplate<class Impl> 2972292SN/Abool 2982292SN/ALSQ<Impl>::violation() 2992292SN/A{ 3002292SN/A /* Answers: Does Anybody Have a Violation?*/ 3016221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3026221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3032292SN/A 3043867Sbinkertn@umich.edu while (threads != end) { 3056221Snate@binkert.org ThreadID tid = *threads++; 3063867Sbinkertn@umich.edu 3072292SN/A if (thread[tid].violation()) 3082292SN/A return true; 3092292SN/A } 3102292SN/A 3112292SN/A return false; 3122292SN/A} 3132292SN/A 3148707Sandreas.hansson@arm.comtemplate <class Impl> 3158707Sandreas.hansson@arm.comvoid 31610713Sandreas.hansson@arm.comLSQ<Impl>::recvReqRetry() 3178707Sandreas.hansson@arm.com{ 31810333Smitch.hayenga@arm.com iewStage->cacheUnblocked(); 31910333Smitch.hayenga@arm.com 32010333Smitch.hayenga@arm.com for (ThreadID tid : *activeThreads) { 32110333Smitch.hayenga@arm.com thread[tid].recvRetry(); 3228707Sandreas.hansson@arm.com } 3238707Sandreas.hansson@arm.com} 3248707Sandreas.hansson@arm.com 3258707Sandreas.hansson@arm.comtemplate <class Impl> 3268707Sandreas.hansson@arm.combool 3278975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingResp(PacketPtr pkt) 3288707Sandreas.hansson@arm.com{ 3298707Sandreas.hansson@arm.com if (pkt->isError()) 3308707Sandreas.hansson@arm.com DPRINTF(LSQ, "Got error packet back for address: %#X\n", 3318707Sandreas.hansson@arm.com pkt->getAddr()); 33210575SMarco.Elver@ARM.com 33311435Smitch.hayenga@arm.com thread[cpu->contextToThread(pkt->req->contextId())] 33411435Smitch.hayenga@arm.com .completeDataAccess(pkt); 33510575SMarco.Elver@ARM.com 33610575SMarco.Elver@ARM.com if (pkt->isInvalidate()) { 33710575SMarco.Elver@ARM.com // This response also contains an invalidate; e.g. this can be the case 33810575SMarco.Elver@ARM.com // if cmd is ReadRespWithInvalidate. 33910575SMarco.Elver@ARM.com // 34010575SMarco.Elver@ARM.com // The calling order between completeDataAccess and checkSnoop matters. 34110575SMarco.Elver@ARM.com // By calling checkSnoop after completeDataAccess, we ensure that the 34210575SMarco.Elver@ARM.com // fault set by checkSnoop is not lost. Calling writeback (more 34310575SMarco.Elver@ARM.com // specifically inst->completeAcc) in completeDataAccess overwrites 34410575SMarco.Elver@ARM.com // fault, and in case this instruction requires squashing (as 34510575SMarco.Elver@ARM.com // determined by checkSnoop), the ReExec fault set by checkSnoop would 34610575SMarco.Elver@ARM.com // be lost otherwise. 34710575SMarco.Elver@ARM.com 34810575SMarco.Elver@ARM.com DPRINTF(LSQ, "received invalidation with response for addr:%#x\n", 34910575SMarco.Elver@ARM.com pkt->getAddr()); 35010575SMarco.Elver@ARM.com 35110575SMarco.Elver@ARM.com for (ThreadID tid = 0; tid < numThreads; tid++) { 35210575SMarco.Elver@ARM.com thread[tid].checkSnoop(pkt); 35310575SMarco.Elver@ARM.com } 35410575SMarco.Elver@ARM.com } 35510575SMarco.Elver@ARM.com 35610573Sstephan.diestelhorst@arm.com delete 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 43310239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries() 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 44310239Sbinhpham@cs.rutgers.edu total += thread[tid].numFreeLoadEntries(); 4442292SN/A } 4452292SN/A 4462292SN/A return total; 4472292SN/A} 4482292SN/A 4492292SN/Atemplate<class Impl> 4502292SN/Aunsigned 45110239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries() 4522292SN/A{ 45310239Sbinhpham@cs.rutgers.edu unsigned total = 0; 45410239Sbinhpham@cs.rutgers.edu 45510239Sbinhpham@cs.rutgers.edu list<ThreadID>::iterator threads = activeThreads->begin(); 45610239Sbinhpham@cs.rutgers.edu list<ThreadID>::iterator end = activeThreads->end(); 45710239Sbinhpham@cs.rutgers.edu 45810239Sbinhpham@cs.rutgers.edu while (threads != end) { 45910239Sbinhpham@cs.rutgers.edu ThreadID tid = *threads++; 46010239Sbinhpham@cs.rutgers.edu 46110239Sbinhpham@cs.rutgers.edu total += thread[tid].numFreeStoreEntries(); 46210239Sbinhpham@cs.rutgers.edu } 46310239Sbinhpham@cs.rutgers.edu 46410239Sbinhpham@cs.rutgers.edu return total; 46510239Sbinhpham@cs.rutgers.edu} 46610239Sbinhpham@cs.rutgers.edu 46710239Sbinhpham@cs.rutgers.edutemplate<class Impl> 46810239Sbinhpham@cs.rutgers.eduunsigned 46910239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries(ThreadID tid) 47010239Sbinhpham@cs.rutgers.edu{ 47110239Sbinhpham@cs.rutgers.edu return thread[tid].numFreeLoadEntries(); 47210239Sbinhpham@cs.rutgers.edu} 47310239Sbinhpham@cs.rutgers.edu 47410239Sbinhpham@cs.rutgers.edutemplate<class Impl> 47510239Sbinhpham@cs.rutgers.eduunsigned 47610239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries(ThreadID tid) 47710239Sbinhpham@cs.rutgers.edu{ 47810239Sbinhpham@cs.rutgers.edu return thread[tid].numFreeStoreEntries(); 4792292SN/A} 4802292SN/A 4812292SN/Atemplate<class Impl> 4822292SN/Abool 4832292SN/ALSQ<Impl>::isFull() 4842292SN/A{ 4856221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4866221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4872292SN/A 4883867Sbinkertn@umich.edu while (threads != end) { 4896221Snate@binkert.org ThreadID tid = *threads++; 4903867Sbinkertn@umich.edu 4913867Sbinkertn@umich.edu if (!(thread[tid].lqFull() || thread[tid].sqFull())) 4922292SN/A return false; 4932292SN/A } 4942292SN/A 4952292SN/A return true; 4962292SN/A} 4972292SN/A 4982292SN/Atemplate<class Impl> 4992292SN/Abool 5006221Snate@binkert.orgLSQ<Impl>::isFull(ThreadID tid) 5012292SN/A{ 5022292SN/A //@todo: Change to Calculate All Entries for 5032292SN/A //Dynamic Policy 50413560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) 5052292SN/A return isFull(); 5062292SN/A else 5072292SN/A return thread[tid].lqFull() || thread[tid].sqFull(); 5082292SN/A} 5092292SN/A 5102292SN/Atemplate<class Impl> 5112292SN/Abool 5129444SAndreas.Sandberg@ARM.comLSQ<Impl>::isEmpty() const 5139444SAndreas.Sandberg@ARM.com{ 5149444SAndreas.Sandberg@ARM.com return lqEmpty() && sqEmpty(); 5159444SAndreas.Sandberg@ARM.com} 5169444SAndreas.Sandberg@ARM.com 5179444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5189444SAndreas.Sandberg@ARM.combool 5199444SAndreas.Sandberg@ARM.comLSQ<Impl>::lqEmpty() const 5209444SAndreas.Sandberg@ARM.com{ 5219444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 5229444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 5239444SAndreas.Sandberg@ARM.com 5249444SAndreas.Sandberg@ARM.com while (threads != end) { 5259444SAndreas.Sandberg@ARM.com ThreadID tid = *threads++; 5269444SAndreas.Sandberg@ARM.com 5279444SAndreas.Sandberg@ARM.com if (!thread[tid].lqEmpty()) 5289444SAndreas.Sandberg@ARM.com return false; 5299444SAndreas.Sandberg@ARM.com } 5309444SAndreas.Sandberg@ARM.com 5319444SAndreas.Sandberg@ARM.com return true; 5329444SAndreas.Sandberg@ARM.com} 5339444SAndreas.Sandberg@ARM.com 5349444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5359444SAndreas.Sandberg@ARM.combool 5369444SAndreas.Sandberg@ARM.comLSQ<Impl>::sqEmpty() const 5379444SAndreas.Sandberg@ARM.com{ 5389444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 5399444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 5409444SAndreas.Sandberg@ARM.com 5419444SAndreas.Sandberg@ARM.com while (threads != end) { 5429444SAndreas.Sandberg@ARM.com ThreadID tid = *threads++; 5439444SAndreas.Sandberg@ARM.com 5449444SAndreas.Sandberg@ARM.com if (!thread[tid].sqEmpty()) 5459444SAndreas.Sandberg@ARM.com return false; 5469444SAndreas.Sandberg@ARM.com } 5479444SAndreas.Sandberg@ARM.com 5489444SAndreas.Sandberg@ARM.com return true; 5499444SAndreas.Sandberg@ARM.com} 5509444SAndreas.Sandberg@ARM.com 5519444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5529444SAndreas.Sandberg@ARM.combool 5532292SN/ALSQ<Impl>::lqFull() 5542292SN/A{ 5556221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5566221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5572292SN/A 5583867Sbinkertn@umich.edu while (threads != end) { 5596221Snate@binkert.org ThreadID tid = *threads++; 5603867Sbinkertn@umich.edu 5612292SN/A if (!thread[tid].lqFull()) 5622292SN/A return false; 5632292SN/A } 5642292SN/A 5652292SN/A return true; 5662292SN/A} 5672292SN/A 5682292SN/Atemplate<class Impl> 5692292SN/Abool 5706221Snate@binkert.orgLSQ<Impl>::lqFull(ThreadID tid) 5712292SN/A{ 5722292SN/A //@todo: Change to Calculate All Entries for 5732292SN/A //Dynamic Policy 57413560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) 5752292SN/A return lqFull(); 5762292SN/A else 5772292SN/A return thread[tid].lqFull(); 5782292SN/A} 5792292SN/A 5802292SN/Atemplate<class Impl> 5812292SN/Abool 5822292SN/ALSQ<Impl>::sqFull() 5832292SN/A{ 5846221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5856221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5862292SN/A 5873867Sbinkertn@umich.edu while (threads != end) { 5886221Snate@binkert.org ThreadID tid = *threads++; 5893867Sbinkertn@umich.edu 5902292SN/A if (!sqFull(tid)) 5912292SN/A return false; 5922292SN/A } 5932292SN/A 5942292SN/A return true; 5952292SN/A} 5962292SN/A 5972292SN/Atemplate<class Impl> 5982292SN/Abool 5996221Snate@binkert.orgLSQ<Impl>::sqFull(ThreadID tid) 6002292SN/A{ 6012292SN/A //@todo: Change to Calculate All Entries for 6022292SN/A //Dynamic Policy 60313560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) 6042292SN/A return sqFull(); 6052292SN/A else 6062292SN/A return thread[tid].sqFull(); 6072292SN/A} 6082292SN/A 6092292SN/Atemplate<class Impl> 6102292SN/Abool 6112292SN/ALSQ<Impl>::isStalled() 6122292SN/A{ 6136221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6146221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6152292SN/A 6163867Sbinkertn@umich.edu while (threads != end) { 6176221Snate@binkert.org ThreadID tid = *threads++; 6183867Sbinkertn@umich.edu 6192292SN/A if (!thread[tid].isStalled()) 6202292SN/A return false; 6212292SN/A } 6222292SN/A 6232292SN/A return true; 6242292SN/A} 6252292SN/A 6262292SN/Atemplate<class Impl> 6272292SN/Abool 6286221Snate@binkert.orgLSQ<Impl>::isStalled(ThreadID tid) 6292292SN/A{ 63013560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) 6312292SN/A return isStalled(); 6322292SN/A else 6332292SN/A return thread[tid].isStalled(); 6342292SN/A} 6352292SN/A 6362292SN/Atemplate<class Impl> 6372292SN/Abool 6382292SN/ALSQ<Impl>::hasStoresToWB() 6392292SN/A{ 6406221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6416221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6422292SN/A 6433867Sbinkertn@umich.edu while (threads != end) { 6446221Snate@binkert.org ThreadID tid = *threads++; 6453867Sbinkertn@umich.edu 6465557Sktlim@umich.edu if (hasStoresToWB(tid)) 6475557Sktlim@umich.edu return true; 6482292SN/A } 6492292SN/A 6505557Sktlim@umich.edu return false; 6512292SN/A} 6522292SN/A 6532292SN/Atemplate<class Impl> 6542292SN/Abool 6552292SN/ALSQ<Impl>::willWB() 6562292SN/A{ 6576221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6586221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6592292SN/A 6603867Sbinkertn@umich.edu while (threads != end) { 6616221Snate@binkert.org ThreadID tid = *threads++; 6623867Sbinkertn@umich.edu 6635557Sktlim@umich.edu if (willWB(tid)) 6645557Sktlim@umich.edu return true; 6652292SN/A } 6662292SN/A 6675557Sktlim@umich.edu return false; 6682292SN/A} 6692292SN/A 6702292SN/Atemplate<class Impl> 6712292SN/Avoid 6729440SAndreas.Sandberg@ARM.comLSQ<Impl>::dumpInsts() const 6732292SN/A{ 6749440SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 6759440SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 6762292SN/A 6773867Sbinkertn@umich.edu while (threads != end) { 6786221Snate@binkert.org ThreadID tid = *threads++; 6793867Sbinkertn@umich.edu 6802292SN/A thread[tid].dumpInsts(); 6812292SN/A } 6822292SN/A} 6839944Smatt.horsnell@ARM.com 6849944Smatt.horsnell@ARM.com#endif//__CPU_O3_LSQ_IMPL_HH__ 685