iew_impl.hh revision 2702
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 41using namespace std; 42 43template<class Impl> 44DefaultIEW<Impl>::DefaultIEW(Params *params) 45 : // @todo: Make this into a parameter. 46 issueToExecQueue(5, 5), 47 instQueue(params), 48 ldstQueue(params), 49 fuPool(params->fuPool), 50 commitToIEWDelay(params->commitToIEWDelay), 51 renameToIEWDelay(params->renameToIEWDelay), 52 issueToExecuteDelay(params->issueToExecuteDelay), 53 issueReadWidth(params->issueWidth), 54 issueWidth(params->issueWidth), 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 instQueue.setIEW(this); 69 ldstQueue.setIEW(this); 70 71 for (int i=0; i < numThreads; i++) { 72 dispatchStatus[i] = Running; 73 stalls[i].commit = false; 74 fetchRedirect[i] = false; 75 } 76 77 updateLSQNextCycle = false; 78 79 skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth; 80} 81 82template <class Impl> 83std::string 84DefaultIEW<Impl>::name() const 85{ 86 return cpu->name() + ".iew"; 87} 88 89template <class Impl> 90void 91DefaultIEW<Impl>::regStats() 92{ 93 using namespace Stats; 94 95 instQueue.regStats(); 96 97 iewIdleCycles 98 .name(name() + ".iewIdleCycles") 99 .desc("Number of cycles IEW is idle"); 100 101 iewSquashCycles 102 .name(name() + ".iewSquashCycles") 103 .desc("Number of cycles IEW is squashing"); 104 105 iewBlockCycles 106 .name(name() + ".iewBlockCycles") 107 .desc("Number of cycles IEW is blocking"); 108 109 iewUnblockCycles 110 .name(name() + ".iewUnblockCycles") 111 .desc("Number of cycles IEW is unblocking"); 112 113 iewDispatchedInsts 114 .name(name() + ".iewDispatchedInsts") 115 .desc("Number of instructions dispatched to IQ"); 116 117 iewDispSquashedInsts 118 .name(name() + ".iewDispSquashedInsts") 119 .desc("Number of squashed instructions skipped by dispatch"); 120 121 iewDispLoadInsts 122 .name(name() + ".iewDispLoadInsts") 123 .desc("Number of dispatched load instructions"); 124 125 iewDispStoreInsts 126 .name(name() + ".iewDispStoreInsts") 127 .desc("Number of dispatched store instructions"); 128 129 iewDispNonSpecInsts 130 .name(name() + ".iewDispNonSpecInsts") 131 .desc("Number of dispatched non-speculative instructions"); 132 133 iewIQFullEvents 134 .name(name() + ".iewIQFullEvents") 135 .desc("Number of times the IQ has become full, causing a stall"); 136 137 iewLSQFullEvents 138 .name(name() + ".iewLSQFullEvents") 139 .desc("Number of times the LSQ has become full, causing a stall"); 140 141 iewExecutedInsts 142 .name(name() + ".iewExecutedInsts") 143 .desc("Number of executed instructions"); 144 145 iewExecLoadInsts 146 .init(cpu->number_of_threads) 147 .name(name() + ".iewExecLoadInsts") 148 .desc("Number of load instructions executed") 149 .flags(total); 150 151 iewExecSquashedInsts 152 .name(name() + ".iewExecSquashedInsts") 153 .desc("Number of squashed instructions skipped in execute"); 154 155 memOrderViolationEvents 156 .name(name() + ".memOrderViolationEvents") 157 .desc("Number of memory order violations"); 158 159 predictedTakenIncorrect 160 .name(name() + ".predictedTakenIncorrect") 161 .desc("Number of branches that were predicted taken incorrectly"); 162 163 predictedNotTakenIncorrect 164 .name(name() + ".predictedNotTakenIncorrect") 165 .desc("Number of branches that were predicted not taken incorrectly"); 166 167 branchMispredicts 168 .name(name() + ".branchMispredicts") 169 .desc("Number of branch mispredicts detected at execute"); 170 171 branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect; 172 173 exeSwp 174 .init(cpu->number_of_threads) 175 .name(name() + ".EXEC:swp") 176 .desc("number of swp insts executed") 177 .flags(total) 178 ; 179 180 exeNop 181 .init(cpu->number_of_threads) 182 .name(name() + ".EXEC:nop") 183 .desc("number of nop insts executed") 184 .flags(total) 185 ; 186 187 exeRefs 188 .init(cpu->number_of_threads) 189 .name(name() + ".EXEC:refs") 190 .desc("number of memory reference insts executed") 191 .flags(total) 192 ; 193 194 exeBranches 195 .init(cpu->number_of_threads) 196 .name(name() + ".EXEC:branches") 197 .desc("Number of branches executed") 198 .flags(total) 199 ; 200 201 issueRate 202 .name(name() + ".EXEC:rate") 203 .desc("Inst execution rate") 204 .flags(total) 205 ; 206 issueRate = iewExecutedInsts / cpu->numCycles; 207 208 iewExecStoreInsts 209 .name(name() + ".EXEC:stores") 210 .desc("Number of stores executed") 211 .flags(total) 212 ; 213 iewExecStoreInsts = exeRefs - iewExecLoadInsts; 214/* 215 for (int i=0; i<Num_OpClasses; ++i) { 216 stringstream subname; 217 subname << opClassStrings[i] << "_delay"; 218 issue_delay_dist.subname(i, subname.str()); 219 } 220*/ 221 // 222 // Other stats 223 // 224 225 iewInstsToCommit 226 .init(cpu->number_of_threads) 227 .name(name() + ".WB:sent") 228 .desc("cumulative count of insts sent to commit") 229 .flags(total) 230 ; 231 232 writebackCount 233 .init(cpu->number_of_threads) 234 .name(name() + ".WB:count") 235 .desc("cumulative count of insts written-back") 236 .flags(total) 237 ; 238 239 producerInst 240 .init(cpu->number_of_threads) 241 .name(name() + ".WB:producers") 242 .desc("num instructions producing a value") 243 .flags(total) 244 ; 245 246 consumerInst 247 .init(cpu->number_of_threads) 248 .name(name() + ".WB:consumers") 249 .desc("num instructions consuming a value") 250 .flags(total) 251 ; 252 253 wbPenalized 254 .init(cpu->number_of_threads) 255 .name(name() + ".WB:penalized") 256 .desc("number of instrctions required to write to 'other' IQ") 257 .flags(total) 258 ; 259 260 wbPenalizedRate 261 .name(name() + ".WB:penalized_rate") 262 .desc ("fraction of instructions written-back that wrote to 'other' IQ") 263 .flags(total) 264 ; 265 266 wbPenalizedRate = wbPenalized / writebackCount; 267 268 wbFanout 269 .name(name() + ".WB:fanout") 270 .desc("average fanout of values written-back") 271 .flags(total) 272 ; 273 274 wbFanout = producerInst / consumerInst; 275 276 wbRate 277 .name(name() + ".WB:rate") 278 .desc("insts written-back per cycle") 279 .flags(total) 280 ; 281 wbRate = writebackCount / cpu->numCycles; 282} 283 284template<class Impl> 285void 286DefaultIEW<Impl>::initStage() 287{ 288 for (int tid=0; tid < numThreads; tid++) { 289 toRename->iewInfo[tid].usedIQ = true; 290 toRename->iewInfo[tid].freeIQEntries = 291 instQueue.numFreeEntries(tid); 292 293 toRename->iewInfo[tid].usedLSQ = true; 294 toRename->iewInfo[tid].freeLSQEntries = 295 ldstQueue.numFreeEntries(tid); 296 } 297} 298 299template<class Impl> 300void 301DefaultIEW<Impl>::setCPU(FullCPU *cpu_ptr) 302{ 303 DPRINTF(IEW, "Setting CPU pointer.\n"); 304 cpu = cpu_ptr; 305 306 instQueue.setCPU(cpu_ptr); 307 ldstQueue.setCPU(cpu_ptr); 308 309 cpu->activateStage(FullCPU::IEWIdx); 310} 311 312template<class Impl> 313void 314DefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 315{ 316 DPRINTF(IEW, "Setting time buffer pointer.\n"); 317 timeBuffer = tb_ptr; 318 319 // Setup wire to read information from time buffer, from commit. 320 fromCommit = timeBuffer->getWire(-commitToIEWDelay); 321 322 // Setup wire to write information back to previous stages. 323 toRename = timeBuffer->getWire(0); 324 325 toFetch = timeBuffer->getWire(0); 326 327 // Instruction queue also needs main time buffer. 328 instQueue.setTimeBuffer(tb_ptr); 329} 330 331template<class Impl> 332void 333DefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 334{ 335 DPRINTF(IEW, "Setting rename queue pointer.\n"); 336 renameQueue = rq_ptr; 337 338 // Setup wire to read information from rename queue. 339 fromRename = renameQueue->getWire(-renameToIEWDelay); 340} 341 342template<class Impl> 343void 344DefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) 345{ 346 DPRINTF(IEW, "Setting IEW queue pointer.\n"); 347 iewQueue = iq_ptr; 348 349 // Setup wire to write instructions to commit. 350 toCommit = iewQueue->getWire(0); 351} 352 353template<class Impl> 354void 355DefaultIEW<Impl>::setActiveThreads(list<unsigned> *at_ptr) 356{ 357 DPRINTF(IEW, "Setting active threads list pointer.\n"); 358 activeThreads = at_ptr; 359 360 ldstQueue.setActiveThreads(at_ptr); 361 instQueue.setActiveThreads(at_ptr); 362} 363 364template<class Impl> 365void 366DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr) 367{ 368 DPRINTF(IEW, "Setting scoreboard pointer.\n"); 369 scoreboard = sb_ptr; 370} 371 372template <class Impl> 373void 374DefaultIEW<Impl>::switchOut() 375{ 376 // IEW is ready to switch out at any time. 377 cpu->signalSwitched(); 378} 379 380template <class Impl> 381void 382DefaultIEW<Impl>::doSwitchOut() 383{ 384 // Clear any state. 385 switchedOut = true; 386 387 instQueue.switchOut(); 388 ldstQueue.switchOut(); 389 fuPool->switchOut(); 390 391 for (int i = 0; i < numThreads; i++) { 392 while (!insts[i].empty()) 393 insts[i].pop(); 394 while (!skidBuffer[i].empty()) 395 skidBuffer[i].pop(); 396 } 397} 398 399template <class Impl> 400void 401DefaultIEW<Impl>::takeOverFrom() 402{ 403 // Reset all state. 404 _status = Active; 405 exeStatus = Running; 406 wbStatus = Idle; 407 switchedOut = false; 408 409 instQueue.takeOverFrom(); 410 ldstQueue.takeOverFrom(); 411 fuPool->takeOverFrom(); 412 413 initStage(); 414 cpu->activityThisCycle(); 415 416 for (int i=0; i < numThreads; i++) { 417 dispatchStatus[i] = Running; 418 stalls[i].commit = false; 419 fetchRedirect[i] = false; 420 } 421 422 updateLSQNextCycle = false; 423 424 // @todo: Fix hardcoded number 425 for (int i = 0; i < 6; ++i) { 426 issueToExecQueue.advance(); 427 } 428} 429 430template<class Impl> 431void 432DefaultIEW<Impl>::squash(unsigned tid) 433{ 434 DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n", 435 tid); 436 437 // Tell the IQ to start squashing. 438 instQueue.squash(tid); 439 440 // Tell the LDSTQ to start squashing. 441 ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid); 442 443 updatedQueues = true; 444 445 // Clear the skid buffer in case it has any data in it. 446 while (!skidBuffer[tid].empty()) { 447 448 if (skidBuffer[tid].front()->isLoad() || 449 skidBuffer[tid].front()->isStore() ) { 450 toRename->iewInfo[tid].dispatchedToLSQ++; 451 } 452 453 toRename->iewInfo[tid].dispatched++; 454 455 skidBuffer[tid].pop(); 456 } 457 458 emptyRenameInsts(tid); 459} 460 461template<class Impl> 462void 463DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid) 464{ 465 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x " 466 "[sn:%i].\n", tid, inst->readPC(), inst->seqNum); 467 468 toCommit->squash[tid] = true; 469 toCommit->squashedSeqNum[tid] = inst->seqNum; 470 toCommit->mispredPC[tid] = inst->readPC(); 471 toCommit->nextPC[tid] = inst->readNextPC(); 472 toCommit->branchMispredict[tid] = true; 473 toCommit->branchTaken[tid] = inst->readNextPC() != 474 (inst->readPC() + sizeof(TheISA::MachInst)); 475 476 toCommit->includeSquashInst[tid] = false; 477 478 wroteToTimeBuffer = true; 479} 480 481template<class Impl> 482void 483DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid) 484{ 485 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, " 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->readNextPC(); 491 492 toCommit->includeSquashInst[tid] = false; 493 494 wroteToTimeBuffer = true; 495} 496 497template<class Impl> 498void 499DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid) 500{ 501 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, " 502 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum); 503 504 toCommit->squash[tid] = true; 505 toCommit->squashedSeqNum[tid] = inst->seqNum; 506 toCommit->nextPC[tid] = inst->readPC(); 507 508 // Must include the broadcasted SN in the squash. 509 toCommit->includeSquashInst[tid] = true; 510 511 ldstQueue.setLoadBlockedHandled(tid); 512 513 wroteToTimeBuffer = true; 514} 515 516template<class Impl> 517void 518DefaultIEW<Impl>::block(unsigned tid) 519{ 520 DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid); 521 522 if (dispatchStatus[tid] != Blocked && 523 dispatchStatus[tid] != Unblocking) { 524 toRename->iewBlock[tid] = true; 525 wroteToTimeBuffer = true; 526 } 527 528 // Add the current inputs to the skid buffer so they can be 529 // reprocessed when this stage unblocks. 530 skidInsert(tid); 531 532 dispatchStatus[tid] = Blocked; 533} 534 535template<class Impl> 536void 537DefaultIEW<Impl>::unblock(unsigned tid) 538{ 539 DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid " 540 "buffer %u.\n",tid, tid); 541 542 // If the skid bufffer is empty, signal back to previous stages to unblock. 543 // Also switch status to running. 544 if (skidBuffer[tid].empty()) { 545 toRename->iewUnblock[tid] = true; 546 wroteToTimeBuffer = true; 547 DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid); 548 dispatchStatus[tid] = Running; 549 } 550} 551 552template<class Impl> 553void 554DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst) 555{ 556 instQueue.wakeDependents(inst); 557} 558 559template<class Impl> 560void 561DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst) 562{ 563 instQueue.rescheduleMemInst(inst); 564} 565 566template<class Impl> 567void 568DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst) 569{ 570 instQueue.replayMemInst(inst); 571} 572 573template<class Impl> 574void 575DefaultIEW<Impl>::instToCommit(DynInstPtr &inst) 576{ 577 // First check the time slot that this instruction will write 578 // to. If there are free write ports at the time, then go ahead 579 // and write the instruction to that time. If there are not, 580 // keep looking back to see where's the first time there's a 581 // free slot. 582 while ((*iewQueue)[wbCycle].insts[wbNumInst]) { 583 ++wbNumInst; 584 if (wbNumInst == issueWidth) { 585 ++wbCycle; 586 wbNumInst = 0; 587 } 588 589 assert(wbCycle < 5); 590 } 591 592 // Add finished instruction to queue to commit. 593 (*iewQueue)[wbCycle].insts[wbNumInst] = inst; 594 (*iewQueue)[wbCycle].size++; 595} 596 597template <class Impl> 598unsigned 599DefaultIEW<Impl>::validInstsFromRename() 600{ 601 unsigned inst_count = 0; 602 603 for (int i=0; i<fromRename->size; i++) { 604 if (!fromRename->insts[i]->squashed) 605 inst_count++; 606 } 607 608 return inst_count; 609} 610 611template<class Impl> 612void 613DefaultIEW<Impl>::skidInsert(unsigned tid) 614{ 615 DynInstPtr inst = NULL; 616 617 while (!insts[tid].empty()) { 618 inst = insts[tid].front(); 619 620 insts[tid].pop(); 621 622 DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into " 623 "dispatch skidBuffer %i\n",tid, inst->seqNum, 624 inst->readPC(),tid); 625 626 skidBuffer[tid].push(inst); 627 } 628 629 assert(skidBuffer[tid].size() <= skidBufferMax && 630 "Skidbuffer Exceeded Max Size"); 631} 632 633template<class Impl> 634int 635DefaultIEW<Impl>::skidCount() 636{ 637 int max=0; 638 639 list<unsigned>::iterator threads = (*activeThreads).begin(); 640 641 while (threads != (*activeThreads).end()) { 642 unsigned thread_count = skidBuffer[*threads++].size(); 643 if (max < thread_count) 644 max = thread_count; 645 } 646 647 return max; 648} 649 650template<class Impl> 651bool 652DefaultIEW<Impl>::skidsEmpty() 653{ 654 list<unsigned>::iterator threads = (*activeThreads).begin(); 655 656 while (threads != (*activeThreads).end()) { 657 if (!skidBuffer[*threads++].empty()) 658 return false; 659 } 660 661 return true; 662} 663 664template <class Impl> 665void 666DefaultIEW<Impl>::updateStatus() 667{ 668 bool any_unblocking = false; 669 670 list<unsigned>::iterator threads = (*activeThreads).begin(); 671 672 threads = (*activeThreads).begin(); 673 674 while (threads != (*activeThreads).end()) { 675 unsigned tid = *threads++; 676 677 if (dispatchStatus[tid] == Unblocking) { 678 any_unblocking = true; 679 break; 680 } 681 } 682 683 // If there are no ready instructions waiting to be scheduled by the IQ, 684 // and there's no stores waiting to write back, and dispatch is not 685 // unblocking, then there is no internal activity for the IEW stage. 686 if (_status == Active && !instQueue.hasReadyInsts() && 687 !ldstQueue.willWB() && !any_unblocking) { 688 DPRINTF(IEW, "IEW switching to idle\n"); 689 690 deactivateStage(); 691 692 _status = Inactive; 693 } else if (_status == Inactive && (instQueue.hasReadyInsts() || 694 ldstQueue.willWB() || 695 any_unblocking)) { 696 // Otherwise there is internal activity. Set to active. 697 DPRINTF(IEW, "IEW switching to active\n"); 698 699 activateStage(); 700 701 _status = Active; 702 } 703} 704 705template <class Impl> 706void 707DefaultIEW<Impl>::resetEntries() 708{ 709 instQueue.resetEntries(); 710 ldstQueue.resetEntries(); 711} 712 713template <class Impl> 714void 715DefaultIEW<Impl>::readStallSignals(unsigned tid) 716{ 717 if (fromCommit->commitBlock[tid]) { 718 stalls[tid].commit = true; 719 } 720 721 if (fromCommit->commitUnblock[tid]) { 722 assert(stalls[tid].commit); 723 stalls[tid].commit = false; 724 } 725} 726 727template <class Impl> 728bool 729DefaultIEW<Impl>::checkStall(unsigned tid) 730{ 731 bool ret_val(false); 732 733 if (stalls[tid].commit) { 734 DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid); 735 ret_val = true; 736 } else if (instQueue.isFull(tid)) { 737 DPRINTF(IEW,"[tid:%i]: Stall: IQ is full.\n",tid); 738 ret_val = true; 739 } else if (ldstQueue.isFull(tid)) { 740 DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid); 741 742 if (ldstQueue.numLoads(tid) > 0 ) { 743 744 DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n", 745 tid,ldstQueue.getLoadHeadSeqNum(tid)); 746 } 747 748 if (ldstQueue.numStores(tid) > 0) { 749 750 DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n", 751 tid,ldstQueue.getStoreHeadSeqNum(tid)); 752 } 753 754 ret_val = true; 755 } else if (ldstQueue.isStalled(tid)) { 756 DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid); 757 ret_val = true; 758 } 759 760 return ret_val; 761} 762 763template <class Impl> 764void 765DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid) 766{ 767 // Check if there's a squash signal, squash if there is 768 // Check stall signals, block if there is. 769 // If status was Blocked 770 // if so then go to unblocking 771 // If status was Squashing 772 // check if squashing is not high. Switch to running this cycle. 773 774 readStallSignals(tid); 775 776 if (fromCommit->commitInfo[tid].squash) { 777 squash(tid); 778 779 if (dispatchStatus[tid] == Blocked || 780 dispatchStatus[tid] == Unblocking) { 781 toRename->iewUnblock[tid] = true; 782 wroteToTimeBuffer = true; 783 } 784 785 dispatchStatus[tid] = Squashing; 786 787 fetchRedirect[tid] = false; 788 return; 789 } 790 791 if (fromCommit->commitInfo[tid].robSquashing) { 792 DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid); 793 794 dispatchStatus[tid] = Squashing; 795 796 emptyRenameInsts(tid); 797 wroteToTimeBuffer = true; 798 return; 799 } 800 801 if (checkStall(tid)) { 802 block(tid); 803 dispatchStatus[tid] = Blocked; 804 return; 805 } 806 807 if (dispatchStatus[tid] == Blocked) { 808 // Status from previous cycle was blocked, but there are no more stall 809 // conditions. Switch over to unblocking. 810 DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n", 811 tid); 812 813 dispatchStatus[tid] = Unblocking; 814 815 unblock(tid); 816 817 return; 818 } 819 820 if (dispatchStatus[tid] == Squashing) { 821 // Switch status to running if rename isn't being told to block or 822 // squash this cycle. 823 DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n", 824 tid); 825 826 dispatchStatus[tid] = Running; 827 828 return; 829 } 830} 831 832template <class Impl> 833void 834DefaultIEW<Impl>::sortInsts() 835{ 836 int insts_from_rename = fromRename->size; 837#ifdef DEBUG 838 for (int i = 0; i < numThreads; i++) 839 assert(insts[i].empty()); 840#endif 841 for (int i = 0; i < insts_from_rename; ++i) { 842 insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]); 843 } 844} 845 846template <class Impl> 847void 848DefaultIEW<Impl>::emptyRenameInsts(unsigned tid) 849{ 850 while (!insts[tid].empty()) { 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(FullCPU::IEWIdx); 883} 884 885template <class Impl> 886inline void 887DefaultIEW<Impl>::deactivateStage() 888{ 889 DPRINTF(Activity, "Deactivating stage.\n"); 890 cpu->deactivateStage(FullCPU::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 < issueReadWidth; 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#if FULL_SYSTEM 1072 } else if (inst->isMemBarrier() || inst->isWriteBarrier()) { 1073 // Same as non-speculative stores. 1074 inst->setCanCommit(); 1075 instQueue.insertBarrier(inst); 1076 add_to_iq = false; 1077#endif 1078 } else if (inst->isNonSpeculative()) { 1079 DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction " 1080 "encountered, skipping.\n", tid); 1081 1082 // Same as non-speculative stores. 1083 inst->setCanCommit(); 1084 1085 // Specifically insert it as nonspeculative. 1086 instQueue.insertNonSpec(inst); 1087 1088 ++iewDispNonSpecInsts; 1089 1090 add_to_iq = false; 1091 } else if (inst->isNop()) { 1092 DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, " 1093 "skipping.\n", tid); 1094 1095 inst->setIssued(); 1096 inst->setExecuted(); 1097 inst->setCanCommit(); 1098 1099 instQueue.recordProducer(inst); 1100 1101 exeNop[tid]++; 1102 1103 add_to_iq = false; 1104 } else if (inst->isExecuted()) { 1105 assert(0 && "Instruction shouldn't be executed.\n"); 1106 DPRINTF(IEW, "Issue: Executed branch encountered, " 1107 "skipping.\n"); 1108 1109 inst->setIssued(); 1110 inst->setCanCommit(); 1111 1112 instQueue.recordProducer(inst); 1113 1114 add_to_iq = false; 1115 } else { 1116 add_to_iq = true; 1117 } 1118 1119 // If the instruction queue is not full, then add the 1120 // instruction. 1121 if (add_to_iq) { 1122 instQueue.insert(inst); 1123 } 1124 1125 insts_to_dispatch.pop(); 1126 1127 toRename->iewInfo[tid].dispatched++; 1128 1129 ++iewDispatchedInsts; 1130 } 1131 1132 if (!insts_to_dispatch.empty()) { 1133 DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n"); 1134 block(tid); 1135 toRename->iewUnblock[tid] = false; 1136 } 1137 1138 if (dispatchStatus[tid] == Idle && dis_num_inst) { 1139 dispatchStatus[tid] = Running; 1140 1141 updatedQueues = true; 1142 } 1143 1144 dis_num_inst = 0; 1145} 1146 1147template <class Impl> 1148void 1149DefaultIEW<Impl>::printAvailableInsts() 1150{ 1151 int inst = 0; 1152 1153 cout << "Available Instructions: "; 1154 1155 while (fromIssue->insts[inst]) { 1156 1157 if (inst%3==0) cout << "\n\t"; 1158 1159 cout << "PC: " << fromIssue->insts[inst]->readPC() 1160 << " TN: " << fromIssue->insts[inst]->threadNumber 1161 << " SN: " << fromIssue->insts[inst]->seqNum << " | "; 1162 1163 inst++; 1164 1165 } 1166 1167 cout << "\n"; 1168} 1169 1170template <class Impl> 1171void 1172DefaultIEW<Impl>::executeInsts() 1173{ 1174 wbNumInst = 0; 1175 wbCycle = 0; 1176 1177 list<unsigned>::iterator threads = (*activeThreads).begin(); 1178 1179 while (threads != (*activeThreads).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 continue; 1215 } 1216 1217 Fault fault = NoFault; 1218 1219 // Execute instruction. 1220 // Note that if the instruction faults, it will be handled 1221 // at the commit stage. 1222 if (inst->isMemRef() && 1223 (!inst->isDataPrefetch() && !inst->isInstPrefetch())) { 1224 DPRINTF(IEW, "Execute: Calculating address for memory " 1225 "reference.\n"); 1226 1227 // Tell the LDSTQ to execute this instruction (if it is a load). 1228 if (inst->isLoad()) { 1229 // Loads will mark themselves as executed, and their writeback 1230 // event adds the instruction to the queue to commit 1231 fault = ldstQueue.executeLoad(inst); 1232 } else if (inst->isStore()) { 1233 ldstQueue.executeStore(inst); 1234 1235 // If the store had a fault then it may not have a mem req 1236 if (inst->req && !(inst->req->getFlags() & LOCKED)) { 1237 inst->setExecuted(); 1238 1239 instToCommit(inst); 1240 } 1241 1242 // Store conditionals will mark themselves as 1243 // executed, and their writeback event will add the 1244 // instruction to the queue to commit. 1245 } else { 1246 panic("Unexpected memory type!\n"); 1247 } 1248 1249 } else { 1250 inst->execute(); 1251 1252 inst->setExecuted(); 1253 1254 instToCommit(inst); 1255 } 1256 1257 updateExeInstStats(inst); 1258 1259 // Check if branch prediction was correct, if not then we need 1260 // to tell commit to squash in flight instructions. Only 1261 // handle this if there hasn't already been something that 1262 // redirects fetch in this group of instructions. 1263 1264 // This probably needs to prioritize the redirects if a different 1265 // scheduler is used. Currently the scheduler schedules the oldest 1266 // instruction first, so the branch resolution order will be correct. 1267 unsigned tid = inst->threadNumber; 1268 1269 if (!fetchRedirect[tid]) { 1270 1271 if (inst->mispredicted()) { 1272 fetchRedirect[tid] = true; 1273 1274 DPRINTF(IEW, "Execute: Branch mispredict detected.\n"); 1275 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n", 1276 inst->nextPC); 1277 1278 // If incorrect, then signal the ROB that it must be squashed. 1279 squashDueToBranch(inst, tid); 1280 1281 if (inst->predTaken()) { 1282 predictedTakenIncorrect++; 1283 } else { 1284 predictedNotTakenIncorrect++; 1285 } 1286 } else if (ldstQueue.violation(tid)) { 1287 fetchRedirect[tid] = true; 1288 1289 // If there was an ordering violation, then get the 1290 // DynInst that caused the violation. Note that this 1291 // clears the violation signal. 1292 DynInstPtr violator; 1293 violator = ldstQueue.getMemDepViolator(tid); 1294 1295 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: " 1296 "%#x, inst PC: %#x. Addr is: %#x.\n", 1297 violator->readPC(), inst->readPC(), inst->physEffAddr); 1298 1299 // Tell the instruction queue that a violation has occured. 1300 instQueue.violation(inst, violator); 1301 1302 // Squash. 1303 squashDueToMemOrder(inst,tid); 1304 1305 ++memOrderViolationEvents; 1306 } else if (ldstQueue.loadBlocked(tid) && 1307 !ldstQueue.isLoadBlockedHandled(tid)) { 1308 fetchRedirect[tid] = true; 1309 1310 DPRINTF(IEW, "Load operation couldn't execute because the " 1311 "memory system is blocked. PC: %#x [sn:%lli]\n", 1312 inst->readPC(), inst->seqNum); 1313 1314 squashDueToMemBlocked(inst, tid); 1315 } 1316 } 1317 } 1318 1319 // Update and record activity if we processed any instructions. 1320 if (inst_num) { 1321 if (exeStatus == Idle) { 1322 exeStatus = Running; 1323 } 1324 1325 updatedQueues = true; 1326 1327 cpu->activityThisCycle(); 1328 } 1329 1330 // Need to reset this in case a writeback event needs to write into the 1331 // iew queue. That way the writeback event will write into the correct 1332 // spot in the queue. 1333 wbNumInst = 0; 1334} 1335 1336template <class Impl> 1337void 1338DefaultIEW<Impl>::writebackInsts() 1339{ 1340 // Loop through the head of the time buffer and wake any 1341 // dependents. These instructions are about to write back. Also 1342 // mark scoreboard that this instruction is finally complete. 1343 // Either have IEW have direct access to scoreboard, or have this 1344 // as part of backwards communication. 1345 for (int inst_num = 0; inst_num < issueWidth && 1346 toCommit->insts[inst_num]; inst_num++) { 1347 DynInstPtr inst = toCommit->insts[inst_num]; 1348 int tid = inst->threadNumber; 1349 1350 DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %#x.\n", 1351 inst->seqNum, inst->readPC()); 1352 1353 iewInstsToCommit[tid]++; 1354 1355 // Some instructions will be sent to commit without having 1356 // executed because they need commit to handle them. 1357 // E.g. Uncached loads have not actually executed when they 1358 // are first sent to commit. Instead commit must tell the LSQ 1359 // when it's ready to execute the uncached load. 1360 if (!inst->isSquashed() && inst->isExecuted()) { 1361 int dependents = instQueue.wakeDependents(inst); 1362 1363 for (int i = 0; i < inst->numDestRegs(); i++) { 1364 //mark as Ready 1365 DPRINTF(IEW,"Setting Destination Register %i\n", 1366 inst->renamedDestRegIdx(i)); 1367 scoreboard->setReg(inst->renamedDestRegIdx(i)); 1368 } 1369 1370 if (dependents) { 1371 producerInst[tid]++; 1372 consumerInst[tid]+= dependents; 1373 } 1374 writebackCount[tid]++; 1375 } 1376 } 1377} 1378 1379template<class Impl> 1380void 1381DefaultIEW<Impl>::tick() 1382{ 1383 wbNumInst = 0; 1384 wbCycle = 0; 1385 1386 wroteToTimeBuffer = false; 1387 updatedQueues = false; 1388 1389 sortInsts(); 1390 1391 // Free function units marked as being freed this cycle. 1392 fuPool->processFreeUnits(); 1393 1394 list<unsigned>::iterator threads = (*activeThreads).begin(); 1395 1396 // Check stall and squash signals, dispatch any instructions. 1397 while (threads != (*activeThreads).end()) { 1398 unsigned tid = *threads++; 1399 1400 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid); 1401 1402 checkSignalsAndUpdate(tid); 1403 dispatch(tid); 1404 } 1405 1406 if (exeStatus != Squashing) { 1407 executeInsts(); 1408 1409 writebackInsts(); 1410 1411 // Have the instruction queue try to schedule any ready instructions. 1412 // (In actuality, this scheduling is for instructions that will 1413 // be executed next cycle.) 1414 instQueue.scheduleReadyInsts(); 1415 1416 // Also should advance its own time buffers if the stage ran. 1417 // Not the best place for it, but this works (hopefully). 1418 issueToExecQueue.advance(); 1419 } 1420 1421 bool broadcast_free_entries = false; 1422 1423 if (updatedQueues || exeStatus == Running || updateLSQNextCycle) { 1424 exeStatus = Idle; 1425 updateLSQNextCycle = false; 1426 1427 broadcast_free_entries = true; 1428 } 1429 1430 // Writeback any stores using any leftover bandwidth. 1431 ldstQueue.writebackStores(); 1432 1433 // Check the committed load/store signals to see if there's a load 1434 // or store to commit. Also check if it's being told to execute a 1435 // nonspeculative instruction. 1436 // This is pretty inefficient... 1437 1438 threads = (*activeThreads).begin(); 1439 while (threads != (*activeThreads).end()) { 1440 unsigned tid = (*threads++); 1441 1442 DPRINTF(IEW,"Processing [tid:%i]\n",tid); 1443 1444 // Update structures based on instructions committed. 1445 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 1446 !fromCommit->commitInfo[tid].squash && 1447 !fromCommit->commitInfo[tid].robSquashing) { 1448 1449 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid); 1450 1451 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid); 1452 1453 updateLSQNextCycle = true; 1454 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid); 1455 } 1456 1457 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) { 1458 1459 //DPRINTF(IEW,"NonspecInst from thread %i",tid); 1460 if (fromCommit->commitInfo[tid].uncached) { 1461 instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad); 1462 } else { 1463 instQueue.scheduleNonSpec( 1464 fromCommit->commitInfo[tid].nonSpecSeqNum); 1465 } 1466 } 1467 1468 if (broadcast_free_entries) { 1469 toFetch->iewInfo[tid].iqCount = 1470 instQueue.getCount(tid); 1471 toFetch->iewInfo[tid].ldstqCount = 1472 ldstQueue.getCount(tid); 1473 1474 toRename->iewInfo[tid].usedIQ = true; 1475 toRename->iewInfo[tid].freeIQEntries = 1476 instQueue.numFreeEntries(); 1477 toRename->iewInfo[tid].usedLSQ = true; 1478 toRename->iewInfo[tid].freeLSQEntries = 1479 ldstQueue.numFreeEntries(tid); 1480 1481 wroteToTimeBuffer = true; 1482 } 1483 1484 DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n", 1485 tid, toRename->iewInfo[tid].dispatched); 1486 } 1487 1488 DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). " 1489 "LSQ has %i free entries.\n", 1490 instQueue.numFreeEntries(), instQueue.hasReadyInsts(), 1491 ldstQueue.numFreeEntries()); 1492 1493 updateStatus(); 1494 1495 if (wroteToTimeBuffer) { 1496 DPRINTF(Activity, "Activity this cycle.\n"); 1497 cpu->activityThisCycle(); 1498 } 1499} 1500 1501template <class Impl> 1502void 1503DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst) 1504{ 1505 int thread_number = inst->threadNumber; 1506 1507 // 1508 // Pick off the software prefetches 1509 // 1510#ifdef TARGET_ALPHA 1511 if (inst->isDataPrefetch()) 1512 exeSwp[thread_number]++; 1513 else 1514 iewExecutedInsts++; 1515#else 1516 iewExecutedInsts++; 1517#endif 1518 1519 // 1520 // Control operations 1521 // 1522 if (inst->isControl()) 1523 exeBranches[thread_number]++; 1524 1525 // 1526 // Memory operations 1527 // 1528 if (inst->isMemRef()) { 1529 exeRefs[thread_number]++; 1530 1531 if (inst->isLoad()) { 1532 iewExecLoadInsts[thread_number]++; 1533 } 1534 } 1535} 1536