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