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