iew_impl.hh revision 2367
1/* 2 * Copyright (c) 2004-2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29// @todo: Fix the instantaneous communication among all the stages within 30// iew. There's a clear delay between issue and execute, yet backwards 31// communication happens simultaneously. 32 33#include <queue> 34 35#include "base/timebuf.hh" 36#include "cpu/o3/fu_pool.hh" 37#include "cpu/o3/iew.hh" 38 39using namespace std; 40 41template<class Impl> 42DefaultIEW<Impl>::LdWritebackEvent::LdWritebackEvent(DynInstPtr &_inst, 43 DefaultIEW<Impl> *_iew) 44 : Event(&mainEventQueue), inst(_inst), iewStage(_iew) 45{ 46 this->setFlags(Event::AutoDelete); 47} 48 49template<class Impl> 50void 51DefaultIEW<Impl>::LdWritebackEvent::process() 52{ 53 DPRINTF(IEW, "Load writeback event [sn:%lli]\n", inst->seqNum); 54 DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum); 55 56 //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum); 57 58 if (iewStage->isSwitchedOut()) { 59 iewStage->decrWb(inst->seqNum); 60 inst = NULL; 61 return; 62 } else if (inst->isSquashed()) { 63 iewStage->decrWb(inst->seqNum); 64 iewStage->wakeCPU(); 65 inst = NULL; 66 return; 67 } 68 69 iewStage->wakeCPU(); 70 71 if (!inst->isExecuted()) { 72 inst->setExecuted(); 73 74 // Complete access to copy data to proper place. 75 if (inst->isStore()) { 76 inst->completeAcc(); 77 } 78 } 79 80 // Need to insert instruction into queue to commit 81 iewStage->instToCommit(inst); 82 83 iewStage->activityThisCycle(); 84 85 inst = NULL; 86} 87 88template<class Impl> 89const char * 90DefaultIEW<Impl>::LdWritebackEvent::description() 91{ 92 return "Load writeback event"; 93} 94 95template<class Impl> 96DefaultIEW<Impl>::DefaultIEW(Params *params) 97 : // @todo: Make this into a parameter. 98 issueToExecQueue(params->backComSize, params->forwardComSize), 99 instQueue(params), 100 ldstQueue(params), 101 fuPool(params->fuPool), 102 commitToIEWDelay(params->commitToIEWDelay), 103 renameToIEWDelay(params->renameToIEWDelay), 104 issueToExecuteDelay(params->issueToExecuteDelay), 105 dispatchWidth(params->dispatchWidth), 106 issueWidth(params->issueWidth), 107 wbOutstanding(0), 108 wbWidth(params->wbWidth), 109 numThreads(params->numberOfThreads), 110 switchedOut(false) 111{ 112 _status = Active; 113 exeStatus = Running; 114 wbStatus = Idle; 115 116 // Setup wire to read instructions coming from issue. 117 fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay); 118 119 // Instruction queue needs the queue between issue and execute. 120 instQueue.setIssueToExecuteQueue(&issueToExecQueue); 121 122 instQueue.setIEW(this); 123 ldstQueue.setIEW(this); 124 125 for (int i=0; i < numThreads; i++) { 126 dispatchStatus[i] = Running; 127 stalls[i].commit = false; 128 fetchRedirect[i] = false; 129 } 130 131 wbMax = wbWidth * params->wbDepth; 132 133 updateLSQNextCycle = false; 134 135 ableToIssue = true; 136 137 skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth; 138} 139 140template <class Impl> 141std::string 142DefaultIEW<Impl>::name() const 143{ 144 return cpu->name() + ".iew"; 145} 146 147template <class Impl> 148void 149DefaultIEW<Impl>::regStats() 150{ 151 using namespace Stats; 152 153 instQueue.regStats(); 154 ldstQueue.regStats(); 155 156 iewIdleCycles 157 .name(name() + ".iewIdleCycles") 158 .desc("Number of cycles IEW is idle"); 159 160 iewSquashCycles 161 .name(name() + ".iewSquashCycles") 162 .desc("Number of cycles IEW is squashing"); 163 164 iewBlockCycles 165 .name(name() + ".iewBlockCycles") 166 .desc("Number of cycles IEW is blocking"); 167 168 iewUnblockCycles 169 .name(name() + ".iewUnblockCycles") 170 .desc("Number of cycles IEW is unblocking"); 171 172 iewDispatchedInsts 173 .name(name() + ".iewDispatchedInsts") 174 .desc("Number of instructions dispatched to IQ"); 175 176 iewDispSquashedInsts 177 .name(name() + ".iewDispSquashedInsts") 178 .desc("Number of squashed instructions skipped by dispatch"); 179 180 iewDispLoadInsts 181 .name(name() + ".iewDispLoadInsts") 182 .desc("Number of dispatched load instructions"); 183 184 iewDispStoreInsts 185 .name(name() + ".iewDispStoreInsts") 186 .desc("Number of dispatched store instructions"); 187 188 iewDispNonSpecInsts 189 .name(name() + ".iewDispNonSpecInsts") 190 .desc("Number of dispatched non-speculative instructions"); 191 192 iewIQFullEvents 193 .name(name() + ".iewIQFullEvents") 194 .desc("Number of times the IQ has become full, causing a stall"); 195 196 iewLSQFullEvents 197 .name(name() + ".iewLSQFullEvents") 198 .desc("Number of times the LSQ has become full, causing a stall"); 199 200 memOrderViolationEvents 201 .name(name() + ".memOrderViolationEvents") 202 .desc("Number of memory order violations"); 203 204 predictedTakenIncorrect 205 .name(name() + ".predictedTakenIncorrect") 206 .desc("Number of branches that were predicted taken incorrectly"); 207 208 predictedNotTakenIncorrect 209 .name(name() + ".predictedNotTakenIncorrect") 210 .desc("Number of branches that were predicted not taken incorrectly"); 211 212 branchMispredicts 213 .name(name() + ".branchMispredicts") 214 .desc("Number of branch mispredicts detected at execute"); 215 216 branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect; 217 218 iewExecutedInsts 219 .name(name() + ".iewExecutedInsts") 220 .desc("Number of executed instructions"); 221 222 iewExecLoadInsts 223 .init(cpu->number_of_threads) 224 .name(name() + ".iewExecLoadInsts") 225 .desc("Number of load instructions executed") 226 .flags(total); 227 228 iewExecSquashedInsts 229 .name(name() + ".iewExecSquashedInsts") 230 .desc("Number of squashed instructions skipped in execute"); 231 232 iewExecutedSwp 233 .init(cpu->number_of_threads) 234 .name(name() + ".EXEC:swp") 235 .desc("number of swp insts executed") 236 .flags(total); 237 238 iewExecutedNop 239 .init(cpu->number_of_threads) 240 .name(name() + ".EXEC:nop") 241 .desc("number of nop insts executed") 242 .flags(total); 243 244 iewExecutedRefs 245 .init(cpu->number_of_threads) 246 .name(name() + ".EXEC:refs") 247 .desc("number of memory reference insts executed") 248 .flags(total); 249 250 iewExecutedBranches 251 .init(cpu->number_of_threads) 252 .name(name() + ".EXEC:branches") 253 .desc("Number of branches executed") 254 .flags(total); 255 256 iewExecStoreInsts 257 .name(name() + ".EXEC:stores") 258 .desc("Number of stores executed") 259 .flags(total); 260 iewExecStoreInsts = iewExecutedRefs - iewExecLoadInsts; 261/* 262 for (int i=0; i<Num_OpClasses; ++i) { 263 stringstream subname; 264 subname << opClassStrings[i] << "_delay"; 265 issue_delay_dist.subname(i, subname.str()); 266 } 267*/ 268 // 269 // Other stats 270 // 271 272 iewInstsToCommit 273 .init(cpu->number_of_threads) 274 .name(name() + ".WB:sent") 275 .desc("cumulative count of insts sent to commit") 276 .flags(total); 277 278 writebackCount 279 .init(cpu->number_of_threads) 280 .name(name() + ".WB:count") 281 .desc("cumulative count of insts written-back") 282 .flags(total); 283 284 producerInst 285 .init(cpu->number_of_threads) 286 .name(name() + ".WB:producers") 287 .desc("num instructions producing a value") 288 .flags(total); 289 290 consumerInst 291 .init(cpu->number_of_threads) 292 .name(name() + ".WB:consumers") 293 .desc("num instructions consuming a value") 294 .flags(total); 295 296 wbPenalized 297 .init(cpu->number_of_threads) 298 .name(name() + ".WB:penalized") 299 .desc("number of instrctions required to write to 'other' IQ") 300 .flags(total); 301 302 wbPenalizedRate 303 .name(name() + ".WB:penalized_rate") 304 .desc ("fraction of instructions written-back that wrote to 'other' IQ") 305 .flags(total); 306 307 wbPenalizedRate = wbPenalized / writebackCount; 308 309 wbFanout 310 .name(name() + ".WB:fanout") 311 .desc("average fanout of values written-back") 312 .flags(total); 313 314 wbFanout = producerInst / consumerInst; 315 316 wbRate 317 .name(name() + ".WB:rate") 318 .desc("insts written-back per cycle") 319 .flags(total); 320 wbRate = writebackCount / cpu->numCycles; 321} 322 323template<class Impl> 324void 325DefaultIEW<Impl>::initStage() 326{ 327 for (int tid=0; tid < numThreads; tid++) { 328 toRename->iewInfo[tid].usedIQ = true; 329 toRename->iewInfo[tid].freeIQEntries = 330 instQueue.numFreeEntries(tid); 331 332 toRename->iewInfo[tid].usedLSQ = true; 333 toRename->iewInfo[tid].freeLSQEntries = 334 ldstQueue.numFreeEntries(tid); 335 } 336} 337 338template<class Impl> 339void 340DefaultIEW<Impl>::setCPU(FullCPU *cpu_ptr) 341{ 342 DPRINTF(IEW, "Setting CPU pointer.\n"); 343 cpu = cpu_ptr; 344 345 instQueue.setCPU(cpu_ptr); 346 ldstQueue.setCPU(cpu_ptr); 347 348 cpu->activateStage(FullCPU::IEWIdx); 349} 350 351template<class Impl> 352void 353DefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 354{ 355 DPRINTF(IEW, "Setting time buffer pointer.\n"); 356 timeBuffer = tb_ptr; 357 358 // Setup wire to read information from time buffer, from commit. 359 fromCommit = timeBuffer->getWire(-commitToIEWDelay); 360 361 // Setup wire to write information back to previous stages. 362 toRename = timeBuffer->getWire(0); 363 364 toFetch = timeBuffer->getWire(0); 365 366 // Instruction queue also needs main time buffer. 367 instQueue.setTimeBuffer(tb_ptr); 368} 369 370template<class Impl> 371void 372DefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 373{ 374 DPRINTF(IEW, "Setting rename queue pointer.\n"); 375 renameQueue = rq_ptr; 376 377 // Setup wire to read information from rename queue. 378 fromRename = renameQueue->getWire(-renameToIEWDelay); 379} 380 381template<class Impl> 382void 383DefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) 384{ 385 DPRINTF(IEW, "Setting IEW queue pointer.\n"); 386 iewQueue = iq_ptr; 387 388 // Setup wire to write instructions to commit. 389 toCommit = iewQueue->getWire(0); 390} 391 392template<class Impl> 393void 394DefaultIEW<Impl>::setActiveThreads(list<unsigned> *at_ptr) 395{ 396 DPRINTF(IEW, "Setting active threads list pointer.\n"); 397 activeThreads = at_ptr; 398 399 ldstQueue.setActiveThreads(at_ptr); 400 instQueue.setActiveThreads(at_ptr); 401} 402 403template<class Impl> 404void 405DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr) 406{ 407 DPRINTF(IEW, "Setting scoreboard pointer.\n"); 408 scoreboard = sb_ptr; 409} 410 411#if 0 412template<class Impl> 413void 414DefaultIEW<Impl>::setPageTable(PageTable *pt_ptr) 415{ 416 ldstQueue.setPageTable(pt_ptr); 417} 418#endif 419 420template <class Impl> 421void 422DefaultIEW<Impl>::switchOut() 423{ 424 // IEW is ready to switch out at any time. 425 cpu->signalSwitched(); 426} 427 428template <class Impl> 429void 430DefaultIEW<Impl>::doSwitchOut() 431{ 432 // Clear any state. 433 switchedOut = true; 434 assert(insts[0].empty()); 435 assert(skidBuffer[0].empty()); 436 437 instQueue.switchOut(); 438 ldstQueue.switchOut(); 439 fuPool->switchOut(); 440 441 for (int i = 0; i < numThreads; i++) { 442 while (!insts[i].empty()) 443 insts[i].pop(); 444 while (!skidBuffer[i].empty()) 445 skidBuffer[i].pop(); 446 } 447} 448 449template <class Impl> 450void 451DefaultIEW<Impl>::takeOverFrom() 452{ 453 // Reset all state. 454 _status = Active; 455 exeStatus = Running; 456 wbStatus = Idle; 457 switchedOut = false; 458 459 instQueue.takeOverFrom(); 460 ldstQueue.takeOverFrom(); 461 fuPool->takeOverFrom(); 462 463 initStage(); 464 cpu->activityThisCycle(); 465 466 for (int i=0; i < numThreads; i++) { 467 dispatchStatus[i] = Running; 468 stalls[i].commit = false; 469 fetchRedirect[i] = false; 470 } 471 472 updateLSQNextCycle = false; 473 474 for (int i = 0; i < issueToExecQueue.getSize(); ++i) { 475 issueToExecQueue.advance(); 476 } 477} 478 479template<class Impl> 480void 481DefaultIEW<Impl>::squash(unsigned tid) 482{ 483 DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n", 484 tid); 485 486 // Tell the IQ to start squashing. 487 instQueue.squash(tid); 488 489 // Tell the LDSTQ to start squashing. 490 ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid); 491 492 updatedQueues = true; 493 494 // Clear the skid buffer in case it has any data in it. 495 while (!skidBuffer[tid].empty()) { 496 497 if (skidBuffer[tid].front()->isLoad() || 498 skidBuffer[tid].front()->isStore() ) { 499 toRename->iewInfo[tid].dispatchedToLSQ++; 500 } 501 502 toRename->iewInfo[tid].dispatched++; 503 504 skidBuffer[tid].pop(); 505 } 506 507 emptyRenameInsts(tid); 508} 509 510template<class Impl> 511void 512DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid) 513{ 514 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x " 515 "[sn:%i].\n", tid, inst->readPC(), inst->seqNum); 516 517 toCommit->squash[tid] = true; 518 toCommit->squashedSeqNum[tid] = inst->seqNum; 519 toCommit->mispredPC[tid] = inst->readPC(); 520 toCommit->nextPC[tid] = inst->readNextPC(); 521 toCommit->branchMispredict[tid] = true; 522 toCommit->branchTaken[tid] = inst->readNextPC() != 523 (inst->readPC() + sizeof(TheISA::MachInst)); 524 525 toCommit->includeSquashInst[tid] = false; 526 527 wroteToTimeBuffer = true; 528} 529 530template<class Impl> 531void 532DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid) 533{ 534 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, " 535 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 536 537 toCommit->squash[tid] = true; 538 toCommit->squashedSeqNum[tid] = inst->seqNum; 539 toCommit->nextPC[tid] = inst->readNextPC(); 540 541 toCommit->includeSquashInst[tid] = false; 542 543 wroteToTimeBuffer = true; 544} 545 546template<class Impl> 547void 548DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid) 549{ 550 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, " 551 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 552 553 toCommit->squash[tid] = true; 554 toCommit->squashedSeqNum[tid] = inst->seqNum; 555 toCommit->nextPC[tid] = inst->readPC(); 556 557 // Must include the broadcasted SN in the squash. 558 toCommit->includeSquashInst[tid] = true; 559 560 ldstQueue.setLoadBlockedHandled(tid); 561 562 wroteToTimeBuffer = true; 563} 564 565template<class Impl> 566void 567DefaultIEW<Impl>::block(unsigned tid) 568{ 569 DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid); 570 571 if (dispatchStatus[tid] != Blocked && 572 dispatchStatus[tid] != Unblocking) { 573 toRename->iewBlock[tid] = true; 574 wroteToTimeBuffer = true; 575 } 576 577 // Add the current inputs to the skid buffer so they can be 578 // reprocessed when this stage unblocks. 579 skidInsert(tid); 580 581 dispatchStatus[tid] = Blocked; 582} 583 584template<class Impl> 585void 586DefaultIEW<Impl>::unblock(unsigned tid) 587{ 588 DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid " 589 "buffer %u.\n",tid, tid); 590 591 // If the skid bufffer is empty, signal back to previous stages to unblock. 592 // Also switch status to running. 593 if (skidBuffer[tid].empty()) { 594 toRename->iewUnblock[tid] = true; 595 wroteToTimeBuffer = true; 596 DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid); 597 dispatchStatus[tid] = Running; 598 } 599} 600 601template<class Impl> 602void 603DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst) 604{ 605 instQueue.wakeDependents(inst); 606} 607 608template<class Impl> 609void 610DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst) 611{ 612 instQueue.rescheduleMemInst(inst); 613} 614 615template<class Impl> 616void 617DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst) 618{ 619 instQueue.replayMemInst(inst); 620} 621 622template<class Impl> 623void 624DefaultIEW<Impl>::instToCommit(DynInstPtr &inst) 625{ 626 // First check the time slot that this instruction will write 627 // to. If there are free write ports at the time, then go ahead 628 // and write the instruction to that time. If there are not, 629 // keep looking back to see where's the first time there's a 630 // free slot. 631 while ((*iewQueue)[wbCycle].insts[wbNumInst]) { 632 ++wbNumInst; 633 if (wbNumInst == wbWidth) { 634 ++wbCycle; 635 wbNumInst = 0; 636 } 637 638 assert((wbCycle * wbWidth + wbNumInst) <= wbMax); 639 } 640 641 DPRINTF(IEW, "Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n", 642 wbCycle, wbWidth, wbNumInst, wbCycle * wbWidth + wbNumInst); 643 // Add finished instruction to queue to commit. 644 (*iewQueue)[wbCycle].insts[wbNumInst] = inst; 645 (*iewQueue)[wbCycle].size++; 646} 647 648template <class Impl> 649unsigned 650DefaultIEW<Impl>::validInstsFromRename() 651{ 652 unsigned inst_count = 0; 653 654 for (int i=0; i<fromRename->size; i++) { 655 if (!fromRename->insts[i]->isSquashed()) 656 inst_count++; 657 } 658 659 return inst_count; 660} 661 662template<class Impl> 663void 664DefaultIEW<Impl>::skidInsert(unsigned tid) 665{ 666 DynInstPtr inst = NULL; 667 668 while (!insts[tid].empty()) { 669 inst = insts[tid].front(); 670 671 insts[tid].pop(); 672 673 DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into " 674 "dispatch skidBuffer %i\n",tid, inst->seqNum, 675 inst->readPC(),tid); 676 677 skidBuffer[tid].push(inst); 678 } 679 680 assert(skidBuffer[tid].size() <= skidBufferMax && 681 "Skidbuffer Exceeded Max Size"); 682} 683 684template<class Impl> 685int 686DefaultIEW<Impl>::skidCount() 687{ 688 int max=0; 689 690 list<unsigned>::iterator threads = (*activeThreads).begin(); 691 692 while (threads != (*activeThreads).end()) { 693 unsigned thread_count = skidBuffer[*threads++].size(); 694 if (max < thread_count) 695 max = thread_count; 696 } 697 698 return max; 699} 700 701template<class Impl> 702bool 703DefaultIEW<Impl>::skidsEmpty() 704{ 705 list<unsigned>::iterator threads = (*activeThreads).begin(); 706 707 while (threads != (*activeThreads).end()) { 708 if (!skidBuffer[*threads++].empty()) 709 return false; 710 } 711 712 return true; 713} 714 715template <class Impl> 716void 717DefaultIEW<Impl>::updateStatus() 718{ 719 bool any_unblocking = false; 720 721 list<unsigned>::iterator threads = (*activeThreads).begin(); 722 723 threads = (*activeThreads).begin(); 724 725 while (threads != (*activeThreads).end()) { 726 unsigned tid = *threads++; 727 728 if (dispatchStatus[tid] == Unblocking) { 729 any_unblocking = true; 730 break; 731 } 732 } 733 734 // If there are no ready instructions waiting to be scheduled by the IQ, 735 // and there's no stores waiting to write back, and dispatch is not 736 // unblocking, then there is no internal activity for the IEW stage. 737 if (_status == Active && !instQueue.hasReadyInsts() && 738 !ldstQueue.willWB() && !any_unblocking) { 739 DPRINTF(IEW, "IEW switching to idle\n"); 740 741 deactivateStage(); 742 743 _status = Inactive; 744 } else if (_status == Inactive && (instQueue.hasReadyInsts() || 745 ldstQueue.willWB() || 746 any_unblocking)) { 747 // Otherwise there is internal activity. Set to active. 748 DPRINTF(IEW, "IEW switching to active\n"); 749 750 activateStage(); 751 752 _status = Active; 753 } 754} 755 756template <class Impl> 757void 758DefaultIEW<Impl>::resetEntries() 759{ 760 instQueue.resetEntries(); 761 ldstQueue.resetEntries(); 762} 763 764template <class Impl> 765void 766DefaultIEW<Impl>::readStallSignals(unsigned tid) 767{ 768 if (fromCommit->commitBlock[tid]) { 769 stalls[tid].commit = true; 770 } 771 772 if (fromCommit->commitUnblock[tid]) { 773 assert(stalls[tid].commit); 774 stalls[tid].commit = false; 775 } 776} 777 778template <class Impl> 779bool 780DefaultIEW<Impl>::checkStall(unsigned tid) 781{ 782 bool ret_val(false); 783 784 if (stalls[tid].commit) { 785 DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid); 786 ret_val = true; 787 } else if (instQueue.isFull(tid)) { 788 DPRINTF(IEW,"[tid:%i]: Stall: IQ is full.\n",tid); 789 ret_val = true; 790 } else if (ldstQueue.isFull(tid)) { 791 DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid); 792 793 if (ldstQueue.numLoads(tid) > 0 ) { 794 795 DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n", 796 tid,ldstQueue.getLoadHeadSeqNum(tid)); 797 } 798 799 if (ldstQueue.numStores(tid) > 0) { 800 801 DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n", 802 tid,ldstQueue.getStoreHeadSeqNum(tid)); 803 } 804 805 ret_val = true; 806 } else if (ldstQueue.isStalled(tid)) { 807 DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid); 808 ret_val = true; 809 } 810 811 return ret_val; 812} 813 814template <class Impl> 815void 816DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid) 817{ 818 // Check if there's a squash signal, squash if there is 819 // Check stall signals, block if there is. 820 // If status was Blocked 821 // if so then go to unblocking 822 // If status was Squashing 823 // check if squashing is not high. Switch to running this cycle. 824 825 readStallSignals(tid); 826 827 if (fromCommit->commitInfo[tid].squash) { 828 squash(tid); 829 830 if (dispatchStatus[tid] == Blocked || 831 dispatchStatus[tid] == Unblocking) { 832 toRename->iewUnblock[tid] = true; 833 wroteToTimeBuffer = true; 834 } 835 836 dispatchStatus[tid] = Squashing; 837 838 fetchRedirect[tid] = false; 839 return; 840 } 841 842 if (fromCommit->commitInfo[tid].robSquashing) { 843 DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid); 844 845 dispatchStatus[tid] = Squashing; 846 847 emptyRenameInsts(tid); 848 wroteToTimeBuffer = true; 849 return; 850 } 851 852 if (checkStall(tid)) { 853 block(tid); 854 dispatchStatus[tid] = Blocked; 855 return; 856 } 857 858 if (dispatchStatus[tid] == Blocked) { 859 // Status from previous cycle was blocked, but there are no more stall 860 // conditions. Switch over to unblocking. 861 DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n", 862 tid); 863 864 dispatchStatus[tid] = Unblocking; 865 866 unblock(tid); 867 868 return; 869 } 870 871 if (dispatchStatus[tid] == Squashing) { 872 // Switch status to running if rename isn't being told to block or 873 // squash this cycle. 874 DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n", 875 tid); 876 877 dispatchStatus[tid] = Running; 878 879 return; 880 } 881} 882 883template <class Impl> 884void 885DefaultIEW<Impl>::sortInsts() 886{ 887 int insts_from_rename = fromRename->size; 888#ifdef DEBUG 889 for (int i = 0; i < numThreads; i++) 890 assert(insts[i].empty()); 891#endif 892 for (int i = 0; i < insts_from_rename; ++i) { 893 insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]); 894 } 895} 896 897template <class Impl> 898void 899DefaultIEW<Impl>::emptyRenameInsts(unsigned tid) 900{ 901 while (!insts[tid].empty()) { 902 if (insts[tid].front()->isLoad() || 903 insts[tid].front()->isStore() ) { 904 toRename->iewInfo[tid].dispatchedToLSQ++; 905 } 906 907 toRename->iewInfo[tid].dispatched++; 908 909 insts[tid].pop(); 910 } 911} 912 913template <class Impl> 914void 915DefaultIEW<Impl>::wakeCPU() 916{ 917 cpu->wakeCPU(); 918} 919 920template <class Impl> 921void 922DefaultIEW<Impl>::activityThisCycle() 923{ 924 DPRINTF(Activity, "Activity this cycle.\n"); 925 cpu->activityThisCycle(); 926} 927 928template <class Impl> 929inline void 930DefaultIEW<Impl>::activateStage() 931{ 932 DPRINTF(Activity, "Activating stage.\n"); 933 cpu->activateStage(FullCPU::IEWIdx); 934} 935 936template <class Impl> 937inline void 938DefaultIEW<Impl>::deactivateStage() 939{ 940 DPRINTF(Activity, "Deactivating stage.\n"); 941 cpu->deactivateStage(FullCPU::IEWIdx); 942} 943 944template<class Impl> 945void 946DefaultIEW<Impl>::dispatch(unsigned tid) 947{ 948 // If status is Running or idle, 949 // call dispatchInsts() 950 // If status is Unblocking, 951 // buffer any instructions coming from rename 952 // continue trying to empty skid buffer 953 // check if stall conditions have passed 954 955 if (dispatchStatus[tid] == Blocked) { 956 ++iewBlockCycles; 957 958 } else if (dispatchStatus[tid] == Squashing) { 959 ++iewSquashCycles; 960 } 961 962 // Dispatch should try to dispatch as many instructions as its bandwidth 963 // will allow, as long as it is not currently blocked. 964 if (dispatchStatus[tid] == Running || 965 dispatchStatus[tid] == Idle) { 966 DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run " 967 "dispatch.\n", tid); 968 969 dispatchInsts(tid); 970 } else if (dispatchStatus[tid] == Unblocking) { 971 // Make sure that the skid buffer has something in it if the 972 // status is unblocking. 973 assert(!skidsEmpty()); 974 975 // If the status was unblocking, then instructions from the skid 976 // buffer were used. Remove those instructions and handle 977 // the rest of unblocking. 978 dispatchInsts(tid); 979 980 ++iewUnblockCycles; 981 982 if (validInstsFromRename() && dispatchedAllInsts) { 983 // Add the current inputs to the skid buffer so they can be 984 // reprocessed when this stage unblocks. 985 skidInsert(tid); 986 } 987 988 unblock(tid); 989 } 990} 991 992template <class Impl> 993void 994DefaultIEW<Impl>::dispatchInsts(unsigned tid) 995{ 996 dispatchedAllInsts = true; 997 998 // Obtain instructions from skid buffer if unblocking, or queue from rename 999 // otherwise. 1000 std::queue<DynInstPtr> &insts_to_dispatch = 1001 dispatchStatus[tid] == Unblocking ? 1002 skidBuffer[tid] : insts[tid]; 1003 1004 int insts_to_add = insts_to_dispatch.size(); 1005 1006 DynInstPtr inst; 1007 bool add_to_iq = false; 1008 int dis_num_inst = 0; 1009 1010 // Loop through the instructions, putting them in the instruction 1011 // queue. 1012 for ( ; dis_num_inst < insts_to_add && 1013 dis_num_inst < dispatchWidth; 1014 ++dis_num_inst) 1015 { 1016 inst = insts_to_dispatch.front(); 1017 1018 if (dispatchStatus[tid] == Unblocking) { 1019 DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid " 1020 "buffer\n", tid); 1021 } 1022 1023 // Make sure there's a valid instruction there. 1024 assert(inst); 1025 1026 DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to " 1027 "IQ.\n", 1028 tid, inst->readPC(), inst->seqNum, inst->threadNumber); 1029 1030 // Be sure to mark these instructions as ready so that the 1031 // commit stage can go ahead and execute them, and mark 1032 // them as issued so the IQ doesn't reprocess them. 1033 1034 // Check for squashed instructions. 1035 if (inst->isSquashed()) { 1036 DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, " 1037 "not adding to IQ.\n", tid); 1038 1039 ++iewDispSquashedInsts; 1040 1041 insts_to_dispatch.pop(); 1042 1043 //Tell Rename That An Instruction has been processed 1044 if (inst->isLoad() || inst->isStore()) { 1045 toRename->iewInfo[tid].dispatchedToLSQ++; 1046 } 1047 toRename->iewInfo[tid].dispatched++; 1048 1049 continue; 1050 } 1051 1052 // Check for full conditions. 1053 if (instQueue.isFull(tid)) { 1054 DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid); 1055 1056 // Call function to start blocking. 1057 block(tid); 1058 1059 // Set unblock to false. Special case where we are using 1060 // skidbuffer (unblocking) instructions but then we still 1061 // get full in the IQ. 1062 toRename->iewUnblock[tid] = false; 1063 1064 dispatchedAllInsts = false; 1065 1066 ++iewIQFullEvents; 1067 break; 1068 } else if (ldstQueue.isFull(tid)) { 1069 DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid); 1070 1071 // Call function to start blocking. 1072 block(tid); 1073 1074 // Set unblock to false. Special case where we are using 1075 // skidbuffer (unblocking) instructions but then we still 1076 // get full in the IQ. 1077 toRename->iewUnblock[tid] = false; 1078 1079 dispatchedAllInsts = false; 1080 1081 ++iewLSQFullEvents; 1082 break; 1083 } 1084 1085 // Otherwise issue the instruction just fine. 1086 if (inst->isLoad()) { 1087 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 1088 "encountered, adding to LSQ.\n", tid); 1089 1090 // Reserve a spot in the load store queue for this 1091 // memory access. 1092 ldstQueue.insertLoad(inst); 1093 1094 ++iewDispLoadInsts; 1095 1096 add_to_iq = true; 1097 1098 toRename->iewInfo[tid].dispatchedToLSQ++; 1099 } else if (inst->isStore()) { 1100 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 1101 "encountered, adding to LSQ.\n", tid); 1102 1103 ldstQueue.insertStore(inst); 1104 1105 ++iewDispStoreInsts; 1106 1107 if (inst->isStoreConditional()) { 1108 // Store conditionals need to be set as "canCommit()" 1109 // so that commit can process them when they reach the 1110 // head of commit. 1111 // @todo: This is somewhat specific to Alpha. 1112 inst->setCanCommit(); 1113 instQueue.insertNonSpec(inst); 1114 add_to_iq = false; 1115 1116 ++iewDispNonSpecInsts; 1117 } else { 1118 add_to_iq = true; 1119 } 1120 1121 toRename->iewInfo[tid].dispatchedToLSQ++; 1122#if FULL_SYSTEM 1123 } else if (inst->isMemBarrier() || inst->isWriteBarrier()) { 1124 // Same as non-speculative stores. 1125 inst->setCanCommit(); 1126 instQueue.insertBarrier(inst); 1127 add_to_iq = false; 1128#endif 1129 } else if (inst->isNonSpeculative()) { 1130 DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction " 1131 "encountered, skipping.\n", tid); 1132 1133 // Same as non-speculative stores. 1134 inst->setCanCommit(); 1135 1136 // Specifically insert it as nonspeculative. 1137 instQueue.insertNonSpec(inst); 1138 1139 ++iewDispNonSpecInsts; 1140 1141 add_to_iq = false; 1142 } else if (inst->isNop()) { 1143 DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, " 1144 "skipping.\n", tid); 1145 1146 inst->setIssued(); 1147 inst->setExecuted(); 1148 inst->setCanCommit(); 1149 1150 instQueue.recordProducer(inst); 1151 1152 iewExecutedNop[tid]++; 1153 1154 add_to_iq = false; 1155 } else if (inst->isExecuted()) { 1156 assert(0 && "Instruction shouldn't be executed.\n"); 1157 DPRINTF(IEW, "Issue: Executed branch encountered, " 1158 "skipping.\n"); 1159 1160 inst->setIssued(); 1161 inst->setCanCommit(); 1162 1163 instQueue.recordProducer(inst); 1164 1165 add_to_iq = false; 1166 } else { 1167 add_to_iq = true; 1168 } 1169 1170 // If the instruction queue is not full, then add the 1171 // instruction. 1172 if (add_to_iq) { 1173 instQueue.insert(inst); 1174 } 1175 1176 insts_to_dispatch.pop(); 1177 1178 toRename->iewInfo[tid].dispatched++; 1179 1180 ++iewDispatchedInsts; 1181 } 1182 1183 if (!insts_to_dispatch.empty()) { 1184 DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n"); 1185 block(tid); 1186 toRename->iewUnblock[tid] = false; 1187 } 1188 1189 if (dispatchStatus[tid] == Idle && dis_num_inst) { 1190 dispatchStatus[tid] = Running; 1191 1192 updatedQueues = true; 1193 } 1194 1195 dis_num_inst = 0; 1196} 1197 1198template <class Impl> 1199void 1200DefaultIEW<Impl>::printAvailableInsts() 1201{ 1202 int inst = 0; 1203 1204 cout << "Available Instructions: "; 1205 1206 while (fromIssue->insts[inst]) { 1207 1208 if (inst%3==0) cout << "\n\t"; 1209 1210 cout << "PC: " << fromIssue->insts[inst]->readPC() 1211 << " TN: " << fromIssue->insts[inst]->threadNumber 1212 << " SN: " << fromIssue->insts[inst]->seqNum << " | "; 1213 1214 inst++; 1215 1216 } 1217 1218 cout << "\n"; 1219} 1220 1221template <class Impl> 1222void 1223DefaultIEW<Impl>::executeInsts() 1224{ 1225 wbNumInst = 0; 1226 wbCycle = 0; 1227 1228 list<unsigned>::iterator threads = (*activeThreads).begin(); 1229 1230 while (threads != (*activeThreads).end()) { 1231 unsigned tid = *threads++; 1232 fetchRedirect[tid] = false; 1233 } 1234 1235#if 0 1236 printAvailableInsts(); 1237#endif 1238 1239 // Execute/writeback any instructions that are available. 1240 int insts_to_execute = fromIssue->size; 1241 int inst_num = 0; 1242 for (; inst_num < insts_to_execute; 1243 ++inst_num) { 1244 1245 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n"); 1246 1247 DynInstPtr inst = instQueue.getInstToExecute(); 1248 1249 DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n", 1250 inst->readPC(), inst->threadNumber,inst->seqNum); 1251 1252 // Check if the instruction is squashed; if so then skip it 1253 if (inst->isSquashed()) { 1254 DPRINTF(IEW, "Execute: Instruction was squashed.\n"); 1255 1256 // Consider this instruction executed so that commit can go 1257 // ahead and retire the instruction. 1258 inst->setExecuted(); 1259 1260 // Not sure if I should set this here or just let commit try to 1261 // commit any squashed instructions. I like the latter a bit more. 1262 inst->setCanCommit(); 1263 1264 ++iewExecSquashedInsts; 1265 1266 decrWb(inst->seqNum); 1267 continue; 1268 } 1269 1270 Fault fault = NoFault; 1271 1272 // Execute instruction. 1273 // Note that if the instruction faults, it will be handled 1274 // at the commit stage. 1275 if (inst->isMemRef() && 1276 (!inst->isDataPrefetch() && !inst->isInstPrefetch())) { 1277 DPRINTF(IEW, "Execute: Calculating address for memory " 1278 "reference.\n"); 1279 1280 // Tell the LDSTQ to execute this instruction (if it is a load). 1281 if (inst->isLoad()) { 1282 // Loads will mark themselves as executed, and their writeback 1283 // event adds the instruction to the queue to commit 1284 fault = ldstQueue.executeLoad(inst); 1285 } else if (inst->isStore()) { 1286 fault = ldstQueue.executeStore(inst); 1287 1288 // If the store had a fault then it may not have a mem req 1289 if (!inst->isStoreConditional() && fault == NoFault) { 1290 inst->setExecuted(); 1291 1292 instToCommit(inst); 1293 } else if (fault != NoFault) { 1294 // If the instruction faulted, then we need to send it along to commit 1295 // without the instruction completing. 1296 1297 // Send this instruction to commit, also make sure iew stage 1298 // realizes there is activity. 1299 inst->setExecuted(); 1300 1301 instToCommit(inst); 1302 activityThisCycle(); 1303 } 1304 1305 // Store conditionals will mark themselves as 1306 // executed, and their writeback event will add the 1307 // instruction to the queue to commit. 1308 } else { 1309 panic("Unexpected memory type!\n"); 1310 } 1311 1312 } else { 1313 inst->execute(); 1314 1315 inst->setExecuted(); 1316 1317 instToCommit(inst); 1318 } 1319 1320 updateExeInstStats(inst); 1321 1322 // Check if branch prediction was correct, if not then we need 1323 // to tell commit to squash in flight instructions. Only 1324 // handle this if there hasn't already been something that 1325 // redirects fetch in this group of instructions. 1326 1327 // This probably needs to prioritize the redirects if a different 1328 // scheduler is used. Currently the scheduler schedules the oldest 1329 // instruction first, so the branch resolution order will be correct. 1330 unsigned tid = inst->threadNumber; 1331 1332 if (!fetchRedirect[tid]) { 1333 1334 if (inst->mispredicted()) { 1335 fetchRedirect[tid] = true; 1336 1337 DPRINTF(IEW, "Execute: Branch mispredict detected.\n"); 1338 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n", 1339 inst->nextPC); 1340 1341 // If incorrect, then signal the ROB that it must be squashed. 1342 squashDueToBranch(inst, tid); 1343 1344 if (inst->predTaken()) { 1345 predictedTakenIncorrect++; 1346 } else { 1347 predictedNotTakenIncorrect++; 1348 } 1349 } else if (ldstQueue.violation(tid)) { 1350 fetchRedirect[tid] = true; 1351 1352 // If there was an ordering violation, then get the 1353 // DynInst that caused the violation. Note that this 1354 // clears the violation signal. 1355 DynInstPtr violator; 1356 violator = ldstQueue.getMemDepViolator(tid); 1357 1358 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: " 1359 "%#x, inst PC: %#x. Addr is: %#x.\n", 1360 violator->readPC(), inst->readPC(), inst->physEffAddr); 1361 1362 // Tell the instruction queue that a violation has occured. 1363 instQueue.violation(inst, violator); 1364 1365 // Squash. 1366 squashDueToMemOrder(inst,tid); 1367 1368 ++memOrderViolationEvents; 1369 } else if (ldstQueue.loadBlocked(tid) && 1370 !ldstQueue.isLoadBlockedHandled(tid)) { 1371 fetchRedirect[tid] = true; 1372 1373 DPRINTF(IEW, "Load operation couldn't execute because the " 1374 "memory system is blocked. PC: %#x [sn:%lli]\n", 1375 inst->readPC(), inst->seqNum); 1376 1377 squashDueToMemBlocked(inst, tid); 1378 } 1379 } 1380 } 1381 1382 // Update and record activity if we processed any instructions. 1383 if (inst_num) { 1384 if (exeStatus == Idle) { 1385 exeStatus = Running; 1386 } 1387 1388 updatedQueues = true; 1389 1390 cpu->activityThisCycle(); 1391 } 1392 1393 // Need to reset this in case a writeback event needs to write into the 1394 // iew queue. That way the writeback event will write into the correct 1395 // spot in the queue. 1396 wbNumInst = 0; 1397} 1398 1399template <class Impl> 1400void 1401DefaultIEW<Impl>::writebackInsts() 1402{ 1403 // Loop through the head of the time buffer and wake any 1404 // dependents. These instructions are about to write back. Also 1405 // mark scoreboard that this instruction is finally complete. 1406 // Either have IEW have direct access to scoreboard, or have this 1407 // as part of backwards communication. 1408 for (int inst_num = 0; inst_num < issueWidth && 1409 toCommit->insts[inst_num]; inst_num++) { 1410 DynInstPtr inst = toCommit->insts[inst_num]; 1411 int tid = inst->threadNumber; 1412 1413 DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %#x.\n", 1414 inst->seqNum, inst->readPC()); 1415 1416 iewInstsToCommit[tid]++; 1417 1418 // Some instructions will be sent to commit without having 1419 // executed because they need commit to handle them. 1420 // E.g. Uncached loads have not actually executed when they 1421 // are first sent to commit. Instead commit must tell the LSQ 1422 // when it's ready to execute the uncached load. 1423 if (!inst->isSquashed() && inst->isExecuted() && inst->getFault() == NoFault) { 1424 int dependents = instQueue.wakeDependents(inst); 1425 1426 for (int i = 0; i < inst->numDestRegs(); i++) { 1427 //mark as Ready 1428 DPRINTF(IEW,"Setting Destination Register %i\n", 1429 inst->renamedDestRegIdx(i)); 1430 scoreboard->setReg(inst->renamedDestRegIdx(i)); 1431 } 1432 1433 if (dependents) { 1434 producerInst[tid]++; 1435 consumerInst[tid]+= dependents; 1436 } 1437 writebackCount[tid]++; 1438 } 1439 1440 decrWb(inst->seqNum); 1441 } 1442} 1443 1444template<class Impl> 1445void 1446DefaultIEW<Impl>::tick() 1447{ 1448 wbNumInst = 0; 1449 wbCycle = 0; 1450 1451 wroteToTimeBuffer = false; 1452 updatedQueues = false; 1453 1454 sortInsts(); 1455 1456 // Free function units marked as being freed this cycle. 1457 fuPool->processFreeUnits(); 1458 1459 list<unsigned>::iterator threads = (*activeThreads).begin(); 1460 1461 // Check stall and squash signals, dispatch any instructions. 1462 while (threads != (*activeThreads).end()) { 1463 unsigned tid = *threads++; 1464 1465 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid); 1466 1467 checkSignalsAndUpdate(tid); 1468 dispatch(tid); 1469 } 1470 1471 if (exeStatus != Squashing) { 1472 executeInsts(); 1473 1474 writebackInsts(); 1475 1476 // Have the instruction queue try to schedule any ready instructions. 1477 // (In actuality, this scheduling is for instructions that will 1478 // be executed next cycle.) 1479 instQueue.scheduleReadyInsts(); 1480 1481 // Also should advance its own time buffers if the stage ran. 1482 // Not the best place for it, but this works (hopefully). 1483 issueToExecQueue.advance(); 1484 } 1485 1486 bool broadcast_free_entries = false; 1487 1488 if (updatedQueues || exeStatus == Running || updateLSQNextCycle) { 1489 exeStatus = Idle; 1490 updateLSQNextCycle = false; 1491 1492 broadcast_free_entries = true; 1493 } 1494 1495 // Writeback any stores using any leftover bandwidth. 1496 ldstQueue.writebackStores(); 1497 1498 // Check the committed load/store signals to see if there's a load 1499 // or store to commit. Also check if it's being told to execute a 1500 // nonspeculative instruction. 1501 // This is pretty inefficient... 1502 1503 threads = (*activeThreads).begin(); 1504 while (threads != (*activeThreads).end()) { 1505 unsigned tid = (*threads++); 1506 1507 DPRINTF(IEW,"Processing [tid:%i]\n",tid); 1508 1509 // Update structures based on instructions committed. 1510 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 1511 !fromCommit->commitInfo[tid].squash && 1512 !fromCommit->commitInfo[tid].robSquashing) { 1513 1514 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid); 1515 1516 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid); 1517 1518 updateLSQNextCycle = true; 1519 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid); 1520 } 1521 1522 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) { 1523 1524 //DPRINTF(IEW,"NonspecInst from thread %i",tid); 1525 if (fromCommit->commitInfo[tid].uncached) { 1526 instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad); 1527 } else { 1528 instQueue.scheduleNonSpec( 1529 fromCommit->commitInfo[tid].nonSpecSeqNum); 1530 } 1531 } 1532 1533 if (broadcast_free_entries) { 1534 toFetch->iewInfo[tid].iqCount = 1535 instQueue.getCount(tid); 1536 toFetch->iewInfo[tid].ldstqCount = 1537 ldstQueue.getCount(tid); 1538 1539 toRename->iewInfo[tid].usedIQ = true; 1540 toRename->iewInfo[tid].freeIQEntries = 1541 instQueue.numFreeEntries(); 1542 toRename->iewInfo[tid].usedLSQ = true; 1543 toRename->iewInfo[tid].freeLSQEntries = 1544 ldstQueue.numFreeEntries(tid); 1545 1546 wroteToTimeBuffer = true; 1547 } 1548 1549 DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n", 1550 tid, toRename->iewInfo[tid].dispatched); 1551 } 1552 1553 DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). " 1554 "LSQ has %i free entries.\n", 1555 instQueue.numFreeEntries(), instQueue.hasReadyInsts(), 1556 ldstQueue.numFreeEntries()); 1557 1558 updateStatus(); 1559 1560 if (wroteToTimeBuffer) { 1561 DPRINTF(Activity, "Activity this cycle.\n"); 1562 cpu->activityThisCycle(); 1563 } 1564} 1565 1566template <class Impl> 1567void 1568DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst) 1569{ 1570 int thread_number = inst->threadNumber; 1571 1572 // 1573 // Pick off the software prefetches 1574 // 1575#ifdef TARGET_ALPHA 1576 if (inst->isDataPrefetch()) 1577 iewExecutedSwp[thread_number]++; 1578 else 1579 iewExecutedInsts++; 1580#else 1581 iewExecutedInsts[thread_number]++; 1582#endif 1583 1584 // 1585 // Control operations 1586 // 1587 if (inst->isControl()) 1588 iewExecutedBranches[thread_number]++; 1589 1590 // 1591 // Memory operations 1592 // 1593 if (inst->isMemRef()) { 1594 iewExecutedRefs[thread_number]++; 1595 1596 if (inst->isLoad()) { 1597 iewExecLoadInsts[thread_number]++; 1598 } 1599 } 1600} 1601