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