iew_impl.hh revision 2353
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 435 instQueue.switchOut(); 436 ldstQueue.switchOut(); 437 fuPool->switchOut(); 438 439 for (int i = 0; i < numThreads; i++) { 440 while (!insts[i].empty()) 441 insts[i].pop(); 442 while (!skidBuffer[i].empty()) 443 skidBuffer[i].pop(); 444 } 445} 446 447template <class Impl> 448void 449DefaultIEW<Impl>::takeOverFrom() 450{ 451 // Reset all state. 452 _status = Active; 453 exeStatus = Running; 454 wbStatus = Idle; 455 switchedOut = false; 456 457 instQueue.takeOverFrom(); 458 ldstQueue.takeOverFrom(); 459 fuPool->takeOverFrom(); 460 461 initStage(); 462 cpu->activityThisCycle(); 463 464 for (int i=0; i < numThreads; i++) { 465 dispatchStatus[i] = Running; 466 stalls[i].commit = false; 467 fetchRedirect[i] = false; 468 } 469 470 updateLSQNextCycle = false; 471 472 for (int i = 0; i < issueToExecQueue.getSize(); ++i) { 473 issueToExecQueue.advance(); 474 } 475} 476 477template<class Impl> 478void 479DefaultIEW<Impl>::squash(unsigned tid) 480{ 481 DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n", 482 tid); 483 484 // Tell the IQ to start squashing. 485 instQueue.squash(tid); 486 487 // Tell the LDSTQ to start squashing. 488 ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid); 489 490 updatedQueues = true; 491 492 // Clear the skid buffer in case it has any data in it. 493 while (!skidBuffer[tid].empty()) { 494 495 if (skidBuffer[tid].front()->isLoad() || 496 skidBuffer[tid].front()->isStore() ) { 497 toRename->iewInfo[tid].dispatchedToLSQ++; 498 } 499 500 toRename->iewInfo[tid].dispatched++; 501 502 skidBuffer[tid].pop(); 503 } 504 505 emptyRenameInsts(tid); 506} 507 508template<class Impl> 509void 510DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid) 511{ 512 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x " 513 "[sn:%i].\n", tid, inst->readPC(), inst->seqNum); 514 515 toCommit->squash[tid] = true; 516 toCommit->squashedSeqNum[tid] = inst->seqNum; 517 toCommit->mispredPC[tid] = inst->readPC(); 518 toCommit->nextPC[tid] = inst->readNextPC(); 519 toCommit->branchMispredict[tid] = true; 520 toCommit->branchTaken[tid] = inst->readNextPC() != 521 (inst->readPC() + sizeof(TheISA::MachInst)); 522 523 toCommit->includeSquashInst[tid] = false; 524 525 wroteToTimeBuffer = true; 526} 527 528template<class Impl> 529void 530DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid) 531{ 532 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, " 533 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 534 535 toCommit->squash[tid] = true; 536 toCommit->squashedSeqNum[tid] = inst->seqNum; 537 toCommit->nextPC[tid] = inst->readNextPC(); 538 539 toCommit->includeSquashInst[tid] = false; 540 541 wroteToTimeBuffer = true; 542} 543 544template<class Impl> 545void 546DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid) 547{ 548 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, " 549 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 550 551 toCommit->squash[tid] = true; 552 toCommit->squashedSeqNum[tid] = inst->seqNum; 553 toCommit->nextPC[tid] = inst->readPC(); 554 555 // Must include the broadcasted SN in the squash. 556 toCommit->includeSquashInst[tid] = true; 557 558 ldstQueue.setLoadBlockedHandled(tid); 559 560 wroteToTimeBuffer = true; 561} 562 563template<class Impl> 564void 565DefaultIEW<Impl>::block(unsigned tid) 566{ 567 DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid); 568 569 if (dispatchStatus[tid] != Blocked && 570 dispatchStatus[tid] != Unblocking) { 571 toRename->iewBlock[tid] = true; 572 wroteToTimeBuffer = true; 573 } 574 575 // Add the current inputs to the skid buffer so they can be 576 // reprocessed when this stage unblocks. 577 skidInsert(tid); 578 579 dispatchStatus[tid] = Blocked; 580} 581 582template<class Impl> 583void 584DefaultIEW<Impl>::unblock(unsigned tid) 585{ 586 DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid " 587 "buffer %u.\n",tid, tid); 588 589 // If the skid bufffer is empty, signal back to previous stages to unblock. 590 // Also switch status to running. 591 if (skidBuffer[tid].empty()) { 592 toRename->iewUnblock[tid] = true; 593 wroteToTimeBuffer = true; 594 DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid); 595 dispatchStatus[tid] = Running; 596 } 597} 598 599template<class Impl> 600void 601DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst) 602{ 603 instQueue.wakeDependents(inst); 604} 605 606template<class Impl> 607void 608DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst) 609{ 610 instQueue.rescheduleMemInst(inst); 611} 612 613template<class Impl> 614void 615DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst) 616{ 617 instQueue.replayMemInst(inst); 618} 619 620template<class Impl> 621void 622DefaultIEW<Impl>::instToCommit(DynInstPtr &inst) 623{ 624 // First check the time slot that this instruction will write 625 // to. If there are free write ports at the time, then go ahead 626 // and write the instruction to that time. If there are not, 627 // keep looking back to see where's the first time there's a 628 // free slot. 629 while ((*iewQueue)[wbCycle].insts[wbNumInst]) { 630 ++wbNumInst; 631 if (wbNumInst == wbWidth) { 632 ++wbCycle; 633 wbNumInst = 0; 634 } 635 636 assert((wbCycle * wbWidth + wbNumInst) <= wbMax); 637 } 638 639 DPRINTF(IEW, "Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n", 640 wbCycle, wbWidth, wbNumInst, wbCycle * wbWidth + wbNumInst); 641 // Add finished instruction to queue to commit. 642 (*iewQueue)[wbCycle].insts[wbNumInst] = inst; 643 (*iewQueue)[wbCycle].size++; 644} 645 646template <class Impl> 647unsigned 648DefaultIEW<Impl>::validInstsFromRename() 649{ 650 unsigned inst_count = 0; 651 652 for (int i=0; i<fromRename->size; i++) { 653 if (!fromRename->insts[i]->isSquashed()) 654 inst_count++; 655 } 656 657 return inst_count; 658} 659 660template<class Impl> 661void 662DefaultIEW<Impl>::skidInsert(unsigned tid) 663{ 664 DynInstPtr inst = NULL; 665 666 while (!insts[tid].empty()) { 667 inst = insts[tid].front(); 668 669 insts[tid].pop(); 670 671 DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into " 672 "dispatch skidBuffer %i\n",tid, inst->seqNum, 673 inst->readPC(),tid); 674 675 skidBuffer[tid].push(inst); 676 } 677 678 assert(skidBuffer[tid].size() <= skidBufferMax && 679 "Skidbuffer Exceeded Max Size"); 680} 681 682template<class Impl> 683int 684DefaultIEW<Impl>::skidCount() 685{ 686 int max=0; 687 688 list<unsigned>::iterator threads = (*activeThreads).begin(); 689 690 while (threads != (*activeThreads).end()) { 691 unsigned thread_count = skidBuffer[*threads++].size(); 692 if (max < thread_count) 693 max = thread_count; 694 } 695 696 return max; 697} 698 699template<class Impl> 700bool 701DefaultIEW<Impl>::skidsEmpty() 702{ 703 list<unsigned>::iterator threads = (*activeThreads).begin(); 704 705 while (threads != (*activeThreads).end()) { 706 if (!skidBuffer[*threads++].empty()) 707 return false; 708 } 709 710 return true; 711} 712 713template <class Impl> 714void 715DefaultIEW<Impl>::updateStatus() 716{ 717 bool any_unblocking = false; 718 719 list<unsigned>::iterator threads = (*activeThreads).begin(); 720 721 threads = (*activeThreads).begin(); 722 723 while (threads != (*activeThreads).end()) { 724 unsigned tid = *threads++; 725 726 if (dispatchStatus[tid] == Unblocking) { 727 any_unblocking = true; 728 break; 729 } 730 } 731 732 // If there are no ready instructions waiting to be scheduled by the IQ, 733 // and there's no stores waiting to write back, and dispatch is not 734 // unblocking, then there is no internal activity for the IEW stage. 735 if (_status == Active && !instQueue.hasReadyInsts() && 736 !ldstQueue.willWB() && !any_unblocking) { 737 DPRINTF(IEW, "IEW switching to idle\n"); 738 739 deactivateStage(); 740 741 _status = Inactive; 742 } else if (_status == Inactive && (instQueue.hasReadyInsts() || 743 ldstQueue.willWB() || 744 any_unblocking)) { 745 // Otherwise there is internal activity. Set to active. 746 DPRINTF(IEW, "IEW switching to active\n"); 747 748 activateStage(); 749 750 _status = Active; 751 } 752} 753 754template <class Impl> 755void 756DefaultIEW<Impl>::resetEntries() 757{ 758 instQueue.resetEntries(); 759 ldstQueue.resetEntries(); 760} 761 762template <class Impl> 763void 764DefaultIEW<Impl>::readStallSignals(unsigned tid) 765{ 766 if (fromCommit->commitBlock[tid]) { 767 stalls[tid].commit = true; 768 } 769 770 if (fromCommit->commitUnblock[tid]) { 771 assert(stalls[tid].commit); 772 stalls[tid].commit = false; 773 } 774} 775 776template <class Impl> 777bool 778DefaultIEW<Impl>::checkStall(unsigned tid) 779{ 780 bool ret_val(false); 781 782 if (stalls[tid].commit) { 783 DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid); 784 ret_val = true; 785 } else if (instQueue.isFull(tid)) { 786 DPRINTF(IEW,"[tid:%i]: Stall: IQ is full.\n",tid); 787 ret_val = true; 788 } else if (ldstQueue.isFull(tid)) { 789 DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid); 790 791 if (ldstQueue.numLoads(tid) > 0 ) { 792 793 DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n", 794 tid,ldstQueue.getLoadHeadSeqNum(tid)); 795 } 796 797 if (ldstQueue.numStores(tid) > 0) { 798 799 DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n", 800 tid,ldstQueue.getStoreHeadSeqNum(tid)); 801 } 802 803 ret_val = true; 804 } else if (ldstQueue.isStalled(tid)) { 805 DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid); 806 ret_val = true; 807 } 808 809 return ret_val; 810} 811 812template <class Impl> 813void 814DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid) 815{ 816 // Check if there's a squash signal, squash if there is 817 // Check stall signals, block if there is. 818 // If status was Blocked 819 // if so then go to unblocking 820 // If status was Squashing 821 // check if squashing is not high. Switch to running this cycle. 822 823 readStallSignals(tid); 824 825 if (fromCommit->commitInfo[tid].squash) { 826 squash(tid); 827 828 if (dispatchStatus[tid] == Blocked || 829 dispatchStatus[tid] == Unblocking) { 830 toRename->iewUnblock[tid] = true; 831 wroteToTimeBuffer = true; 832 } 833 834 dispatchStatus[tid] = Squashing; 835 836 fetchRedirect[tid] = false; 837 return; 838 } 839 840 if (fromCommit->commitInfo[tid].robSquashing) { 841 DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid); 842 843 dispatchStatus[tid] = Squashing; 844 845 emptyRenameInsts(tid); 846 wroteToTimeBuffer = true; 847 return; 848 } 849 850 if (checkStall(tid)) { 851 block(tid); 852 dispatchStatus[tid] = Blocked; 853 return; 854 } 855 856 if (dispatchStatus[tid] == Blocked) { 857 // Status from previous cycle was blocked, but there are no more stall 858 // conditions. Switch over to unblocking. 859 DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n", 860 tid); 861 862 dispatchStatus[tid] = Unblocking; 863 864 unblock(tid); 865 866 return; 867 } 868 869 if (dispatchStatus[tid] == Squashing) { 870 // Switch status to running if rename isn't being told to block or 871 // squash this cycle. 872 DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n", 873 tid); 874 875 dispatchStatus[tid] = Running; 876 877 return; 878 } 879} 880 881template <class Impl> 882void 883DefaultIEW<Impl>::sortInsts() 884{ 885 int insts_from_rename = fromRename->size; 886#ifdef DEBUG 887 for (int i = 0; i < numThreads; i++) 888 assert(insts[i].empty()); 889#endif 890 for (int i = 0; i < insts_from_rename; ++i) { 891 insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]); 892 } 893} 894 895template <class Impl> 896void 897DefaultIEW<Impl>::emptyRenameInsts(unsigned tid) 898{ 899 while (!insts[tid].empty()) { 900 if (insts[tid].front()->isLoad() || 901 insts[tid].front()->isStore() ) { 902 toRename->iewInfo[tid].dispatchedToLSQ++; 903 } 904 905 toRename->iewInfo[tid].dispatched++; 906 907 insts[tid].pop(); 908 } 909} 910 911template <class Impl> 912void 913DefaultIEW<Impl>::wakeCPU() 914{ 915 cpu->wakeCPU(); 916} 917 918template <class Impl> 919void 920DefaultIEW<Impl>::activityThisCycle() 921{ 922 DPRINTF(Activity, "Activity this cycle.\n"); 923 cpu->activityThisCycle(); 924} 925 926template <class Impl> 927inline void 928DefaultIEW<Impl>::activateStage() 929{ 930 DPRINTF(Activity, "Activating stage.\n"); 931 cpu->activateStage(FullCPU::IEWIdx); 932} 933 934template <class Impl> 935inline void 936DefaultIEW<Impl>::deactivateStage() 937{ 938 DPRINTF(Activity, "Deactivating stage.\n"); 939 cpu->deactivateStage(FullCPU::IEWIdx); 940} 941 942template<class Impl> 943void 944DefaultIEW<Impl>::dispatch(unsigned tid) 945{ 946 // If status is Running or idle, 947 // call dispatchInsts() 948 // If status is Unblocking, 949 // buffer any instructions coming from rename 950 // continue trying to empty skid buffer 951 // check if stall conditions have passed 952 953 if (dispatchStatus[tid] == Blocked) { 954 ++iewBlockCycles; 955 956 } else if (dispatchStatus[tid] == Squashing) { 957 ++iewSquashCycles; 958 } 959 960 // Dispatch should try to dispatch as many instructions as its bandwidth 961 // will allow, as long as it is not currently blocked. 962 if (dispatchStatus[tid] == Running || 963 dispatchStatus[tid] == Idle) { 964 DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run " 965 "dispatch.\n", tid); 966 967 dispatchInsts(tid); 968 } else if (dispatchStatus[tid] == Unblocking) { 969 // Make sure that the skid buffer has something in it if the 970 // status is unblocking. 971 assert(!skidsEmpty()); 972 973 // If the status was unblocking, then instructions from the skid 974 // buffer were used. Remove those instructions and handle 975 // the rest of unblocking. 976 dispatchInsts(tid); 977 978 ++iewUnblockCycles; 979 980 if (validInstsFromRename() && dispatchedAllInsts) { 981 // Add the current inputs to the skid buffer so they can be 982 // reprocessed when this stage unblocks. 983 skidInsert(tid); 984 } 985 986 unblock(tid); 987 } 988} 989 990template <class Impl> 991void 992DefaultIEW<Impl>::dispatchInsts(unsigned tid) 993{ 994 dispatchedAllInsts = true; 995 996 // Obtain instructions from skid buffer if unblocking, or queue from rename 997 // otherwise. 998 std::queue<DynInstPtr> &insts_to_dispatch = 999 dispatchStatus[tid] == Unblocking ? 1000 skidBuffer[tid] : insts[tid]; 1001 1002 int insts_to_add = insts_to_dispatch.size(); 1003 1004 DynInstPtr inst; 1005 bool add_to_iq = false; 1006 int dis_num_inst = 0; 1007 1008 // Loop through the instructions, putting them in the instruction 1009 // queue. 1010 for ( ; dis_num_inst < insts_to_add && 1011 dis_num_inst < dispatchWidth; 1012 ++dis_num_inst) 1013 { 1014 inst = insts_to_dispatch.front(); 1015 1016 if (dispatchStatus[tid] == Unblocking) { 1017 DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid " 1018 "buffer\n", tid); 1019 } 1020 1021 // Make sure there's a valid instruction there. 1022 assert(inst); 1023 1024 DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to " 1025 "IQ.\n", 1026 tid, inst->readPC(), inst->seqNum, inst->threadNumber); 1027 1028 // Be sure to mark these instructions as ready so that the 1029 // commit stage can go ahead and execute them, and mark 1030 // them as issued so the IQ doesn't reprocess them. 1031 1032 // Check for squashed instructions. 1033 if (inst->isSquashed()) { 1034 DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, " 1035 "not adding to IQ.\n", tid); 1036 1037 ++iewDispSquashedInsts; 1038 1039 insts_to_dispatch.pop(); 1040 1041 //Tell Rename That An Instruction has been processed 1042 if (inst->isLoad() || inst->isStore()) { 1043 toRename->iewInfo[tid].dispatchedToLSQ++; 1044 } 1045 toRename->iewInfo[tid].dispatched++; 1046 1047 continue; 1048 } 1049 1050 // Check for full conditions. 1051 if (instQueue.isFull(tid)) { 1052 DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid); 1053 1054 // Call function to start blocking. 1055 block(tid); 1056 1057 // Set unblock to false. Special case where we are using 1058 // skidbuffer (unblocking) instructions but then we still 1059 // get full in the IQ. 1060 toRename->iewUnblock[tid] = false; 1061 1062 dispatchedAllInsts = false; 1063 1064 ++iewIQFullEvents; 1065 break; 1066 } else if (ldstQueue.isFull(tid)) { 1067 DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid); 1068 1069 // Call function to start blocking. 1070 block(tid); 1071 1072 // Set unblock to false. Special case where we are using 1073 // skidbuffer (unblocking) instructions but then we still 1074 // get full in the IQ. 1075 toRename->iewUnblock[tid] = false; 1076 1077 dispatchedAllInsts = false; 1078 1079 ++iewLSQFullEvents; 1080 break; 1081 } 1082 1083 // Otherwise issue the instruction just fine. 1084 if (inst->isLoad()) { 1085 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 1086 "encountered, adding to LSQ.\n", tid); 1087 1088 // Reserve a spot in the load store queue for this 1089 // memory access. 1090 ldstQueue.insertLoad(inst); 1091 1092 ++iewDispLoadInsts; 1093 1094 add_to_iq = true; 1095 1096 toRename->iewInfo[tid].dispatchedToLSQ++; 1097 } else if (inst->isStore()) { 1098 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction " 1099 "encountered, adding to LSQ.\n", tid); 1100 1101 ldstQueue.insertStore(inst); 1102 1103 ++iewDispStoreInsts; 1104 1105 if (inst->isStoreConditional()) { 1106 // Store conditionals need to be set as "canCommit()" 1107 // so that commit can process them when they reach the 1108 // head of commit. 1109 // @todo: This is somewhat specific to Alpha. 1110 inst->setCanCommit(); 1111 instQueue.insertNonSpec(inst); 1112 add_to_iq = false; 1113 1114 ++iewDispNonSpecInsts; 1115 } else { 1116 add_to_iq = true; 1117 } 1118 1119 toRename->iewInfo[tid].dispatchedToLSQ++; 1120#if FULL_SYSTEM 1121 } else if (inst->isMemBarrier() || inst->isWriteBarrier()) { 1122 // Same as non-speculative stores. 1123 inst->setCanCommit(); 1124 instQueue.insertBarrier(inst); 1125 add_to_iq = false; 1126#endif 1127 } else if (inst->isNonSpeculative()) { 1128 DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction " 1129 "encountered, skipping.\n", tid); 1130 1131 // Same as non-speculative stores. 1132 inst->setCanCommit(); 1133 1134 // Specifically insert it as nonspeculative. 1135 instQueue.insertNonSpec(inst); 1136 1137 ++iewDispNonSpecInsts; 1138 1139 add_to_iq = false; 1140 } else if (inst->isNop()) { 1141 DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, " 1142 "skipping.\n", tid); 1143 1144 inst->setIssued(); 1145 inst->setExecuted(); 1146 inst->setCanCommit(); 1147 1148 instQueue.recordProducer(inst); 1149 1150 iewExecutedNop[tid]++; 1151 1152 add_to_iq = false; 1153 } else if (inst->isExecuted()) { 1154 assert(0 && "Instruction shouldn't be executed.\n"); 1155 DPRINTF(IEW, "Issue: Executed branch encountered, " 1156 "skipping.\n"); 1157 1158 inst->setIssued(); 1159 inst->setCanCommit(); 1160 1161 instQueue.recordProducer(inst); 1162 1163 add_to_iq = false; 1164 } else { 1165 add_to_iq = true; 1166 } 1167 1168 // If the instruction queue is not full, then add the 1169 // instruction. 1170 if (add_to_iq) { 1171 instQueue.insert(inst); 1172 } 1173 1174 insts_to_dispatch.pop(); 1175 1176 toRename->iewInfo[tid].dispatched++; 1177 1178 ++iewDispatchedInsts; 1179 } 1180 1181 if (!insts_to_dispatch.empty()) { 1182 DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n"); 1183 block(tid); 1184 toRename->iewUnblock[tid] = false; 1185 } 1186 1187 if (dispatchStatus[tid] == Idle && dis_num_inst) { 1188 dispatchStatus[tid] = Running; 1189 1190 updatedQueues = true; 1191 } 1192 1193 dis_num_inst = 0; 1194} 1195 1196template <class Impl> 1197void 1198DefaultIEW<Impl>::printAvailableInsts() 1199{ 1200 int inst = 0; 1201 1202 cout << "Available Instructions: "; 1203 1204 while (fromIssue->insts[inst]) { 1205 1206 if (inst%3==0) cout << "\n\t"; 1207 1208 cout << "PC: " << fromIssue->insts[inst]->readPC() 1209 << " TN: " << fromIssue->insts[inst]->threadNumber 1210 << " SN: " << fromIssue->insts[inst]->seqNum << " | "; 1211 1212 inst++; 1213 1214 } 1215 1216 cout << "\n"; 1217} 1218 1219template <class Impl> 1220void 1221DefaultIEW<Impl>::executeInsts() 1222{ 1223 wbNumInst = 0; 1224 wbCycle = 0; 1225 1226 list<unsigned>::iterator threads = (*activeThreads).begin(); 1227 1228 while (threads != (*activeThreads).end()) { 1229 unsigned tid = *threads++; 1230 fetchRedirect[tid] = false; 1231 } 1232 1233#if 0 1234 printAvailableInsts(); 1235#endif 1236 1237 // Execute/writeback any instructions that are available. 1238 int insts_to_execute = fromIssue->size; 1239 int inst_num = 0; 1240 for (; inst_num < insts_to_execute; 1241 ++inst_num) { 1242 1243 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n"); 1244 1245 DynInstPtr inst = instQueue.getInstToExecute(); 1246 1247 DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n", 1248 inst->readPC(), inst->threadNumber,inst->seqNum); 1249 1250 // Check if the instruction is squashed; if so then skip it 1251 if (inst->isSquashed()) { 1252 DPRINTF(IEW, "Execute: Instruction was squashed.\n"); 1253 1254 // Consider this instruction executed so that commit can go 1255 // ahead and retire the instruction. 1256 inst->setExecuted(); 1257 1258 // Not sure if I should set this here or just let commit try to 1259 // commit any squashed instructions. I like the latter a bit more. 1260 inst->setCanCommit(); 1261 1262 ++iewExecSquashedInsts; 1263 1264 decrWb(inst->seqNum); 1265 continue; 1266 } 1267 1268 Fault fault = NoFault; 1269 1270 // Execute instruction. 1271 // Note that if the instruction faults, it will be handled 1272 // at the commit stage. 1273 if (inst->isMemRef() && 1274 (!inst->isDataPrefetch() && !inst->isInstPrefetch())) { 1275 DPRINTF(IEW, "Execute: Calculating address for memory " 1276 "reference.\n"); 1277 1278 // Tell the LDSTQ to execute this instruction (if it is a load). 1279 if (inst->isLoad()) { 1280 // Loads will mark themselves as executed, and their writeback 1281 // event adds the instruction to the queue to commit 1282 fault = ldstQueue.executeLoad(inst); 1283 } else if (inst->isStore()) { 1284 ldstQueue.executeStore(inst); 1285 1286 // If the store had a fault then it may not have a mem req 1287 if (inst->req && !(inst->req->flags & LOCKED)) { 1288 inst->setExecuted(); 1289 1290 instToCommit(inst); 1291 } 1292 1293 // Store conditionals will mark themselves as 1294 // executed, and their writeback event will add the 1295 // instruction to the queue to commit. 1296 } else { 1297 panic("Unexpected memory type!\n"); 1298 } 1299 1300 } else { 1301 inst->execute(); 1302 1303 inst->setExecuted(); 1304 1305 instToCommit(inst); 1306 } 1307 1308 updateExeInstStats(inst); 1309 1310 // Check if branch prediction was correct, if not then we need 1311 // to tell commit to squash in flight instructions. Only 1312 // handle this if there hasn't already been something that 1313 // redirects fetch in this group of instructions. 1314 1315 // This probably needs to prioritize the redirects if a different 1316 // scheduler is used. Currently the scheduler schedules the oldest 1317 // instruction first, so the branch resolution order will be correct. 1318 unsigned tid = inst->threadNumber; 1319 1320 if (!fetchRedirect[tid]) { 1321 1322 if (inst->mispredicted()) { 1323 fetchRedirect[tid] = true; 1324 1325 DPRINTF(IEW, "Execute: Branch mispredict detected.\n"); 1326 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n", 1327 inst->nextPC); 1328 1329 // If incorrect, then signal the ROB that it must be squashed. 1330 squashDueToBranch(inst, tid); 1331 1332 if (inst->predTaken()) { 1333 predictedTakenIncorrect++; 1334 } else { 1335 predictedNotTakenIncorrect++; 1336 } 1337 } else if (ldstQueue.violation(tid)) { 1338 fetchRedirect[tid] = true; 1339 1340 // If there was an ordering violation, then get the 1341 // DynInst that caused the violation. Note that this 1342 // clears the violation signal. 1343 DynInstPtr violator; 1344 violator = ldstQueue.getMemDepViolator(tid); 1345 1346 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: " 1347 "%#x, inst PC: %#x. Addr is: %#x.\n", 1348 violator->readPC(), inst->readPC(), inst->physEffAddr); 1349 1350 // Tell the instruction queue that a violation has occured. 1351 instQueue.violation(inst, violator); 1352 1353 // Squash. 1354 squashDueToMemOrder(inst,tid); 1355 1356 ++memOrderViolationEvents; 1357 } else if (ldstQueue.loadBlocked(tid) && 1358 !ldstQueue.isLoadBlockedHandled(tid)) { 1359 fetchRedirect[tid] = true; 1360 1361 DPRINTF(IEW, "Load operation couldn't execute because the " 1362 "memory system is blocked. PC: %#x [sn:%lli]\n", 1363 inst->readPC(), inst->seqNum); 1364 1365 squashDueToMemBlocked(inst, tid); 1366 } 1367 } 1368 } 1369 1370 // Update and record activity if we processed any instructions. 1371 if (inst_num) { 1372 if (exeStatus == Idle) { 1373 exeStatus = Running; 1374 } 1375 1376 updatedQueues = true; 1377 1378 cpu->activityThisCycle(); 1379 } 1380 1381 // Need to reset this in case a writeback event needs to write into the 1382 // iew queue. That way the writeback event will write into the correct 1383 // spot in the queue. 1384 wbNumInst = 0; 1385} 1386 1387template <class Impl> 1388void 1389DefaultIEW<Impl>::writebackInsts() 1390{ 1391 // Loop through the head of the time buffer and wake any 1392 // dependents. These instructions are about to write back. Also 1393 // mark scoreboard that this instruction is finally complete. 1394 // Either have IEW have direct access to scoreboard, or have this 1395 // as part of backwards communication. 1396 for (int inst_num = 0; inst_num < issueWidth && 1397 toCommit->insts[inst_num]; inst_num++) { 1398 DynInstPtr inst = toCommit->insts[inst_num]; 1399 int tid = inst->threadNumber; 1400 1401 DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %#x.\n", 1402 inst->seqNum, inst->readPC()); 1403 1404 iewInstsToCommit[tid]++; 1405 1406 // Some instructions will be sent to commit without having 1407 // executed because they need commit to handle them. 1408 // E.g. Uncached loads have not actually executed when they 1409 // are first sent to commit. Instead commit must tell the LSQ 1410 // when it's ready to execute the uncached load. 1411 if (!inst->isSquashed() && inst->isExecuted()) { 1412 int dependents = instQueue.wakeDependents(inst); 1413 1414 for (int i = 0; i < inst->numDestRegs(); i++) { 1415 //mark as Ready 1416 DPRINTF(IEW,"Setting Destination Register %i\n", 1417 inst->renamedDestRegIdx(i)); 1418 scoreboard->setReg(inst->renamedDestRegIdx(i)); 1419 } 1420 1421 if (dependents) { 1422 producerInst[tid]++; 1423 consumerInst[tid]+= dependents; 1424 } 1425 writebackCount[tid]++; 1426 } 1427 1428 decrWb(inst->seqNum); 1429 } 1430} 1431 1432template<class Impl> 1433void 1434DefaultIEW<Impl>::tick() 1435{ 1436 wbNumInst = 0; 1437 wbCycle = 0; 1438 1439 wroteToTimeBuffer = false; 1440 updatedQueues = false; 1441 1442 sortInsts(); 1443 1444 // Free function units marked as being freed this cycle. 1445 fuPool->processFreeUnits(); 1446 1447 list<unsigned>::iterator threads = (*activeThreads).begin(); 1448 1449 // Check stall and squash signals, dispatch any instructions. 1450 while (threads != (*activeThreads).end()) { 1451 unsigned tid = *threads++; 1452 1453 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid); 1454 1455 checkSignalsAndUpdate(tid); 1456 dispatch(tid); 1457 } 1458 1459 if (exeStatus != Squashing) { 1460 executeInsts(); 1461 1462 writebackInsts(); 1463 1464 // Have the instruction queue try to schedule any ready instructions. 1465 // (In actuality, this scheduling is for instructions that will 1466 // be executed next cycle.) 1467 instQueue.scheduleReadyInsts(); 1468 1469 // Also should advance its own time buffers if the stage ran. 1470 // Not the best place for it, but this works (hopefully). 1471 issueToExecQueue.advance(); 1472 } 1473 1474 bool broadcast_free_entries = false; 1475 1476 if (updatedQueues || exeStatus == Running || updateLSQNextCycle) { 1477 exeStatus = Idle; 1478 updateLSQNextCycle = false; 1479 1480 broadcast_free_entries = true; 1481 } 1482 1483 // Writeback any stores using any leftover bandwidth. 1484 ldstQueue.writebackStores(); 1485 1486 // Check the committed load/store signals to see if there's a load 1487 // or store to commit. Also check if it's being told to execute a 1488 // nonspeculative instruction. 1489 // This is pretty inefficient... 1490 1491 threads = (*activeThreads).begin(); 1492 while (threads != (*activeThreads).end()) { 1493 unsigned tid = (*threads++); 1494 1495 DPRINTF(IEW,"Processing [tid:%i]\n",tid); 1496 1497 // Update structures based on instructions committed. 1498 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 1499 !fromCommit->commitInfo[tid].squash && 1500 !fromCommit->commitInfo[tid].robSquashing) { 1501 1502 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid); 1503 1504 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid); 1505 1506 updateLSQNextCycle = true; 1507 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid); 1508 } 1509 1510 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) { 1511 1512 //DPRINTF(IEW,"NonspecInst from thread %i",tid); 1513 if (fromCommit->commitInfo[tid].uncached) { 1514 instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad); 1515 } else { 1516 instQueue.scheduleNonSpec( 1517 fromCommit->commitInfo[tid].nonSpecSeqNum); 1518 } 1519 } 1520 1521 if (broadcast_free_entries) { 1522 toFetch->iewInfo[tid].iqCount = 1523 instQueue.getCount(tid); 1524 toFetch->iewInfo[tid].ldstqCount = 1525 ldstQueue.getCount(tid); 1526 1527 toRename->iewInfo[tid].usedIQ = true; 1528 toRename->iewInfo[tid].freeIQEntries = 1529 instQueue.numFreeEntries(); 1530 toRename->iewInfo[tid].usedLSQ = true; 1531 toRename->iewInfo[tid].freeLSQEntries = 1532 ldstQueue.numFreeEntries(tid); 1533 1534 wroteToTimeBuffer = true; 1535 } 1536 1537 DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n", 1538 tid, toRename->iewInfo[tid].dispatched); 1539 } 1540 1541 DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). " 1542 "LSQ has %i free entries.\n", 1543 instQueue.numFreeEntries(), instQueue.hasReadyInsts(), 1544 ldstQueue.numFreeEntries()); 1545 1546 updateStatus(); 1547 1548 if (wroteToTimeBuffer) { 1549 DPRINTF(Activity, "Activity this cycle.\n"); 1550 cpu->activityThisCycle(); 1551 } 1552} 1553 1554template <class Impl> 1555void 1556DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst) 1557{ 1558 int thread_number = inst->threadNumber; 1559 1560 // 1561 // Pick off the software prefetches 1562 // 1563#ifdef TARGET_ALPHA 1564 if (inst->isDataPrefetch()) 1565 iewExecutedSwp[thread_number]++; 1566 else 1567 iewExecutedInsts++; 1568#else 1569 iewExecutedInsts[thread_number]++; 1570#endif 1571 1572 // 1573 // Control operations 1574 // 1575 if (inst->isControl()) 1576 iewExecutedBranches[thread_number]++; 1577 1578 // 1579 // Memory operations 1580 // 1581 if (inst->isMemRef()) { 1582 iewExecutedRefs[thread_number]++; 1583 1584 if (inst->isLoad()) { 1585 iewExecLoadInsts[thread_number]++; 1586 } 1587 } 1588} 1589