lsq_impl.hh revision 9944
13520Sgblack@eecs.umich.edu/* 23520Sgblack@eecs.umich.edu * Copyright (c) 2011-2012 ARM Limited 33520Sgblack@eecs.umich.edu * All rights reserved 43520Sgblack@eecs.umich.edu * 53520Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 63520Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 73520Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 83520Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 93520Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 103520Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 113520Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 123520Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 133520Sgblack@eecs.umich.edu * 143520Sgblack@eecs.umich.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan 153520Sgblack@eecs.umich.edu * All rights reserved. 163520Sgblack@eecs.umich.edu * 173520Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 183520Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 193520Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 203520Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 213520Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 223520Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 233520Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 243520Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 253520Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 263520Sgblack@eecs.umich.edu * this software without specific prior written permission. 273520Sgblack@eecs.umich.edu * 283520Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 293520Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 303520Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 313520Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 323520Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 333520Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 343520Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 353520Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 363520Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 374103Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 385647Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 393520Sgblack@eecs.umich.edu * 408232Snate@binkert.org * Authors: Korey Sewell 418232Snate@binkert.org */ 425647Sgblack@eecs.umich.edu 435647Sgblack@eecs.umich.edu#ifndef __CPU_O3_LSQ_IMPL_HH__ 443520Sgblack@eecs.umich.edu#define __CPU_O3_LSQ_IMPL_HH__ 455565Snate@binkert.org 465565Snate@binkert.org#include <algorithm> 475647Sgblack@eecs.umich.edu#include <list> 483520Sgblack@eecs.umich.edu#include <string> 495565Snate@binkert.org 505565Snate@binkert.org#include "cpu/o3/lsq.hh" 515565Snate@binkert.org#include "debug/Drain.hh" 525565Snate@binkert.org#include "debug/Fetch.hh" 535810Sgblack@eecs.umich.edu#include "debug/LSQ.hh" 545565Snate@binkert.org#include "debug/Writeback.hh" 555565Snate@binkert.org#include "params/DerivO3CPU.hh" 565565Snate@binkert.org 575565Snate@binkert.orgusing namespace std; 585565Snate@binkert.org 595565Snate@binkert.orgtemplate <class Impl> 605647Sgblack@eecs.umich.eduLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 615647Sgblack@eecs.umich.edu : cpu(cpu_ptr), iewStage(iew_ptr), 625647Sgblack@eecs.umich.edu LQEntries(params->LQEntries), 635647Sgblack@eecs.umich.edu SQEntries(params->SQEntries), 645647Sgblack@eecs.umich.edu numThreads(params->numThreads), 655647Sgblack@eecs.umich.edu retryTid(-1) 665647Sgblack@eecs.umich.edu{ 675647Sgblack@eecs.umich.edu assert(numThreads > 0 && numThreads <= Impl::MaxThreads); 685810Sgblack@eecs.umich.edu 693520Sgblack@eecs.umich.edu //**********************************************/ 705565Snate@binkert.org //************ Handle SMT Parameters ***********/ 715565Snate@binkert.org //**********************************************/ 725565Snate@binkert.org std::string policy = params->smtLSQPolicy; 735565Snate@binkert.org 743520Sgblack@eecs.umich.edu //Convert string to lowercase 755565Snate@binkert.org std::transform(policy.begin(), policy.end(), policy.begin(), 765810Sgblack@eecs.umich.edu (int(*)(int)) tolower); 775810Sgblack@eecs.umich.edu 785810Sgblack@eecs.umich.edu //Figure out fetch policy 795810Sgblack@eecs.umich.edu if (policy == "dynamic") { 805810Sgblack@eecs.umich.edu lsqPolicy = Dynamic; 815810Sgblack@eecs.umich.edu 825565Snate@binkert.org maxLQEntries = LQEntries; 835565Snate@binkert.org maxSQEntries = SQEntries; 845565Snate@binkert.org 853520Sgblack@eecs.umich.edu DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 865565Snate@binkert.org } else if (policy == "partitioned") { 875565Snate@binkert.org lsqPolicy = Partitioned; 883520Sgblack@eecs.umich.edu 895565Snate@binkert.org //@todo:make work if part_amt doesnt divide evenly. 905565Snate@binkert.org maxLQEntries = LQEntries / numThreads; 913520Sgblack@eecs.umich.edu maxSQEntries = SQEntries / numThreads; 925565Snate@binkert.org 935565Snate@binkert.org DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 945565Snate@binkert.org "%i entries per LQ | %i entries per SQ\n", 953520Sgblack@eecs.umich.edu maxLQEntries,maxSQEntries); 965565Snate@binkert.org } else if (policy == "threshold") { 975565Snate@binkert.org lsqPolicy = Threshold; 985565Snate@binkert.org 995565Snate@binkert.org assert(params->smtLSQThreshold > LQEntries); 1003520Sgblack@eecs.umich.edu assert(params->smtLSQThreshold > SQEntries); 1015568Snate@binkert.org 1025565Snate@binkert.org //Divide up by threshold amount 1033520Sgblack@eecs.umich.edu //@todo: Should threads check the max and the total 1045565Snate@binkert.org //amount of the LSQ 1055565Snate@binkert.org maxLQEntries = params->smtLSQThreshold; 1063520Sgblack@eecs.umich.edu maxSQEntries = params->smtLSQThreshold; 1075565Snate@binkert.org 1085565Snate@binkert.org DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 1095565Snate@binkert.org "%i entries per LQ | %i entries per SQ\n", 1105565Snate@binkert.org maxLQEntries,maxSQEntries); 1113520Sgblack@eecs.umich.edu } else { 1125565Snate@binkert.org assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," 1135704Snate@binkert.org "Partitioned, Threshold}"); 1145565Snate@binkert.org } 1155565Snate@binkert.org 1163520Sgblack@eecs.umich.edu //Initialize LSQs 1175565Snate@binkert.org thread = new LSQUnit[numThreads]; 1185565Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1195565Snate@binkert.org thread[tid].init(cpu, iew_ptr, params, this, 1203520Sgblack@eecs.umich.edu maxLQEntries, maxSQEntries, tid); 1215565Snate@binkert.org thread[tid].setDcachePort(&cpu_ptr->getDataPort()); 1225565Snate@binkert.org } 1235565Snate@binkert.org} 1245565Snate@binkert.org 1255565Snate@binkert.org 1265565Snate@binkert.orgtemplate<class Impl> 1273520Sgblack@eecs.umich.edustd::string 1285565Snate@binkert.orgLSQ<Impl>::name() const 1295565Snate@binkert.org{ 1305565Snate@binkert.org return iewStage->name() + ".lsq"; 1315565Snate@binkert.org} 1325565Snate@binkert.org 1335565Snate@binkert.orgtemplate<class Impl> 1343520Sgblack@eecs.umich.eduvoid 1355565Snate@binkert.orgLSQ<Impl>::regStats() 1365704Snate@binkert.org{ 1375565Snate@binkert.org //Initialize LSQs 1387720Sgblack@eecs.umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 1395565Snate@binkert.org thread[tid].regStats(); 1403520Sgblack@eecs.umich.edu } 1415565Snate@binkert.org} 1425565Snate@binkert.org 1435565Snate@binkert.orgtemplate<class Impl> 1446227Snate@binkert.orgvoid 1456227Snate@binkert.orgLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1463521Sgblack@eecs.umich.edu{ 1475565Snate@binkert.org activeThreads = at_ptr; 1485565Snate@binkert.org assert(activeThreads != 0); 1493520Sgblack@eecs.umich.edu} 1505565Snate@binkert.org 1516227Snate@binkert.orgtemplate <class Impl> 1525565Snate@binkert.orgvoid 1535565Snate@binkert.orgLSQ<Impl>::drainSanityCheck() const 1545565Snate@binkert.org{ 1555565Snate@binkert.org assert(isDrained()); 1565565Snate@binkert.org 1573520Sgblack@eecs.umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) 1583520Sgblack@eecs.umich.edu thread[tid].drainSanityCheck(); 1593520Sgblack@eecs.umich.edu} 1603520Sgblack@eecs.umich.edu 1615565Snate@binkert.orgtemplate <class Impl> 1625565Snate@binkert.orgbool 1636227Snate@binkert.orgLSQ<Impl>::isDrained() const 1645565Snate@binkert.org{ 1655565Snate@binkert.org bool drained(true); 1665565Snate@binkert.org 1675565Snate@binkert.org if (!lqEmpty()) { 1685565Snate@binkert.org DPRINTF(Drain, "Not drained, LQ not empty.\n"); 1695565Snate@binkert.org drained = false; 1705565Snate@binkert.org } 1713633Sktlim@umich.edu 1723633Sktlim@umich.edu if (!sqEmpty()) { 1735565Snate@binkert.org DPRINTF(Drain, "Not drained, SQ not empty.\n"); 1745565Snate@binkert.org drained = false; 1755565Snate@binkert.org } 1765565Snate@binkert.org 1775565Snate@binkert.org if (retryTid != InvalidThreadID) { 1785565Snate@binkert.org DPRINTF(Drain, "Not drained, the LSQ has blocked the caches.\n"); 1795565Snate@binkert.org drained = false; 1805565Snate@binkert.org } 1815565Snate@binkert.org 1825565Snate@binkert.org return drained; 1834103Ssaidi@eecs.umich.edu} 1845565Snate@binkert.org 1854103Ssaidi@eecs.umich.edutemplate <class Impl> 1865565Snate@binkert.orgvoid 1875565Snate@binkert.orgLSQ<Impl>::takeOverFrom() 1885565Snate@binkert.org{ 1895565Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1905565Snate@binkert.org thread[tid].takeOverFrom(); 1915565Snate@binkert.org } 1925565Snate@binkert.org} 1935565Snate@binkert.org 1945565Snate@binkert.orgtemplate <class Impl> 1953520Sgblack@eecs.umich.eduint 1965565Snate@binkert.orgLSQ<Impl>::entryAmount(ThreadID num_threads) 1975565Snate@binkert.org{ 1985565Snate@binkert.org if (lsqPolicy == Partitioned) { 1995565Snate@binkert.org return LQEntries / num_threads; 200 } else { 201 return 0; 202 } 203} 204 205template <class Impl> 206void 207LSQ<Impl>::resetEntries() 208{ 209 if (lsqPolicy != Dynamic || numThreads > 1) { 210 int active_threads = activeThreads->size(); 211 212 int maxEntries; 213 214 if (lsqPolicy == Partitioned) { 215 maxEntries = LQEntries / active_threads; 216 } else if (lsqPolicy == Threshold && active_threads == 1) { 217 maxEntries = LQEntries; 218 } else { 219 maxEntries = LQEntries; 220 } 221 222 list<ThreadID>::iterator threads = activeThreads->begin(); 223 list<ThreadID>::iterator end = activeThreads->end(); 224 225 while (threads != end) { 226 ThreadID tid = *threads++; 227 228 resizeEntries(maxEntries, tid); 229 } 230 } 231} 232 233template<class Impl> 234void 235LSQ<Impl>::removeEntries(ThreadID tid) 236{ 237 thread[tid].clearLQ(); 238 thread[tid].clearSQ(); 239} 240 241template<class Impl> 242void 243LSQ<Impl>::resizeEntries(unsigned size, ThreadID tid) 244{ 245 thread[tid].resizeLQ(size); 246 thread[tid].resizeSQ(size); 247} 248 249template<class Impl> 250void 251LSQ<Impl>::tick() 252{ 253 list<ThreadID>::iterator threads = activeThreads->begin(); 254 list<ThreadID>::iterator end = activeThreads->end(); 255 256 while (threads != end) { 257 ThreadID tid = *threads++; 258 259 thread[tid].tick(); 260 } 261} 262 263template<class Impl> 264void 265LSQ<Impl>::insertLoad(DynInstPtr &load_inst) 266{ 267 ThreadID tid = load_inst->threadNumber; 268 269 thread[tid].insertLoad(load_inst); 270} 271 272template<class Impl> 273void 274LSQ<Impl>::insertStore(DynInstPtr &store_inst) 275{ 276 ThreadID tid = store_inst->threadNumber; 277 278 thread[tid].insertStore(store_inst); 279} 280 281template<class Impl> 282Fault 283LSQ<Impl>::executeLoad(DynInstPtr &inst) 284{ 285 ThreadID tid = inst->threadNumber; 286 287 return thread[tid].executeLoad(inst); 288} 289 290template<class Impl> 291Fault 292LSQ<Impl>::executeStore(DynInstPtr &inst) 293{ 294 ThreadID tid = inst->threadNumber; 295 296 return thread[tid].executeStore(inst); 297} 298 299template<class Impl> 300void 301LSQ<Impl>::writebackStores() 302{ 303 list<ThreadID>::iterator threads = activeThreads->begin(); 304 list<ThreadID>::iterator end = activeThreads->end(); 305 306 while (threads != end) { 307 ThreadID tid = *threads++; 308 309 if (numStoresToWB(tid) > 0) { 310 DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 311 "available for Writeback.\n", tid, numStoresToWB(tid)); 312 } 313 314 thread[tid].writebackStores(); 315 } 316} 317 318template<class Impl> 319bool 320LSQ<Impl>::violation() 321{ 322 /* Answers: Does Anybody Have a Violation?*/ 323 list<ThreadID>::iterator threads = activeThreads->begin(); 324 list<ThreadID>::iterator end = activeThreads->end(); 325 326 while (threads != end) { 327 ThreadID tid = *threads++; 328 329 if (thread[tid].violation()) 330 return true; 331 } 332 333 return false; 334} 335 336template <class Impl> 337void 338LSQ<Impl>::recvRetry() 339{ 340 if (retryTid == InvalidThreadID) 341 { 342 //Squashed, so drop it 343 return; 344 } 345 int curr_retry_tid = retryTid; 346 // Speculatively clear the retry Tid. This will get set again if 347 // the LSQUnit was unable to complete its access. 348 retryTid = -1; 349 thread[curr_retry_tid].recvRetry(); 350} 351 352template <class Impl> 353bool 354LSQ<Impl>::recvTimingResp(PacketPtr pkt) 355{ 356 if (pkt->isError()) 357 DPRINTF(LSQ, "Got error packet back for address: %#X\n", 358 pkt->getAddr()); 359 thread[pkt->req->threadId()].completeDataAccess(pkt); 360 return true; 361} 362 363template <class Impl> 364void 365LSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt) 366{ 367 DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), 368 pkt->cmdString()); 369 370 // must be a snoop 371 if (pkt->isInvalidate()) { 372 DPRINTF(LSQ, "received invalidation for addr:%#x\n", 373 pkt->getAddr()); 374 for (ThreadID tid = 0; tid < numThreads; tid++) { 375 thread[tid].checkSnoop(pkt); 376 } 377 } 378} 379 380template<class Impl> 381int 382LSQ<Impl>::getCount() 383{ 384 unsigned total = 0; 385 386 list<ThreadID>::iterator threads = activeThreads->begin(); 387 list<ThreadID>::iterator end = activeThreads->end(); 388 389 while (threads != end) { 390 ThreadID tid = *threads++; 391 392 total += getCount(tid); 393 } 394 395 return total; 396} 397 398template<class Impl> 399int 400LSQ<Impl>::numLoads() 401{ 402 unsigned total = 0; 403 404 list<ThreadID>::iterator threads = activeThreads->begin(); 405 list<ThreadID>::iterator end = activeThreads->end(); 406 407 while (threads != end) { 408 ThreadID tid = *threads++; 409 410 total += numLoads(tid); 411 } 412 413 return total; 414} 415 416template<class Impl> 417int 418LSQ<Impl>::numStores() 419{ 420 unsigned total = 0; 421 422 list<ThreadID>::iterator threads = activeThreads->begin(); 423 list<ThreadID>::iterator end = activeThreads->end(); 424 425 while (threads != end) { 426 ThreadID tid = *threads++; 427 428 total += thread[tid].numStores(); 429 } 430 431 return total; 432} 433 434template<class Impl> 435unsigned 436LSQ<Impl>::numFreeEntries() 437{ 438 unsigned total = 0; 439 440 list<ThreadID>::iterator threads = activeThreads->begin(); 441 list<ThreadID>::iterator end = activeThreads->end(); 442 443 while (threads != end) { 444 ThreadID tid = *threads++; 445 446 total += thread[tid].numFreeEntries(); 447 } 448 449 return total; 450} 451 452template<class Impl> 453unsigned 454LSQ<Impl>::numFreeEntries(ThreadID tid) 455{ 456 //if (lsqPolicy == Dynamic) 457 //return numFreeEntries(); 458 //else 459 return thread[tid].numFreeEntries(); 460} 461 462template<class Impl> 463bool 464LSQ<Impl>::isFull() 465{ 466 list<ThreadID>::iterator threads = activeThreads->begin(); 467 list<ThreadID>::iterator end = activeThreads->end(); 468 469 while (threads != end) { 470 ThreadID tid = *threads++; 471 472 if (!(thread[tid].lqFull() || thread[tid].sqFull())) 473 return false; 474 } 475 476 return true; 477} 478 479template<class Impl> 480bool 481LSQ<Impl>::isFull(ThreadID tid) 482{ 483 //@todo: Change to Calculate All Entries for 484 //Dynamic Policy 485 if (lsqPolicy == Dynamic) 486 return isFull(); 487 else 488 return thread[tid].lqFull() || thread[tid].sqFull(); 489} 490 491template<class Impl> 492bool 493LSQ<Impl>::isEmpty() const 494{ 495 return lqEmpty() && sqEmpty(); 496} 497 498template<class Impl> 499bool 500LSQ<Impl>::lqEmpty() const 501{ 502 list<ThreadID>::const_iterator threads = activeThreads->begin(); 503 list<ThreadID>::const_iterator end = activeThreads->end(); 504 505 while (threads != end) { 506 ThreadID tid = *threads++; 507 508 if (!thread[tid].lqEmpty()) 509 return false; 510 } 511 512 return true; 513} 514 515template<class Impl> 516bool 517LSQ<Impl>::sqEmpty() const 518{ 519 list<ThreadID>::const_iterator threads = activeThreads->begin(); 520 list<ThreadID>::const_iterator end = activeThreads->end(); 521 522 while (threads != end) { 523 ThreadID tid = *threads++; 524 525 if (!thread[tid].sqEmpty()) 526 return false; 527 } 528 529 return true; 530} 531 532template<class Impl> 533bool 534LSQ<Impl>::lqFull() 535{ 536 list<ThreadID>::iterator threads = activeThreads->begin(); 537 list<ThreadID>::iterator end = activeThreads->end(); 538 539 while (threads != end) { 540 ThreadID tid = *threads++; 541 542 if (!thread[tid].lqFull()) 543 return false; 544 } 545 546 return true; 547} 548 549template<class Impl> 550bool 551LSQ<Impl>::lqFull(ThreadID tid) 552{ 553 //@todo: Change to Calculate All Entries for 554 //Dynamic Policy 555 if (lsqPolicy == Dynamic) 556 return lqFull(); 557 else 558 return thread[tid].lqFull(); 559} 560 561template<class Impl> 562bool 563LSQ<Impl>::sqFull() 564{ 565 list<ThreadID>::iterator threads = activeThreads->begin(); 566 list<ThreadID>::iterator end = activeThreads->end(); 567 568 while (threads != end) { 569 ThreadID tid = *threads++; 570 571 if (!sqFull(tid)) 572 return false; 573 } 574 575 return true; 576} 577 578template<class Impl> 579bool 580LSQ<Impl>::sqFull(ThreadID tid) 581{ 582 //@todo: Change to Calculate All Entries for 583 //Dynamic Policy 584 if (lsqPolicy == Dynamic) 585 return sqFull(); 586 else 587 return thread[tid].sqFull(); 588} 589 590template<class Impl> 591bool 592LSQ<Impl>::isStalled() 593{ 594 list<ThreadID>::iterator threads = activeThreads->begin(); 595 list<ThreadID>::iterator end = activeThreads->end(); 596 597 while (threads != end) { 598 ThreadID tid = *threads++; 599 600 if (!thread[tid].isStalled()) 601 return false; 602 } 603 604 return true; 605} 606 607template<class Impl> 608bool 609LSQ<Impl>::isStalled(ThreadID tid) 610{ 611 if (lsqPolicy == Dynamic) 612 return isStalled(); 613 else 614 return thread[tid].isStalled(); 615} 616 617template<class Impl> 618bool 619LSQ<Impl>::hasStoresToWB() 620{ 621 list<ThreadID>::iterator threads = activeThreads->begin(); 622 list<ThreadID>::iterator end = activeThreads->end(); 623 624 while (threads != end) { 625 ThreadID tid = *threads++; 626 627 if (hasStoresToWB(tid)) 628 return true; 629 } 630 631 return false; 632} 633 634template<class Impl> 635bool 636LSQ<Impl>::willWB() 637{ 638 list<ThreadID>::iterator threads = activeThreads->begin(); 639 list<ThreadID>::iterator end = activeThreads->end(); 640 641 while (threads != end) { 642 ThreadID tid = *threads++; 643 644 if (willWB(tid)) 645 return true; 646 } 647 648 return false; 649} 650 651template<class Impl> 652void 653LSQ<Impl>::dumpInsts() const 654{ 655 list<ThreadID>::const_iterator threads = activeThreads->begin(); 656 list<ThreadID>::const_iterator end = activeThreads->end(); 657 658 while (threads != end) { 659 ThreadID tid = *threads++; 660 661 thread[tid].dumpInsts(); 662 } 663} 664 665#endif//__CPU_O3_LSQ_IMPL_HH__ 666