rename_impl.hh revision 2665
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 * Authors: Kevin Lim 29 */ 30 31#include <list> 32 33#include "config/full_system.hh" 34#include "cpu/o3/rename.hh" 35 36template <class Impl> 37SimpleRename<Impl>::SimpleRename(Params ¶ms) 38 : iewToRenameDelay(params.iewToRenameDelay), 39 decodeToRenameDelay(params.decodeToRenameDelay), 40 commitToRenameDelay(params.commitToRenameDelay), 41 renameWidth(params.renameWidth), 42 commitWidth(params.commitWidth), 43 numInst(0) 44{ 45 _status = Idle; 46} 47 48template <class Impl> 49void 50SimpleRename<Impl>::regStats() 51{ 52 renameSquashCycles 53 .name(name() + ".renameSquashCycles") 54 .desc("Number of cycles rename is squashing") 55 .prereq(renameSquashCycles); 56 renameIdleCycles 57 .name(name() + ".renameIdleCycles") 58 .desc("Number of cycles rename is idle") 59 .prereq(renameIdleCycles); 60 renameBlockCycles 61 .name(name() + ".renameBlockCycles") 62 .desc("Number of cycles rename is blocking") 63 .prereq(renameBlockCycles); 64 renameUnblockCycles 65 .name(name() + ".renameUnblockCycles") 66 .desc("Number of cycles rename is unblocking") 67 .prereq(renameUnblockCycles); 68 renameRenamedInsts 69 .name(name() + ".renameRenamedInsts") 70 .desc("Number of instructions processed by rename") 71 .prereq(renameRenamedInsts); 72 renameSquashedInsts 73 .name(name() + ".renameSquashedInsts") 74 .desc("Number of squashed instructions processed by rename") 75 .prereq(renameSquashedInsts); 76 renameROBFullEvents 77 .name(name() + ".renameROBFullEvents") 78 .desc("Number of times rename has considered the ROB 'full'") 79 .prereq(renameROBFullEvents); 80 renameIQFullEvents 81 .name(name() + ".renameIQFullEvents") 82 .desc("Number of times rename has considered the IQ 'full'") 83 .prereq(renameIQFullEvents); 84 renameFullRegistersEvents 85 .name(name() + ".renameFullRegisterEvents") 86 .desc("Number of times there has been no free registers") 87 .prereq(renameFullRegistersEvents); 88 renameRenamedOperands 89 .name(name() + ".renameRenamedOperands") 90 .desc("Number of destination operands rename has renamed") 91 .prereq(renameRenamedOperands); 92 renameRenameLookups 93 .name(name() + ".renameRenameLookups") 94 .desc("Number of register rename lookups that rename has made") 95 .prereq(renameRenameLookups); 96 renameHBPlaceHolders 97 .name(name() + ".renameHBPlaceHolders") 98 .desc("Number of place holders added to the history buffer") 99 .prereq(renameHBPlaceHolders); 100 renameCommittedMaps 101 .name(name() + ".renameCommittedMaps") 102 .desc("Number of HB maps that are committed") 103 .prereq(renameCommittedMaps); 104 renameUndoneMaps 105 .name(name() + ".renameUndoneMaps") 106 .desc("Number of HB maps that are undone due to squashing") 107 .prereq(renameUndoneMaps); 108 renameValidUndoneMaps 109 .name(name() + ".renameValidUndoneMaps") 110 .desc("Number of HB maps that are undone, and are not place holders") 111 .prereq(renameValidUndoneMaps); 112} 113 114template <class Impl> 115void 116SimpleRename<Impl>::setCPU(FullCPU *cpu_ptr) 117{ 118 DPRINTF(Rename, "Rename: Setting CPU pointer.\n"); 119 cpu = cpu_ptr; 120} 121 122template <class Impl> 123void 124SimpleRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 125{ 126 DPRINTF(Rename, "Rename: Setting time buffer pointer.\n"); 127 timeBuffer = tb_ptr; 128 129 // Setup wire to read information from time buffer, from IEW stage. 130 fromIEW = timeBuffer->getWire(-iewToRenameDelay); 131 132 // Setup wire to read infromation from time buffer, from commit stage. 133 fromCommit = timeBuffer->getWire(-commitToRenameDelay); 134 135 // Setup wire to write information to previous stages. 136 toDecode = timeBuffer->getWire(0); 137} 138 139template <class Impl> 140void 141SimpleRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 142{ 143 DPRINTF(Rename, "Rename: Setting rename queue pointer.\n"); 144 renameQueue = rq_ptr; 145 146 // Setup wire to write information to future stages. 147 toIEW = renameQueue->getWire(0); 148} 149 150template <class Impl> 151void 152SimpleRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) 153{ 154 DPRINTF(Rename, "Rename: Setting decode queue pointer.\n"); 155 decodeQueue = dq_ptr; 156 157 // Setup wire to get information from decode. 158 fromDecode = decodeQueue->getWire(-decodeToRenameDelay); 159} 160 161template <class Impl> 162void 163SimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr) 164{ 165 DPRINTF(Rename, "Rename: Setting rename map pointer.\n"); 166 renameMap = rm_ptr; 167} 168 169template <class Impl> 170void 171SimpleRename<Impl>::setFreeList(FreeList *fl_ptr) 172{ 173 DPRINTF(Rename, "Rename: Setting free list pointer.\n"); 174 freeList = fl_ptr; 175} 176 177template <class Impl> 178void 179SimpleRename<Impl>::dumpHistory() 180{ 181 typename list<RenameHistory>::iterator buf_it = historyBuffer.begin(); 182 183 while (buf_it != historyBuffer.end()) 184 { 185 cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys " 186 "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg, 187 (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg); 188 189 buf_it++; 190 } 191} 192 193template <class Impl> 194void 195SimpleRename<Impl>::block() 196{ 197 DPRINTF(Rename, "Rename: Blocking.\n"); 198 // Set status to Blocked. 199 _status = Blocked; 200 201 // Add the current inputs onto the skid buffer, so they can be 202 // reprocessed when this stage unblocks. 203 skidBuffer.push(*fromDecode); 204 205 // Note that this stage only signals previous stages to stall when 206 // it is the cause of the stall originates at this stage. Otherwise 207 // the previous stages are expected to check all possible stall signals. 208} 209 210template <class Impl> 211inline void 212SimpleRename<Impl>::unblock() 213{ 214 DPRINTF(Rename, "Rename: Read instructions out of skid buffer this " 215 "cycle.\n"); 216 // Remove the now processed instructions from the skid buffer. 217 skidBuffer.pop(); 218 219 // If there's still information in the skid buffer, then 220 // continue to tell previous stages to stall. They will be 221 // able to restart once the skid buffer is empty. 222 if (!skidBuffer.empty()) { 223 toDecode->renameInfo.stall = true; 224 } else { 225 DPRINTF(Rename, "Rename: Done unblocking.\n"); 226 _status = Running; 227 } 228} 229 230template <class Impl> 231void 232SimpleRename<Impl>::doSquash() 233{ 234 typename list<RenameHistory>::iterator hb_it = historyBuffer.begin(); 235 236 InstSeqNum squashed_seq_num = fromCommit->commitInfo.doneSeqNum; 237 238#if FULL_SYSTEM 239 assert(!historyBuffer.empty()); 240#else 241 // After a syscall squashes everything, the history buffer may be empty 242 // but the ROB may still be squashing instructions. 243 if (historyBuffer.empty()) { 244 return; 245 } 246#endif // FULL_SYSTEM 247 248 // Go through the most recent instructions, undoing the mappings 249 // they did and freeing up the registers. 250 while ((*hb_it).instSeqNum > squashed_seq_num) 251 { 252 assert(hb_it != historyBuffer.end()); 253 254 DPRINTF(Rename, "Rename: Removing history entry with sequence " 255 "number %i.\n", (*hb_it).instSeqNum); 256 257 // If it's not simply a place holder, then add the registers. 258 if (!(*hb_it).placeHolder) { 259 // Tell the rename map to set the architected register to the 260 // previous physical register that it was renamed to. 261 renameMap->setEntry(hb_it->archReg, hb_it->prevPhysReg); 262 263 // Put the renamed physical register back on the free list. 264 freeList->addReg(hb_it->newPhysReg); 265 266 ++renameValidUndoneMaps; 267 } 268 269 historyBuffer.erase(hb_it++); 270 271 ++renameUndoneMaps; 272 } 273} 274 275template <class Impl> 276void 277SimpleRename<Impl>::squash() 278{ 279 DPRINTF(Rename, "Rename: Squashing instructions.\n"); 280 // Set the status to Squashing. 281 _status = Squashing; 282 283 numInst = 0; 284 285 // Clear the skid buffer in case it has any data in it. 286 while (!skidBuffer.empty()) 287 { 288 skidBuffer.pop(); 289 } 290 291 doSquash(); 292} 293 294template<class Impl> 295void 296SimpleRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num) 297{ 298 DPRINTF(Rename, "Rename: Removing a committed instruction from the " 299 "history buffer, until sequence number %lli.\n", inst_seq_num); 300 typename list<RenameHistory>::iterator hb_it = historyBuffer.end(); 301 302 --hb_it; 303 304 if (hb_it->instSeqNum > inst_seq_num) { 305 DPRINTF(Rename, "Rename: Old sequence number encountered. Ensure " 306 "that a syscall happened recently.\n"); 307 return; 308 } 309 310 while ((*hb_it).instSeqNum != inst_seq_num) 311 { 312 // Make sure we haven't gone off the end of the list. 313 assert(hb_it != historyBuffer.end()); 314 315 // In theory instructions at the end of the history buffer 316 // should be older than the instruction being removed, which 317 // means they will have a lower sequence number. Also the 318 // instruction being removed from the history really should 319 // be the last instruction in the list, as it is the instruction 320 // that was just committed that is being removed. 321 assert(hb_it->instSeqNum < inst_seq_num); 322 DPRINTF(Rename, "Rename: Freeing up older rename of reg %i, sequence" 323 " number %i.\n", 324 (*hb_it).prevPhysReg, (*hb_it).instSeqNum); 325 326 if (!(*hb_it).placeHolder) { 327 freeList->addReg((*hb_it).prevPhysReg); 328 ++renameCommittedMaps; 329 } 330 331 historyBuffer.erase(hb_it--); 332 } 333 334 // Finally free up the previous register of the finished instruction 335 // itself. 336 if (!(*hb_it).placeHolder) { 337 freeList->addReg(hb_it->prevPhysReg); 338 ++renameCommittedMaps; 339 } 340 341 historyBuffer.erase(hb_it); 342} 343 344template <class Impl> 345inline void 346SimpleRename<Impl>::renameSrcRegs(DynInstPtr &inst) 347{ 348 unsigned num_src_regs = inst->numSrcRegs(); 349 350 // Get the architectual register numbers from the source and 351 // destination operands, and redirect them to the right register. 352 // Will need to mark dependencies though. 353 for (int src_idx = 0; src_idx < num_src_regs; src_idx++) 354 { 355 RegIndex src_reg = inst->srcRegIdx(src_idx); 356 357 // Look up the source registers to get the phys. register they've 358 // been renamed to, and set the sources to those registers. 359 PhysRegIndex renamed_reg = renameMap->lookup(src_reg); 360 361 DPRINTF(Rename, "Rename: Looking up arch reg %i, got " 362 "physical reg %i.\n", (int)src_reg, (int)renamed_reg); 363 364 inst->renameSrcReg(src_idx, renamed_reg); 365 366 // Either incorporate it into the info passed back, 367 // or make another function call to see if that register is 368 // ready or not. 369 if (renameMap->isReady(renamed_reg)) { 370 DPRINTF(Rename, "Rename: Register is ready.\n"); 371 372 inst->markSrcRegReady(src_idx); 373 } 374 375 ++renameRenameLookups; 376 } 377} 378 379template <class Impl> 380inline void 381SimpleRename<Impl>::renameDestRegs(DynInstPtr &inst) 382{ 383 typename SimpleRenameMap::RenameInfo rename_result; 384 385 unsigned num_dest_regs = inst->numDestRegs(); 386 387 // If it's an instruction with no destination registers, then put 388 // a placeholder within the history buffer. It might be better 389 // to not put it in the history buffer at all (other than branches, 390 // which always need at least a place holder), and differentiate 391 // between instructions with and without destination registers 392 // when getting from commit the instructions that committed. 393 if (num_dest_regs == 0) { 394 RenameHistory hb_entry(inst->seqNum); 395 396 historyBuffer.push_front(hb_entry); 397 398 DPRINTF(Rename, "Rename: Adding placeholder instruction to " 399 "history buffer, sequence number %lli.\n", 400 inst->seqNum); 401 402 ++renameHBPlaceHolders; 403 } else { 404 405 // Rename the destination registers. 406 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) 407 { 408 RegIndex dest_reg = inst->destRegIdx(dest_idx); 409 410 // Get the physical register that the destination will be 411 // renamed to. 412 rename_result = renameMap->rename(dest_reg); 413 414 DPRINTF(Rename, "Rename: Renaming arch reg %i to physical " 415 "reg %i.\n", (int)dest_reg, 416 (int)rename_result.first); 417 418 // Record the rename information so that a history can be kept. 419 RenameHistory hb_entry(inst->seqNum, dest_reg, 420 rename_result.first, 421 rename_result.second); 422 423 historyBuffer.push_front(hb_entry); 424 425 DPRINTF(Rename, "Rename: Adding instruction to history buffer, " 426 "sequence number %lli.\n", 427 (*historyBuffer.begin()).instSeqNum); 428 429 // Tell the instruction to rename the appropriate destination 430 // register (dest_idx) to the new physical register 431 // (rename_result.first), and record the previous physical 432 // register that the same logical register was renamed to 433 // (rename_result.second). 434 inst->renameDestReg(dest_idx, 435 rename_result.first, 436 rename_result.second); 437 438 ++renameRenamedOperands; 439 } 440 } 441} 442 443template <class Impl> 444inline int 445SimpleRename<Impl>::calcFreeROBEntries() 446{ 447 return fromCommit->commitInfo.freeROBEntries - 448 renameWidth * iewToRenameDelay; 449} 450 451template <class Impl> 452inline int 453SimpleRename<Impl>::calcFreeIQEntries() 454{ 455 return fromIEW->iewInfo.freeIQEntries - renameWidth * iewToRenameDelay; 456} 457 458template<class Impl> 459void 460SimpleRename<Impl>::tick() 461{ 462 // Rename will need to try to rename as many instructions as it 463 // has bandwidth, unless it is blocked. 464 465 // Check if _status is BarrierStall. If so, then check if the number 466 // of free ROB entries is equal to the number of total ROB entries. 467 // Once equal then wake this stage up. Set status to unblocking maybe. 468 469 if (_status != Blocked && _status != Squashing) { 470 DPRINTF(Rename, "Rename: Status is not blocked, will attempt to " 471 "run stage.\n"); 472 // Make sure that the skid buffer has something in it if the 473 // status is unblocking. 474 assert(_status == Unblocking ? !skidBuffer.empty() : 1); 475 476 rename(); 477 478 // If the status was unblocking, then instructions from the skid 479 // buffer were used. Remove those instructions and handle 480 // the rest of unblocking. 481 if (_status == Unblocking) { 482 ++renameUnblockCycles; 483 484 if (fromDecode->size > 0) { 485 // Add the current inputs onto the skid buffer, so they can be 486 // reprocessed when this stage unblocks. 487 skidBuffer.push(*fromDecode); 488 } 489 490 unblock(); 491 } 492 } else if (_status == Blocked) { 493 ++renameBlockCycles; 494 495 // If stage is blocked and still receiving valid instructions, 496 // make sure to store them in the skid buffer. 497 if (fromDecode->size > 0) { 498 499 block(); 500 501 // Continue to tell previous stage to stall. 502 toDecode->renameInfo.stall = true; 503 } 504 505 if (!fromIEW->iewInfo.stall && 506 !fromCommit->commitInfo.stall && 507 calcFreeROBEntries() > 0 && 508 calcFreeIQEntries() > 0 && 509 renameMap->numFreeEntries() > 0) { 510 511 // Need to be sure to check all blocking conditions above. 512 // If they have cleared, then start unblocking. 513 DPRINTF(Rename, "Rename: Stall signals cleared, going to " 514 "unblock.\n"); 515 _status = Unblocking; 516 517 // Continue to tell previous stage to block until this stage 518 // is done unblocking. 519 toDecode->renameInfo.stall = true; 520 } else { 521 // Otherwise no conditions have changed. Tell previous 522 // stage to continue blocking. 523 toDecode->renameInfo.stall = true; 524 } 525 526 if (fromCommit->commitInfo.squash || 527 fromCommit->commitInfo.robSquashing) { 528 squash(); 529 return; 530 } 531 } else if (_status == Squashing) { 532 ++renameSquashCycles; 533 534 if (fromCommit->commitInfo.squash) { 535 squash(); 536 } else if (!fromCommit->commitInfo.squash && 537 !fromCommit->commitInfo.robSquashing) { 538 539 DPRINTF(Rename, "Rename: Done squashing, going to running.\n"); 540 _status = Running; 541 rename(); 542 } else { 543 doSquash(); 544 } 545 } 546 547 // Ugly code, revamp all of the tick() functions eventually. 548 if (fromCommit->commitInfo.doneSeqNum != 0 && _status != Squashing) { 549#if !FULL_SYSTEM 550 if (!fromCommit->commitInfo.squash) { 551 removeFromHistory(fromCommit->commitInfo.doneSeqNum); 552 } 553#else 554 removeFromHistory(fromCommit->commitInfo.doneSeqNum); 555#endif 556 } 557 558} 559 560template<class Impl> 561void 562SimpleRename<Impl>::rename() 563{ 564 // Check if any of the stages ahead of rename are telling rename 565 // to squash. The squash() function will also take care of fixing up 566 // the rename map and the free list. 567 if (fromCommit->commitInfo.squash || 568 fromCommit->commitInfo.robSquashing) { 569 DPRINTF(Rename, "Rename: Receiving signal from Commit to squash.\n"); 570 squash(); 571 return; 572 } 573 574 // Check if time buffer is telling this stage to stall. 575 if (fromIEW->iewInfo.stall || 576 fromCommit->commitInfo.stall) { 577 DPRINTF(Rename, "Rename: Receiving signal from IEW/Commit to " 578 "stall.\n"); 579 block(); 580 return; 581 } 582 583 // Check if the current status is squashing. If so, set its status 584 // to running and resume execution the next cycle. 585 if (_status == Squashing) { 586 DPRINTF(Rename, "Rename: Done squashing.\n"); 587 _status = Running; 588 return; 589 } 590 591 // Check the decode queue to see if instructions are available. 592 // If there are no available instructions to rename, then do nothing. 593 // Or, if the stage is currently unblocking, then go ahead and run it. 594 if (fromDecode->size == 0 && _status != Unblocking) { 595 DPRINTF(Rename, "Rename: Nothing to do, breaking out early.\n"); 596 // Should I change status to idle? 597 return; 598 } 599 600 //////////////////////////////////// 601 // Actual rename part. 602 //////////////////////////////////// 603 604 DynInstPtr inst; 605 606 // If we're unblocking, then we may be in the middle of an instruction 607 // group. Subtract off numInst to get the proper number of instructions 608 // left. 609 int insts_available = _status == Unblocking ? 610 skidBuffer.front().size - numInst : 611 fromDecode->size; 612 613 bool block_this_cycle = false; 614 615 // Will have to do a different calculation for the number of free 616 // entries. Number of free entries recorded on this cycle - 617 // renameWidth * renameToDecodeDelay 618 int free_rob_entries = calcFreeROBEntries(); 619 int free_iq_entries = calcFreeIQEntries(); 620 int min_iq_rob = min(free_rob_entries, free_iq_entries); 621 622 unsigned to_iew_index = 0; 623 624 // Check if there's any space left. 625 if (min_iq_rob <= 0) { 626 DPRINTF(Rename, "Rename: Blocking due to no free ROB or IQ " 627 "entries.\n" 628 "Rename: ROB has %d free entries.\n" 629 "Rename: IQ has %d free entries.\n", 630 free_rob_entries, 631 free_iq_entries); 632 block(); 633 // Tell previous stage to stall. 634 toDecode->renameInfo.stall = true; 635 636 if (free_rob_entries <= 0) { 637 ++renameROBFullEvents; 638 } else { 639 ++renameIQFullEvents; 640 } 641 642 return; 643 } else if (min_iq_rob < insts_available) { 644 DPRINTF(Rename, "Rename: Will have to block this cycle. Only " 645 "%i insts can be renamed due to IQ/ROB limits.\n", 646 min_iq_rob); 647 648 insts_available = min_iq_rob; 649 650 block_this_cycle = true; 651 652 if (free_rob_entries < free_iq_entries) { 653 ++renameROBFullEvents; 654 } else { 655 ++renameIQFullEvents; 656 } 657 } 658 659 while (insts_available > 0) { 660 DPRINTF(Rename, "Rename: Sending instructions to iew.\n"); 661 662 // Get the next instruction either from the skid buffer or the 663 // decode queue. 664 inst = _status == Unblocking ? skidBuffer.front().insts[numInst] : 665 fromDecode->insts[numInst]; 666 667 if (inst->isSquashed()) { 668 DPRINTF(Rename, "Rename: instruction %i with PC %#x is " 669 "squashed, skipping.\n", 670 inst->seqNum, inst->readPC()); 671 672 // Go to the next instruction. 673 ++numInst; 674 675 ++renameSquashedInsts; 676 677 // Decrement how many instructions are available. 678 --insts_available; 679 680 continue; 681 } 682 683 DPRINTF(Rename, "Rename: Processing instruction %i with PC %#x.\n", 684 inst->seqNum, inst->readPC()); 685 686 // If it's a trap instruction, then it needs to wait here within 687 // rename until the ROB is empty. Needs a way to detect that the 688 // ROB is empty. Maybe an event? 689 // Would be nice if it could be avoided putting this into a 690 // specific stage and instead just put it into the AlphaFullCPU. 691 // Might not really be feasible though... 692 // (EXCB, TRAPB) 693 if (inst->isSerializing()) { 694 panic("Rename: Serializing instruction encountered.\n"); 695 DPRINTF(Rename, "Rename: Serializing instruction " 696 "encountered.\n"); 697 698 // Change status over to BarrierStall so that other stages know 699 // what this is blocked on. 700 _status = BarrierStall; 701 702 block_this_cycle = true; 703 704 break; 705 } 706 707 // Check here to make sure there are enough destination registers 708 // to rename to. Otherwise block. 709 if (renameMap->numFreeEntries() < inst->numDestRegs()) 710 { 711 DPRINTF(Rename, "Rename: Blocking due to lack of free " 712 "physical registers to rename to.\n"); 713 // Need some sort of event based on a register being freed. 714 715 block_this_cycle = true; 716 717 ++renameFullRegistersEvents; 718 719 break; 720 } 721 722 renameSrcRegs(inst); 723 724 renameDestRegs(inst); 725 726 // Put instruction in rename queue. 727 toIEW->insts[to_iew_index] = inst; 728 ++(toIEW->size); 729 730 // Decrease the number of free ROB and IQ entries. 731 --free_rob_entries; 732 --free_iq_entries; 733 734 // Increment which instruction we're on. 735 ++to_iew_index; 736 ++numInst; 737 738 ++renameRenamedInsts; 739 740 // Decrement how many instructions are available. 741 --insts_available; 742 } 743 744 // Check if there's any instructions left that haven't yet been renamed. 745 // If so then block. 746 if (block_this_cycle) { 747 block(); 748 749 toDecode->renameInfo.stall = true; 750 } else { 751 // If we had a successful rename and didn't have to exit early, then 752 // reset numInst so it will refer to the correct instruction on next 753 // run. 754 numInst = 0; 755 } 756} 757