lsq_impl.hh revision 13560
15222Sksewell@umich.edu/* 25222Sksewell@umich.edu * Copyright (c) 2011-2012, 2014 ARM Limited 35222Sksewell@umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc. 45222Sksewell@umich.edu * All rights reserved 55222Sksewell@umich.edu * 65222Sksewell@umich.edu * The license below extends only to copyright in the software and shall 75222Sksewell@umich.edu * not be construed as granting a license to any other intellectual 85222Sksewell@umich.edu * property including but not limited to intellectual property relating 95222Sksewell@umich.edu * to a hardware implementation of the functionality of the software 105222Sksewell@umich.edu * licensed hereunder. You may use the software subject to the license 115222Sksewell@umich.edu * terms below provided that you ensure that this notice is replicated 125222Sksewell@umich.edu * unmodified and in its entirety in all distributions of the software, 135222Sksewell@umich.edu * modified or unmodified, in source code or in binary form. 145222Sksewell@umich.edu * 155222Sksewell@umich.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan 165222Sksewell@umich.edu * All rights reserved. 175222Sksewell@umich.edu * 185222Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 195222Sksewell@umich.edu * modification, are permitted provided that the following conditions are 205222Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 215222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 225222Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 235222Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 245222Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 255222Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 265222Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 275222Sksewell@umich.edu * this software without specific prior written permission. 285222Sksewell@umich.edu * 295222Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 305222Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 315222Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 325222Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 335222Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 345222Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 355222Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 365222Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 375222Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 385222Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 395222Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 405222Sksewell@umich.edu * 415222Sksewell@umich.edu * Authors: Korey Sewell 425222Sksewell@umich.edu */ 435222Sksewell@umich.edu 445222Sksewell@umich.edu#ifndef __CPU_O3_LSQ_IMPL_HH__ 455222Sksewell@umich.edu#define __CPU_O3_LSQ_IMPL_HH__ 465222Sksewell@umich.edu 475222Sksewell@umich.edu#include <algorithm> 485222Sksewell@umich.edu#include <list> 495222Sksewell@umich.edu#include <string> 505222Sksewell@umich.edu 515222Sksewell@umich.edu#include "base/logging.hh" 525222Sksewell@umich.edu#include "cpu/o3/lsq.hh" 535222Sksewell@umich.edu#include "debug/Drain.hh" 545222Sksewell@umich.edu#include "debug/Fetch.hh" 555222Sksewell@umich.edu#include "debug/LSQ.hh" 565222Sksewell@umich.edu#include "debug/Writeback.hh" 575222Sksewell@umich.edu#include "params/DerivO3CPU.hh" 585222Sksewell@umich.edu 595222Sksewell@umich.eduusing namespace std; 605222Sksewell@umich.edu 615222Sksewell@umich.edutemplate <class Impl> 625222Sksewell@umich.eduLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 635222Sksewell@umich.edu : cpu(cpu_ptr), iewStage(iew_ptr), 645222Sksewell@umich.edu lsqPolicy(params->smtLSQPolicy), 655222Sksewell@umich.edu LQEntries(params->LQEntries), 665222Sksewell@umich.edu SQEntries(params->SQEntries), 675222Sksewell@umich.edu maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads, 685222Sksewell@umich.edu params->smtLSQThreshold)), 695222Sksewell@umich.edu maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads, 705222Sksewell@umich.edu params->smtLSQThreshold)), 715222Sksewell@umich.edu numThreads(params->numThreads) 725222Sksewell@umich.edu{ 735222Sksewell@umich.edu assert(numThreads > 0 && numThreads <= Impl::MaxThreads); 745222Sksewell@umich.edu 755222Sksewell@umich.edu //**********************************************/ 765222Sksewell@umich.edu //************ Handle SMT Parameters ***********/ 775222Sksewell@umich.edu //**********************************************/ 785222Sksewell@umich.edu 795222Sksewell@umich.edu //Figure out fetch policy 805222Sksewell@umich.edu if (lsqPolicy == SMTQueuePolicy::Dynamic) { 815222Sksewell@umich.edu DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 825222Sksewell@umich.edu } else if (lsqPolicy == SMTQueuePolicy::Partitioned) { 835222Sksewell@umich.edu DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 845222Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 855222Sksewell@umich.edu maxLQEntries,maxSQEntries); 865222Sksewell@umich.edu } else if (lsqPolicy == SMTQueuePolicy::Threshold) { 875222Sksewell@umich.edu 885222Sksewell@umich.edu assert(params->smtLSQThreshold > LQEntries); 895222Sksewell@umich.edu assert(params->smtLSQThreshold > SQEntries); 905222Sksewell@umich.edu 915222Sksewell@umich.edu DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 925222Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 935222Sksewell@umich.edu maxLQEntries,maxSQEntries); 945222Sksewell@umich.edu } else { 955222Sksewell@umich.edu panic("Invalid LSQ sharing policy. Options are: Dynamic, " 965222Sksewell@umich.edu "Partitioned, Threshold"); 975222Sksewell@umich.edu } 985222Sksewell@umich.edu 995222Sksewell@umich.edu thread.reserve(numThreads); 1005222Sksewell@umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 1015222Sksewell@umich.edu thread.emplace_back(maxLQEntries, maxSQEntries); 1025222Sksewell@umich.edu thread[tid].init(cpu, iew_ptr, params, this, tid); 1035222Sksewell@umich.edu thread[tid].setDcachePort(&cpu_ptr->getDataPort()); 1045222Sksewell@umich.edu } 1055222Sksewell@umich.edu} 1065222Sksewell@umich.edu 1075222Sksewell@umich.edu 1085222Sksewell@umich.edutemplate<class Impl> 1095222Sksewell@umich.edustd::string 1105222Sksewell@umich.eduLSQ<Impl>::name() const 1115222Sksewell@umich.edu{ 1125222Sksewell@umich.edu return iewStage->name() + ".lsq"; 1135222Sksewell@umich.edu} 1145222Sksewell@umich.edu 1155222Sksewell@umich.edutemplate<class Impl> 1165222Sksewell@umich.eduvoid 1175222Sksewell@umich.eduLSQ<Impl>::regStats() 1185222Sksewell@umich.edu{ 1195222Sksewell@umich.edu //Initialize LSQs 1205222Sksewell@umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 1215222Sksewell@umich.edu thread[tid].regStats(); 1225222Sksewell@umich.edu } 1235222Sksewell@umich.edu} 1245222Sksewell@umich.edu 1255222Sksewell@umich.edutemplate<class Impl> 1265222Sksewell@umich.eduvoid 1275222Sksewell@umich.eduLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1285222Sksewell@umich.edu{ 1295222Sksewell@umich.edu activeThreads = at_ptr; 1305222Sksewell@umich.edu assert(activeThreads != 0); 1315222Sksewell@umich.edu} 1325222Sksewell@umich.edu 1335222Sksewell@umich.edutemplate <class Impl> 1345222Sksewell@umich.eduvoid 1355222Sksewell@umich.eduLSQ<Impl>::drainSanityCheck() const 1365222Sksewell@umich.edu{ 1375222Sksewell@umich.edu assert(isDrained()); 1385222Sksewell@umich.edu 1395222Sksewell@umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) 1405222Sksewell@umich.edu thread[tid].drainSanityCheck(); 1415222Sksewell@umich.edu} 1425222Sksewell@umich.edu 1435222Sksewell@umich.edutemplate <class Impl> 1445222Sksewell@umich.edubool 1455222Sksewell@umich.eduLSQ<Impl>::isDrained() const 1465222Sksewell@umich.edu{ 1475222Sksewell@umich.edu bool drained(true); 1485222Sksewell@umich.edu 1495222Sksewell@umich.edu if (!lqEmpty()) { 1505222Sksewell@umich.edu DPRINTF(Drain, "Not drained, LQ not empty.\n"); 1515222Sksewell@umich.edu drained = false; 1525222Sksewell@umich.edu } 1535222Sksewell@umich.edu 1545222Sksewell@umich.edu if (!sqEmpty()) { 1555222Sksewell@umich.edu DPRINTF(Drain, "Not drained, SQ not empty.\n"); 1565222Sksewell@umich.edu drained = false; 1575222Sksewell@umich.edu } 1585222Sksewell@umich.edu 1595222Sksewell@umich.edu return drained; 1605222Sksewell@umich.edu} 1615222Sksewell@umich.edu 1625222Sksewell@umich.edutemplate <class Impl> 1635222Sksewell@umich.eduvoid 1645222Sksewell@umich.eduLSQ<Impl>::takeOverFrom() 1655222Sksewell@umich.edu{ 1665222Sksewell@umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 1675222Sksewell@umich.edu thread[tid].takeOverFrom(); 1685222Sksewell@umich.edu } 1695222Sksewell@umich.edu} 1705222Sksewell@umich.edu 1715222Sksewell@umich.edutemplate <class Impl> 1725222Sksewell@umich.eduint 1735222Sksewell@umich.eduLSQ<Impl>::entryAmount(ThreadID num_threads) 1745222Sksewell@umich.edu{ 1755222Sksewell@umich.edu if (lsqPolicy == SMTQueuePolicy::Partitioned) { 1765222Sksewell@umich.edu return LQEntries / num_threads; 1775222Sksewell@umich.edu } else { 1785222Sksewell@umich.edu return 0; 1795222Sksewell@umich.edu } 1805222Sksewell@umich.edu} 1815222Sksewell@umich.edu 1825222Sksewell@umich.edutemplate <class Impl> 1835222Sksewell@umich.eduvoid 1845222Sksewell@umich.eduLSQ<Impl>::resetEntries() 1855222Sksewell@umich.edu{ 1865222Sksewell@umich.edu if (lsqPolicy != SMTQueuePolicy::Dynamic || numThreads > 1) { 1875222Sksewell@umich.edu int active_threads = activeThreads->size(); 1885222Sksewell@umich.edu 1895222Sksewell@umich.edu int maxEntries; 1905222Sksewell@umich.edu 1915222Sksewell@umich.edu if (lsqPolicy == SMTQueuePolicy::Partitioned) { 1925222Sksewell@umich.edu maxEntries = LQEntries / active_threads; 1935222Sksewell@umich.edu } else if (lsqPolicy == SMTQueuePolicy::Threshold && 1945222Sksewell@umich.edu active_threads == 1) { 1955222Sksewell@umich.edu maxEntries = LQEntries; 1965222Sksewell@umich.edu } else { 1975222Sksewell@umich.edu maxEntries = LQEntries; 1985222Sksewell@umich.edu } 1995222Sksewell@umich.edu 2005222Sksewell@umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 2015222Sksewell@umich.edu list<ThreadID>::iterator end = activeThreads->end(); 2025222Sksewell@umich.edu 2035222Sksewell@umich.edu while (threads != end) { 2045222Sksewell@umich.edu ThreadID tid = *threads++; 2055222Sksewell@umich.edu 2065222Sksewell@umich.edu resizeEntries(maxEntries, tid); 2075222Sksewell@umich.edu } 2085222Sksewell@umich.edu } 2095222Sksewell@umich.edu} 2105222Sksewell@umich.edu 2115222Sksewell@umich.edutemplate<class Impl> 2125222Sksewell@umich.eduvoid 2135222Sksewell@umich.eduLSQ<Impl>::removeEntries(ThreadID tid) 2145222Sksewell@umich.edu{ 2155222Sksewell@umich.edu thread[tid].clearLQ(); 2165222Sksewell@umich.edu thread[tid].clearSQ(); 2175222Sksewell@umich.edu} 2185222Sksewell@umich.edu 2195222Sksewell@umich.edutemplate<class Impl> 2205222Sksewell@umich.eduvoid 2215222Sksewell@umich.eduLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid) 2225222Sksewell@umich.edu{ 2235222Sksewell@umich.edu thread[tid].resizeLQ(size); 2245222Sksewell@umich.edu thread[tid].resizeSQ(size); 2255222Sksewell@umich.edu} 2265222Sksewell@umich.edu 2275222Sksewell@umich.edutemplate<class Impl> 2285222Sksewell@umich.eduvoid 2295222Sksewell@umich.eduLSQ<Impl>::tick() 2305222Sksewell@umich.edu{ 2315222Sksewell@umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 2325222Sksewell@umich.edu list<ThreadID>::iterator end = activeThreads->end(); 2335222Sksewell@umich.edu 2345222Sksewell@umich.edu while (threads != end) { 2355222Sksewell@umich.edu ThreadID tid = *threads++; 2365222Sksewell@umich.edu 2375222Sksewell@umich.edu thread[tid].tick(); 2385222Sksewell@umich.edu } 2395222Sksewell@umich.edu} 2405222Sksewell@umich.edu 2415222Sksewell@umich.edutemplate<class Impl> 2425222Sksewell@umich.eduvoid 2435222Sksewell@umich.eduLSQ<Impl>::insertLoad(const DynInstPtr &load_inst) 2445222Sksewell@umich.edu{ 2455222Sksewell@umich.edu ThreadID tid = load_inst->threadNumber; 2465222Sksewell@umich.edu 2475222Sksewell@umich.edu thread[tid].insertLoad(load_inst); 2485222Sksewell@umich.edu} 2495222Sksewell@umich.edu 2505222Sksewell@umich.edutemplate<class Impl> 2515222Sksewell@umich.eduvoid 2525222Sksewell@umich.eduLSQ<Impl>::insertStore(const DynInstPtr &store_inst) 2535222Sksewell@umich.edu{ 2545222Sksewell@umich.edu ThreadID tid = store_inst->threadNumber; 2555222Sksewell@umich.edu 2565222Sksewell@umich.edu thread[tid].insertStore(store_inst); 2575222Sksewell@umich.edu} 2585222Sksewell@umich.edu 2595222Sksewell@umich.edutemplate<class Impl> 2605222Sksewell@umich.eduFault 2615222Sksewell@umich.eduLSQ<Impl>::executeLoad(const DynInstPtr &inst) 2625222Sksewell@umich.edu{ 2635222Sksewell@umich.edu ThreadID tid = inst->threadNumber; 2645222Sksewell@umich.edu 2655222Sksewell@umich.edu return thread[tid].executeLoad(inst); 2665222Sksewell@umich.edu} 2675222Sksewell@umich.edu 2685222Sksewell@umich.edutemplate<class Impl> 2695222Sksewell@umich.eduFault 2705222Sksewell@umich.eduLSQ<Impl>::executeStore(const DynInstPtr &inst) 2715222Sksewell@umich.edu{ 2725222Sksewell@umich.edu ThreadID tid = inst->threadNumber; 2735222Sksewell@umich.edu 2745222Sksewell@umich.edu return thread[tid].executeStore(inst); 2755222Sksewell@umich.edu} 2765222Sksewell@umich.edu 2775222Sksewell@umich.edutemplate<class Impl> 2785222Sksewell@umich.eduvoid 2795222Sksewell@umich.eduLSQ<Impl>::writebackStores() 2805222Sksewell@umich.edu{ 2815222Sksewell@umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 2825222Sksewell@umich.edu list<ThreadID>::iterator end = activeThreads->end(); 2835222Sksewell@umich.edu 2845222Sksewell@umich.edu while (threads != end) { 2855222Sksewell@umich.edu ThreadID tid = *threads++; 2865222Sksewell@umich.edu 2875222Sksewell@umich.edu if (numStoresToWB(tid) > 0) { 2885222Sksewell@umich.edu DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 2895222Sksewell@umich.edu "available for Writeback.\n", tid, numStoresToWB(tid)); 2905222Sksewell@umich.edu } 2915222Sksewell@umich.edu 2925222Sksewell@umich.edu thread[tid].writebackStores(); 2935222Sksewell@umich.edu } 2945222Sksewell@umich.edu} 2955222Sksewell@umich.edu 2965222Sksewell@umich.edutemplate<class Impl> 2975222Sksewell@umich.edubool 2985222Sksewell@umich.eduLSQ<Impl>::violation() 2995222Sksewell@umich.edu{ 3005222Sksewell@umich.edu /* Answers: Does Anybody Have a Violation?*/ 3015222Sksewell@umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 3025222Sksewell@umich.edu list<ThreadID>::iterator end = activeThreads->end(); 3035222Sksewell@umich.edu 3045222Sksewell@umich.edu while (threads != end) { 3055222Sksewell@umich.edu ThreadID tid = *threads++; 3065222Sksewell@umich.edu 3075222Sksewell@umich.edu if (thread[tid].violation()) 3085222Sksewell@umich.edu return true; 3095222Sksewell@umich.edu } 3105222Sksewell@umich.edu 3115222Sksewell@umich.edu return false; 3125222Sksewell@umich.edu} 3135222Sksewell@umich.edu 3145222Sksewell@umich.edutemplate <class Impl> 3155222Sksewell@umich.eduvoid 3165222Sksewell@umich.eduLSQ<Impl>::recvReqRetry() 3175222Sksewell@umich.edu{ 3185222Sksewell@umich.edu iewStage->cacheUnblocked(); 3195222Sksewell@umich.edu 3205222Sksewell@umich.edu for (ThreadID tid : *activeThreads) { 3215222Sksewell@umich.edu thread[tid].recvRetry(); 3225222Sksewell@umich.edu } 3235222Sksewell@umich.edu} 3245222Sksewell@umich.edu 3255222Sksewell@umich.edutemplate <class Impl> 3265222Sksewell@umich.edubool 3275222Sksewell@umich.eduLSQ<Impl>::recvTimingResp(PacketPtr pkt) 3285222Sksewell@umich.edu{ 3295222Sksewell@umich.edu if (pkt->isError()) 3305222Sksewell@umich.edu DPRINTF(LSQ, "Got error packet back for address: %#X\n", 3315222Sksewell@umich.edu pkt->getAddr()); 3325222Sksewell@umich.edu 3335222Sksewell@umich.edu thread[cpu->contextToThread(pkt->req->contextId())] 3345222Sksewell@umich.edu .completeDataAccess(pkt); 3355222Sksewell@umich.edu 3365222Sksewell@umich.edu if (pkt->isInvalidate()) { 3375222Sksewell@umich.edu // This response also contains an invalidate; e.g. this can be the case 3385222Sksewell@umich.edu // if cmd is ReadRespWithInvalidate. 3395222Sksewell@umich.edu // 3405222Sksewell@umich.edu // The calling order between completeDataAccess and checkSnoop matters. 3415222Sksewell@umich.edu // By calling checkSnoop after completeDataAccess, we ensure that the 3425222Sksewell@umich.edu // fault set by checkSnoop is not lost. Calling writeback (more 3435222Sksewell@umich.edu // specifically inst->completeAcc) in completeDataAccess overwrites 3445222Sksewell@umich.edu // fault, and in case this instruction requires squashing (as 3455222Sksewell@umich.edu // determined by checkSnoop), the ReExec fault set by checkSnoop would 3465222Sksewell@umich.edu // be lost otherwise. 3475222Sksewell@umich.edu 3485222Sksewell@umich.edu DPRINTF(LSQ, "received invalidation with response for addr:%#x\n", 3495222Sksewell@umich.edu pkt->getAddr()); 3505222Sksewell@umich.edu 3515222Sksewell@umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 3525222Sksewell@umich.edu thread[tid].checkSnoop(pkt); 3535222Sksewell@umich.edu } 3545222Sksewell@umich.edu } 3555222Sksewell@umich.edu 3565222Sksewell@umich.edu delete pkt; 3575222Sksewell@umich.edu return true; 3585222Sksewell@umich.edu} 3595222Sksewell@umich.edu 3605222Sksewell@umich.edutemplate <class Impl> 361void 362LSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt) 363{ 364 DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), 365 pkt->cmdString()); 366 367 // must be a snoop 368 if (pkt->isInvalidate()) { 369 DPRINTF(LSQ, "received invalidation for addr:%#x\n", 370 pkt->getAddr()); 371 for (ThreadID tid = 0; tid < numThreads; tid++) { 372 thread[tid].checkSnoop(pkt); 373 } 374 } 375} 376 377template<class Impl> 378int 379LSQ<Impl>::getCount() 380{ 381 unsigned total = 0; 382 383 list<ThreadID>::iterator threads = activeThreads->begin(); 384 list<ThreadID>::iterator end = activeThreads->end(); 385 386 while (threads != end) { 387 ThreadID tid = *threads++; 388 389 total += getCount(tid); 390 } 391 392 return total; 393} 394 395template<class Impl> 396int 397LSQ<Impl>::numLoads() 398{ 399 unsigned total = 0; 400 401 list<ThreadID>::iterator threads = activeThreads->begin(); 402 list<ThreadID>::iterator end = activeThreads->end(); 403 404 while (threads != end) { 405 ThreadID tid = *threads++; 406 407 total += numLoads(tid); 408 } 409 410 return total; 411} 412 413template<class Impl> 414int 415LSQ<Impl>::numStores() 416{ 417 unsigned total = 0; 418 419 list<ThreadID>::iterator threads = activeThreads->begin(); 420 list<ThreadID>::iterator end = activeThreads->end(); 421 422 while (threads != end) { 423 ThreadID tid = *threads++; 424 425 total += thread[tid].numStores(); 426 } 427 428 return total; 429} 430 431template<class Impl> 432unsigned 433LSQ<Impl>::numFreeLoadEntries() 434{ 435 unsigned total = 0; 436 437 list<ThreadID>::iterator threads = activeThreads->begin(); 438 list<ThreadID>::iterator end = activeThreads->end(); 439 440 while (threads != end) { 441 ThreadID tid = *threads++; 442 443 total += thread[tid].numFreeLoadEntries(); 444 } 445 446 return total; 447} 448 449template<class Impl> 450unsigned 451LSQ<Impl>::numFreeStoreEntries() 452{ 453 unsigned total = 0; 454 455 list<ThreadID>::iterator threads = activeThreads->begin(); 456 list<ThreadID>::iterator end = activeThreads->end(); 457 458 while (threads != end) { 459 ThreadID tid = *threads++; 460 461 total += thread[tid].numFreeStoreEntries(); 462 } 463 464 return total; 465} 466 467template<class Impl> 468unsigned 469LSQ<Impl>::numFreeLoadEntries(ThreadID tid) 470{ 471 return thread[tid].numFreeLoadEntries(); 472} 473 474template<class Impl> 475unsigned 476LSQ<Impl>::numFreeStoreEntries(ThreadID tid) 477{ 478 return thread[tid].numFreeStoreEntries(); 479} 480 481template<class Impl> 482bool 483LSQ<Impl>::isFull() 484{ 485 list<ThreadID>::iterator threads = activeThreads->begin(); 486 list<ThreadID>::iterator end = activeThreads->end(); 487 488 while (threads != end) { 489 ThreadID tid = *threads++; 490 491 if (!(thread[tid].lqFull() || thread[tid].sqFull())) 492 return false; 493 } 494 495 return true; 496} 497 498template<class Impl> 499bool 500LSQ<Impl>::isFull(ThreadID tid) 501{ 502 //@todo: Change to Calculate All Entries for 503 //Dynamic Policy 504 if (lsqPolicy == SMTQueuePolicy::Dynamic) 505 return isFull(); 506 else 507 return thread[tid].lqFull() || thread[tid].sqFull(); 508} 509 510template<class Impl> 511bool 512LSQ<Impl>::isEmpty() const 513{ 514 return lqEmpty() && sqEmpty(); 515} 516 517template<class Impl> 518bool 519LSQ<Impl>::lqEmpty() const 520{ 521 list<ThreadID>::const_iterator threads = activeThreads->begin(); 522 list<ThreadID>::const_iterator end = activeThreads->end(); 523 524 while (threads != end) { 525 ThreadID tid = *threads++; 526 527 if (!thread[tid].lqEmpty()) 528 return false; 529 } 530 531 return true; 532} 533 534template<class Impl> 535bool 536LSQ<Impl>::sqEmpty() const 537{ 538 list<ThreadID>::const_iterator threads = activeThreads->begin(); 539 list<ThreadID>::const_iterator end = activeThreads->end(); 540 541 while (threads != end) { 542 ThreadID tid = *threads++; 543 544 if (!thread[tid].sqEmpty()) 545 return false; 546 } 547 548 return true; 549} 550 551template<class Impl> 552bool 553LSQ<Impl>::lqFull() 554{ 555 list<ThreadID>::iterator threads = activeThreads->begin(); 556 list<ThreadID>::iterator end = activeThreads->end(); 557 558 while (threads != end) { 559 ThreadID tid = *threads++; 560 561 if (!thread[tid].lqFull()) 562 return false; 563 } 564 565 return true; 566} 567 568template<class Impl> 569bool 570LSQ<Impl>::lqFull(ThreadID tid) 571{ 572 //@todo: Change to Calculate All Entries for 573 //Dynamic Policy 574 if (lsqPolicy == SMTQueuePolicy::Dynamic) 575 return lqFull(); 576 else 577 return thread[tid].lqFull(); 578} 579 580template<class Impl> 581bool 582LSQ<Impl>::sqFull() 583{ 584 list<ThreadID>::iterator threads = activeThreads->begin(); 585 list<ThreadID>::iterator end = activeThreads->end(); 586 587 while (threads != end) { 588 ThreadID tid = *threads++; 589 590 if (!sqFull(tid)) 591 return false; 592 } 593 594 return true; 595} 596 597template<class Impl> 598bool 599LSQ<Impl>::sqFull(ThreadID tid) 600{ 601 //@todo: Change to Calculate All Entries for 602 //Dynamic Policy 603 if (lsqPolicy == SMTQueuePolicy::Dynamic) 604 return sqFull(); 605 else 606 return thread[tid].sqFull(); 607} 608 609template<class Impl> 610bool 611LSQ<Impl>::isStalled() 612{ 613 list<ThreadID>::iterator threads = activeThreads->begin(); 614 list<ThreadID>::iterator end = activeThreads->end(); 615 616 while (threads != end) { 617 ThreadID tid = *threads++; 618 619 if (!thread[tid].isStalled()) 620 return false; 621 } 622 623 return true; 624} 625 626template<class Impl> 627bool 628LSQ<Impl>::isStalled(ThreadID tid) 629{ 630 if (lsqPolicy == SMTQueuePolicy::Dynamic) 631 return isStalled(); 632 else 633 return thread[tid].isStalled(); 634} 635 636template<class Impl> 637bool 638LSQ<Impl>::hasStoresToWB() 639{ 640 list<ThreadID>::iterator threads = activeThreads->begin(); 641 list<ThreadID>::iterator end = activeThreads->end(); 642 643 while (threads != end) { 644 ThreadID tid = *threads++; 645 646 if (hasStoresToWB(tid)) 647 return true; 648 } 649 650 return false; 651} 652 653template<class Impl> 654bool 655LSQ<Impl>::willWB() 656{ 657 list<ThreadID>::iterator threads = activeThreads->begin(); 658 list<ThreadID>::iterator end = activeThreads->end(); 659 660 while (threads != end) { 661 ThreadID tid = *threads++; 662 663 if (willWB(tid)) 664 return true; 665 } 666 667 return false; 668} 669 670template<class Impl> 671void 672LSQ<Impl>::dumpInsts() const 673{ 674 list<ThreadID>::const_iterator threads = activeThreads->begin(); 675 list<ThreadID>::const_iterator end = activeThreads->end(); 676 677 while (threads != end) { 678 ThreadID tid = *threads++; 679 680 thread[tid].dumpInsts(); 681 } 682} 683 684#endif//__CPU_O3_LSQ_IMPL_HH__ 685