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