rename_impl.hh revision 10935
1/* 2 * Copyright (c) 2010-2012, 2014-2015 ARM Limited 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license 11 * terms below provided that you ensure that this notice is replicated 12 * unmodified and in its entirety in all distributions of the software, 13 * modified or unmodified, in source code or in binary form. 14 * 15 * Copyright (c) 2004-2006 The Regents of The University of Michigan 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; 22 * redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution; 25 * neither the name of the copyright holders nor the names of its 26 * contributors may be used to endorse or promote products derived from 27 * this software without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Authors: Kevin Lim 42 * Korey Sewell 43 */ 44 45#ifndef __CPU_O3_RENAME_IMPL_HH__ 46#define __CPU_O3_RENAME_IMPL_HH__ 47 48#include <list> 49 50#include "arch/isa_traits.hh" 51#include "arch/registers.hh" 52#include "config/the_isa.hh" 53#include "cpu/o3/rename.hh" 54#include "cpu/reg_class.hh" 55#include "debug/Activity.hh" 56#include "debug/Rename.hh" 57#include "debug/O3PipeView.hh" 58#include "params/DerivO3CPU.hh" 59 60using namespace std; 61 62template <class Impl> 63DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, DerivO3CPUParams *params) 64 : cpu(_cpu), 65 iewToRenameDelay(params->iewToRenameDelay), 66 decodeToRenameDelay(params->decodeToRenameDelay), 67 commitToRenameDelay(params->commitToRenameDelay), 68 renameWidth(params->renameWidth), 69 commitWidth(params->commitWidth), 70 numThreads(params->numThreads), 71 maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs 72 + params->numPhysCCRegs) 73{ 74 if (renameWidth > Impl::MaxWidth) 75 fatal("renameWidth (%d) is larger than compiled limit (%d),\n" 76 "\tincrease MaxWidth in src/cpu/o3/impl.hh\n", 77 renameWidth, static_cast<int>(Impl::MaxWidth)); 78 79 // @todo: Make into a parameter. 80 skidBufferMax = (decodeToRenameDelay + 1) * params->decodeWidth; 81} 82 83template <class Impl> 84std::string 85DefaultRename<Impl>::name() const 86{ 87 return cpu->name() + ".rename"; 88} 89 90template <class Impl> 91void 92DefaultRename<Impl>::regStats() 93{ 94 renameSquashCycles 95 .name(name() + ".SquashCycles") 96 .desc("Number of cycles rename is squashing") 97 .prereq(renameSquashCycles); 98 renameIdleCycles 99 .name(name() + ".IdleCycles") 100 .desc("Number of cycles rename is idle") 101 .prereq(renameIdleCycles); 102 renameBlockCycles 103 .name(name() + ".BlockCycles") 104 .desc("Number of cycles rename is blocking") 105 .prereq(renameBlockCycles); 106 renameSerializeStallCycles 107 .name(name() + ".serializeStallCycles") 108 .desc("count of cycles rename stalled for serializing inst") 109 .flags(Stats::total); 110 renameRunCycles 111 .name(name() + ".RunCycles") 112 .desc("Number of cycles rename is running") 113 .prereq(renameIdleCycles); 114 renameUnblockCycles 115 .name(name() + ".UnblockCycles") 116 .desc("Number of cycles rename is unblocking") 117 .prereq(renameUnblockCycles); 118 renameRenamedInsts 119 .name(name() + ".RenamedInsts") 120 .desc("Number of instructions processed by rename") 121 .prereq(renameRenamedInsts); 122 renameSquashedInsts 123 .name(name() + ".SquashedInsts") 124 .desc("Number of squashed instructions processed by rename") 125 .prereq(renameSquashedInsts); 126 renameROBFullEvents 127 .name(name() + ".ROBFullEvents") 128 .desc("Number of times rename has blocked due to ROB full") 129 .prereq(renameROBFullEvents); 130 renameIQFullEvents 131 .name(name() + ".IQFullEvents") 132 .desc("Number of times rename has blocked due to IQ full") 133 .prereq(renameIQFullEvents); 134 renameLQFullEvents 135 .name(name() + ".LQFullEvents") 136 .desc("Number of times rename has blocked due to LQ full") 137 .prereq(renameLQFullEvents); 138 renameSQFullEvents 139 .name(name() + ".SQFullEvents") 140 .desc("Number of times rename has blocked due to SQ full") 141 .prereq(renameSQFullEvents); 142 renameFullRegistersEvents 143 .name(name() + ".FullRegisterEvents") 144 .desc("Number of times there has been no free registers") 145 .prereq(renameFullRegistersEvents); 146 renameRenamedOperands 147 .name(name() + ".RenamedOperands") 148 .desc("Number of destination operands rename has renamed") 149 .prereq(renameRenamedOperands); 150 renameRenameLookups 151 .name(name() + ".RenameLookups") 152 .desc("Number of register rename lookups that rename has made") 153 .prereq(renameRenameLookups); 154 renameCommittedMaps 155 .name(name() + ".CommittedMaps") 156 .desc("Number of HB maps that are committed") 157 .prereq(renameCommittedMaps); 158 renameUndoneMaps 159 .name(name() + ".UndoneMaps") 160 .desc("Number of HB maps that are undone due to squashing") 161 .prereq(renameUndoneMaps); 162 renamedSerializing 163 .name(name() + ".serializingInsts") 164 .desc("count of serializing insts renamed") 165 .flags(Stats::total) 166 ; 167 renamedTempSerializing 168 .name(name() + ".tempSerializingInsts") 169 .desc("count of temporary serializing insts renamed") 170 .flags(Stats::total) 171 ; 172 renameSkidInsts 173 .name(name() + ".skidInsts") 174 .desc("count of insts added to the skid buffer") 175 .flags(Stats::total) 176 ; 177 intRenameLookups 178 .name(name() + ".int_rename_lookups") 179 .desc("Number of integer rename lookups") 180 .prereq(intRenameLookups); 181 fpRenameLookups 182 .name(name() + ".fp_rename_lookups") 183 .desc("Number of floating rename lookups") 184 .prereq(fpRenameLookups); 185} 186 187template <class Impl> 188void 189DefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 190{ 191 timeBuffer = tb_ptr; 192 193 // Setup wire to read information from time buffer, from IEW stage. 194 fromIEW = timeBuffer->getWire(-iewToRenameDelay); 195 196 // Setup wire to read infromation from time buffer, from commit stage. 197 fromCommit = timeBuffer->getWire(-commitToRenameDelay); 198 199 // Setup wire to write information to previous stages. 200 toDecode = timeBuffer->getWire(0); 201} 202 203template <class Impl> 204void 205DefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 206{ 207 renameQueue = rq_ptr; 208 209 // Setup wire to write information to future stages. 210 toIEW = renameQueue->getWire(0); 211} 212 213template <class Impl> 214void 215DefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr) 216{ 217 decodeQueue = dq_ptr; 218 219 // Setup wire to get information from decode. 220 fromDecode = decodeQueue->getWire(-decodeToRenameDelay); 221} 222 223template <class Impl> 224void 225DefaultRename<Impl>::startupStage() 226{ 227 resetStage(); 228} 229 230template <class Impl> 231void 232DefaultRename<Impl>::resetStage() 233{ 234 _status = Inactive; 235 236 resumeSerialize = false; 237 resumeUnblocking = false; 238 239 // Grab the number of free entries directly from the stages. 240 for (ThreadID tid = 0; tid < numThreads; tid++) { 241 renameStatus[tid] = Idle; 242 243 freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid); 244 freeEntries[tid].lqEntries = iew_ptr->ldstQueue.numFreeLoadEntries(tid); 245 freeEntries[tid].sqEntries = iew_ptr->ldstQueue.numFreeStoreEntries(tid); 246 freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid); 247 emptyROB[tid] = true; 248 249 stalls[tid].iew = false; 250 serializeInst[tid] = NULL; 251 252 instsInProgress[tid] = 0; 253 loadsInProgress[tid] = 0; 254 storesInProgress[tid] = 0; 255 256 serializeOnNextInst[tid] = false; 257 } 258} 259 260template<class Impl> 261void 262DefaultRename<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 263{ 264 activeThreads = at_ptr; 265} 266 267 268template <class Impl> 269void 270DefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[]) 271{ 272 for (ThreadID tid = 0; tid < numThreads; tid++) 273 renameMap[tid] = &rm_ptr[tid]; 274} 275 276template <class Impl> 277void 278DefaultRename<Impl>::setFreeList(FreeList *fl_ptr) 279{ 280 freeList = fl_ptr; 281} 282 283template<class Impl> 284void 285DefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard) 286{ 287 scoreboard = _scoreboard; 288} 289 290template <class Impl> 291bool 292DefaultRename<Impl>::isDrained() const 293{ 294 for (ThreadID tid = 0; tid < numThreads; tid++) { 295 if (instsInProgress[tid] != 0 || 296 !historyBuffer[tid].empty() || 297 !skidBuffer[tid].empty() || 298 !insts[tid].empty()) 299 return false; 300 } 301 return true; 302} 303 304template <class Impl> 305void 306DefaultRename<Impl>::takeOverFrom() 307{ 308 resetStage(); 309} 310 311template <class Impl> 312void 313DefaultRename<Impl>::drainSanityCheck() const 314{ 315 for (ThreadID tid = 0; tid < numThreads; tid++) { 316 assert(historyBuffer[tid].empty()); 317 assert(insts[tid].empty()); 318 assert(skidBuffer[tid].empty()); 319 assert(instsInProgress[tid] == 0); 320 } 321} 322 323template <class Impl> 324void 325DefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, ThreadID tid) 326{ 327 DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid); 328 329 // Clear the stall signal if rename was blocked or unblocking before. 330 // If it still needs to block, the blocking should happen the next 331 // cycle and there should be space to hold everything due to the squash. 332 if (renameStatus[tid] == Blocked || 333 renameStatus[tid] == Unblocking) { 334 toDecode->renameUnblock[tid] = 1; 335 336 resumeSerialize = false; 337 serializeInst[tid] = NULL; 338 } else if (renameStatus[tid] == SerializeStall) { 339 if (serializeInst[tid]->seqNum <= squash_seq_num) { 340 DPRINTF(Rename, "Rename will resume serializing after squash\n"); 341 resumeSerialize = true; 342 assert(serializeInst[tid]); 343 } else { 344 resumeSerialize = false; 345 toDecode->renameUnblock[tid] = 1; 346 347 serializeInst[tid] = NULL; 348 } 349 } 350 351 // Set the status to Squashing. 352 renameStatus[tid] = Squashing; 353 354 // Squash any instructions from decode. 355 for (int i=0; i<fromDecode->size; i++) { 356 if (fromDecode->insts[i]->threadNumber == tid && 357 fromDecode->insts[i]->seqNum > squash_seq_num) { 358 fromDecode->insts[i]->setSquashed(); 359 wroteToTimeBuffer = true; 360 } 361 362 } 363 364 // Clear the instruction list and skid buffer in case they have any 365 // insts in them. 366 insts[tid].clear(); 367 368 // Clear the skid buffer in case it has any data in it. 369 skidBuffer[tid].clear(); 370 371 doSquash(squash_seq_num, tid); 372} 373 374template <class Impl> 375void 376DefaultRename<Impl>::tick() 377{ 378 wroteToTimeBuffer = false; 379 380 blockThisCycle = false; 381 382 bool status_change = false; 383 384 toIEWIndex = 0; 385 386 sortInsts(); 387 388 list<ThreadID>::iterator threads = activeThreads->begin(); 389 list<ThreadID>::iterator end = activeThreads->end(); 390 391 // Check stall and squash signals. 392 while (threads != end) { 393 ThreadID tid = *threads++; 394 395 DPRINTF(Rename, "Processing [tid:%i]\n", tid); 396 397 status_change = checkSignalsAndUpdate(tid) || status_change; 398 399 rename(status_change, tid); 400 } 401 402 if (status_change) { 403 updateStatus(); 404 } 405 406 if (wroteToTimeBuffer) { 407 DPRINTF(Activity, "Activity this cycle.\n"); 408 cpu->activityThisCycle(); 409 } 410 411 threads = activeThreads->begin(); 412 413 while (threads != end) { 414 ThreadID tid = *threads++; 415 416 // If we committed this cycle then doneSeqNum will be > 0 417 if (fromCommit->commitInfo[tid].doneSeqNum != 0 && 418 !fromCommit->commitInfo[tid].squash && 419 renameStatus[tid] != Squashing) { 420 421 removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum, 422 tid); 423 } 424 } 425 426 // @todo: make into updateProgress function 427 for (ThreadID tid = 0; tid < numThreads; tid++) { 428 instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched; 429 loadsInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToLQ; 430 storesInProgress[tid] -= fromIEW->iewInfo[tid].dispatchedToSQ; 431 assert(loadsInProgress[tid] >= 0); 432 assert(storesInProgress[tid] >= 0); 433 assert(instsInProgress[tid] >=0); 434 } 435 436} 437 438template<class Impl> 439void 440DefaultRename<Impl>::rename(bool &status_change, ThreadID tid) 441{ 442 // If status is Running or idle, 443 // call renameInsts() 444 // If status is Unblocking, 445 // buffer any instructions coming from decode 446 // continue trying to empty skid buffer 447 // check if stall conditions have passed 448 449 if (renameStatus[tid] == Blocked) { 450 ++renameBlockCycles; 451 } else if (renameStatus[tid] == Squashing) { 452 ++renameSquashCycles; 453 } else if (renameStatus[tid] == SerializeStall) { 454 ++renameSerializeStallCycles; 455 // If we are currently in SerializeStall and resumeSerialize 456 // was set, then that means that we are resuming serializing 457 // this cycle. Tell the previous stages to block. 458 if (resumeSerialize) { 459 resumeSerialize = false; 460 block(tid); 461 toDecode->renameUnblock[tid] = false; 462 } 463 } else if (renameStatus[tid] == Unblocking) { 464 if (resumeUnblocking) { 465 block(tid); 466 resumeUnblocking = false; 467 toDecode->renameUnblock[tid] = false; 468 } 469 } 470 471 if (renameStatus[tid] == Running || 472 renameStatus[tid] == Idle) { 473 DPRINTF(Rename, "[tid:%u]: Not blocked, so attempting to run " 474 "stage.\n", tid); 475 476 renameInsts(tid); 477 } else if (renameStatus[tid] == Unblocking) { 478 renameInsts(tid); 479 480 if (validInsts()) { 481 // Add the current inputs to the skid buffer so they can be 482 // reprocessed when this stage unblocks. 483 skidInsert(tid); 484 } 485 486 // If we switched over to blocking, then there's a potential for 487 // an overall status change. 488 status_change = unblock(tid) || status_change || blockThisCycle; 489 } 490} 491 492template <class Impl> 493void 494DefaultRename<Impl>::renameInsts(ThreadID tid) 495{ 496 // Instructions can be either in the skid buffer or the queue of 497 // instructions coming from decode, depending on the status. 498 int insts_available = renameStatus[tid] == Unblocking ? 499 skidBuffer[tid].size() : insts[tid].size(); 500 501 // Check the decode queue to see if instructions are available. 502 // If there are no available instructions to rename, then do nothing. 503 if (insts_available == 0) { 504 DPRINTF(Rename, "[tid:%u]: Nothing to do, breaking out early.\n", 505 tid); 506 // Should I change status to idle? 507 ++renameIdleCycles; 508 return; 509 } else if (renameStatus[tid] == Unblocking) { 510 ++renameUnblockCycles; 511 } else if (renameStatus[tid] == Running) { 512 ++renameRunCycles; 513 } 514 515 DynInstPtr inst; 516 517 // Will have to do a different calculation for the number of free 518 // entries. 519 int free_rob_entries = calcFreeROBEntries(tid); 520 int free_iq_entries = calcFreeIQEntries(tid); 521 int min_free_entries = free_rob_entries; 522 523 FullSource source = ROB; 524 525 if (free_iq_entries < min_free_entries) { 526 min_free_entries = free_iq_entries; 527 source = IQ; 528 } 529 530 // Check if there's any space left. 531 if (min_free_entries <= 0) { 532 DPRINTF(Rename, "[tid:%u]: Blocking due to no free ROB/IQ/ " 533 "entries.\n" 534 "ROB has %i free entries.\n" 535 "IQ has %i free entries.\n", 536 tid, 537 free_rob_entries, 538 free_iq_entries); 539 540 blockThisCycle = true; 541 542 block(tid); 543 544 incrFullStat(source); 545 546 return; 547 } else if (min_free_entries < insts_available) { 548 DPRINTF(Rename, "[tid:%u]: Will have to block this cycle." 549 "%i insts available, but only %i insts can be " 550 "renamed due to ROB/IQ/LSQ limits.\n", 551 tid, insts_available, min_free_entries); 552 553 insts_available = min_free_entries; 554 555 blockThisCycle = true; 556 557 incrFullStat(source); 558 } 559 560 InstQueue &insts_to_rename = renameStatus[tid] == Unblocking ? 561 skidBuffer[tid] : insts[tid]; 562 563 DPRINTF(Rename, "[tid:%u]: %i available instructions to " 564 "send iew.\n", tid, insts_available); 565 566 DPRINTF(Rename, "[tid:%u]: %i insts pipelining from Rename | %i insts " 567 "dispatched to IQ last cycle.\n", 568 tid, instsInProgress[tid], fromIEW->iewInfo[tid].dispatched); 569 570 // Handle serializing the next instruction if necessary. 571 if (serializeOnNextInst[tid]) { 572 if (emptyROB[tid] && instsInProgress[tid] == 0) { 573 // ROB already empty; no need to serialize. 574 serializeOnNextInst[tid] = false; 575 } else if (!insts_to_rename.empty()) { 576 insts_to_rename.front()->setSerializeBefore(); 577 } 578 } 579 580 int renamed_insts = 0; 581 582 while (insts_available > 0 && toIEWIndex < renameWidth) { 583 DPRINTF(Rename, "[tid:%u]: Sending instructions to IEW.\n", tid); 584 585 assert(!insts_to_rename.empty()); 586 587 inst = insts_to_rename.front(); 588 589 //For all kind of instructions, check ROB and IQ first 590 //For load instruction, check LQ size and take into account the inflight loads 591 //For store instruction, check SQ size and take into account the inflight stores 592 593 if (inst->isLoad()) { 594 if (calcFreeLQEntries(tid) <= 0) { 595 DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free LQ\n"); 596 source = LQ; 597 incrFullStat(source); 598 break; 599 } 600 } 601 602 if (inst->isStore()) { 603 if (calcFreeSQEntries(tid) <= 0) { 604 DPRINTF(Rename, "[tid:%u]: Cannot rename due to no free SQ\n"); 605 source = SQ; 606 incrFullStat(source); 607 break; 608 } 609 } 610 611 insts_to_rename.pop_front(); 612 613 if (renameStatus[tid] == Unblocking) { 614 DPRINTF(Rename,"[tid:%u]: Removing [sn:%lli] PC:%s from rename " 615 "skidBuffer\n", tid, inst->seqNum, inst->pcState()); 616 } 617 618 if (inst->isSquashed()) { 619 DPRINTF(Rename, "[tid:%u]: instruction %i with PC %s is " 620 "squashed, skipping.\n", tid, inst->seqNum, 621 inst->pcState()); 622 623 ++renameSquashedInsts; 624 625 // Decrement how many instructions are available. 626 --insts_available; 627 628 continue; 629 } 630 631 DPRINTF(Rename, "[tid:%u]: Processing instruction [sn:%lli] with " 632 "PC %s.\n", tid, inst->seqNum, inst->pcState()); 633 634 // Check here to make sure there are enough destination registers 635 // to rename to. Otherwise block. 636 if (!renameMap[tid]->canRename(inst->numIntDestRegs(), 637 inst->numFPDestRegs(), 638 inst->numCCDestRegs())) { 639 DPRINTF(Rename, "Blocking due to lack of free " 640 "physical registers to rename to.\n"); 641 blockThisCycle = true; 642 insts_to_rename.push_front(inst); 643 ++renameFullRegistersEvents; 644 645 break; 646 } 647 648 // Handle serializeAfter/serializeBefore instructions. 649 // serializeAfter marks the next instruction as serializeBefore. 650 // serializeBefore makes the instruction wait in rename until the ROB 651 // is empty. 652 653 // In this model, IPR accesses are serialize before 654 // instructions, and store conditionals are serialize after 655 // instructions. This is mainly due to lack of support for 656 // out-of-order operations of either of those classes of 657 // instructions. 658 if ((inst->isIprAccess() || inst->isSerializeBefore()) && 659 !inst->isSerializeHandled()) { 660 DPRINTF(Rename, "Serialize before instruction encountered.\n"); 661 662 if (!inst->isTempSerializeBefore()) { 663 renamedSerializing++; 664 inst->setSerializeHandled(); 665 } else { 666 renamedTempSerializing++; 667 } 668 669 // Change status over to SerializeStall so that other stages know 670 // what this is blocked on. 671 renameStatus[tid] = SerializeStall; 672 673 serializeInst[tid] = inst; 674 675 blockThisCycle = true; 676 677 break; 678 } else if ((inst->isStoreConditional() || inst->isSerializeAfter()) && 679 !inst->isSerializeHandled()) { 680 DPRINTF(Rename, "Serialize after instruction encountered.\n"); 681 682 renamedSerializing++; 683 684 inst->setSerializeHandled(); 685 686 serializeAfter(insts_to_rename, tid); 687 } 688 689 renameSrcRegs(inst, inst->threadNumber); 690 691 renameDestRegs(inst, inst->threadNumber); 692 693 if (inst->isLoad()) { 694 loadsInProgress[tid]++; 695 } 696 if (inst->isStore()) { 697 storesInProgress[tid]++; 698 } 699 ++renamed_insts; 700 701 702 // Put instruction in rename queue. 703 toIEW->insts[toIEWIndex] = inst; 704 ++(toIEW->size); 705 706 // Increment which instruction we're on. 707 ++toIEWIndex; 708 709 // Decrement how many instructions are available. 710 --insts_available; 711 } 712 713 instsInProgress[tid] += renamed_insts; 714 renameRenamedInsts += renamed_insts; 715 716 // If we wrote to the time buffer, record this. 717 if (toIEWIndex) { 718 wroteToTimeBuffer = true; 719 } 720 721 // Check if there's any instructions left that haven't yet been renamed. 722 // If so then block. 723 if (insts_available) { 724 blockThisCycle = true; 725 } 726 727 if (blockThisCycle) { 728 block(tid); 729 toDecode->renameUnblock[tid] = false; 730 } 731} 732 733template<class Impl> 734void 735DefaultRename<Impl>::skidInsert(ThreadID tid) 736{ 737 DynInstPtr inst = NULL; 738 739 while (!insts[tid].empty()) { 740 inst = insts[tid].front(); 741 742 insts[tid].pop_front(); 743 744 assert(tid == inst->threadNumber); 745 746 DPRINTF(Rename, "[tid:%u]: Inserting [sn:%lli] PC: %s into Rename " 747 "skidBuffer\n", tid, inst->seqNum, inst->pcState()); 748 749 ++renameSkidInsts; 750 751 skidBuffer[tid].push_back(inst); 752 } 753 754 if (skidBuffer[tid].size() > skidBufferMax) 755 { 756 typename InstQueue::iterator it; 757 warn("Skidbuffer contents:\n"); 758 for(it = skidBuffer[tid].begin(); it != skidBuffer[tid].end(); it++) 759 { 760 warn("[tid:%u]: %s [sn:%i].\n", tid, 761 (*it)->staticInst->disassemble(inst->instAddr()), 762 (*it)->seqNum); 763 } 764 panic("Skidbuffer Exceeded Max Size"); 765 } 766} 767 768template <class Impl> 769void 770DefaultRename<Impl>::sortInsts() 771{ 772 int insts_from_decode = fromDecode->size; 773 for (int i = 0; i < insts_from_decode; ++i) { 774 DynInstPtr inst = fromDecode->insts[i]; 775 insts[inst->threadNumber].push_back(inst); 776#if TRACING_ON 777 if (DTRACE(O3PipeView)) { 778 inst->renameTick = curTick() - inst->fetchTick; 779 } 780#endif 781 } 782} 783 784template<class Impl> 785bool 786DefaultRename<Impl>::skidsEmpty() 787{ 788 list<ThreadID>::iterator threads = activeThreads->begin(); 789 list<ThreadID>::iterator end = activeThreads->end(); 790 791 while (threads != end) { 792 ThreadID tid = *threads++; 793 794 if (!skidBuffer[tid].empty()) 795 return false; 796 } 797 798 return true; 799} 800 801template<class Impl> 802void 803DefaultRename<Impl>::updateStatus() 804{ 805 bool any_unblocking = false; 806 807 list<ThreadID>::iterator threads = activeThreads->begin(); 808 list<ThreadID>::iterator end = activeThreads->end(); 809 810 while (threads != end) { 811 ThreadID tid = *threads++; 812 813 if (renameStatus[tid] == Unblocking) { 814 any_unblocking = true; 815 break; 816 } 817 } 818 819 // Rename will have activity if it's unblocking. 820 if (any_unblocking) { 821 if (_status == Inactive) { 822 _status = Active; 823 824 DPRINTF(Activity, "Activating stage.\n"); 825 826 cpu->activateStage(O3CPU::RenameIdx); 827 } 828 } else { 829 // If it's not unblocking, then rename will not have any internal 830 // activity. Switch it to inactive. 831 if (_status == Active) { 832 _status = Inactive; 833 DPRINTF(Activity, "Deactivating stage.\n"); 834 835 cpu->deactivateStage(O3CPU::RenameIdx); 836 } 837 } 838} 839 840template <class Impl> 841bool 842DefaultRename<Impl>::block(ThreadID tid) 843{ 844 DPRINTF(Rename, "[tid:%u]: Blocking.\n", tid); 845 846 // Add the current inputs onto the skid buffer, so they can be 847 // reprocessed when this stage unblocks. 848 skidInsert(tid); 849 850 // Only signal backwards to block if the previous stages do not think 851 // rename is already blocked. 852 if (renameStatus[tid] != Blocked) { 853 // If resumeUnblocking is set, we unblocked during the squash, 854 // but now we're have unblocking status. We need to tell earlier 855 // stages to block. 856 if (resumeUnblocking || renameStatus[tid] != Unblocking) { 857 toDecode->renameBlock[tid] = true; 858 toDecode->renameUnblock[tid] = false; 859 wroteToTimeBuffer = true; 860 } 861 862 // Rename can not go from SerializeStall to Blocked, otherwise 863 // it would not know to complete the serialize stall. 864 if (renameStatus[tid] != SerializeStall) { 865 // Set status to Blocked. 866 renameStatus[tid] = Blocked; 867 return true; 868 } 869 } 870 871 return false; 872} 873 874template <class Impl> 875bool 876DefaultRename<Impl>::unblock(ThreadID tid) 877{ 878 DPRINTF(Rename, "[tid:%u]: Trying to unblock.\n", tid); 879 880 // Rename is done unblocking if the skid buffer is empty. 881 if (skidBuffer[tid].empty() && renameStatus[tid] != SerializeStall) { 882 883 DPRINTF(Rename, "[tid:%u]: Done unblocking.\n", tid); 884 885 toDecode->renameUnblock[tid] = true; 886 wroteToTimeBuffer = true; 887 888 renameStatus[tid] = Running; 889 return true; 890 } 891 892 return false; 893} 894 895template <class Impl> 896void 897DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid) 898{ 899 typename std::list<RenameHistory>::iterator hb_it = 900 historyBuffer[tid].begin(); 901 902 // After a syscall squashes everything, the history buffer may be empty 903 // but the ROB may still be squashing instructions. 904 if (historyBuffer[tid].empty()) { 905 return; 906 } 907 908 // Go through the most recent instructions, undoing the mappings 909 // they did and freeing up the registers. 910 while (!historyBuffer[tid].empty() && 911 hb_it->instSeqNum > squashed_seq_num) { 912 assert(hb_it != historyBuffer[tid].end()); 913 914 DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence " 915 "number %i.\n", tid, hb_it->instSeqNum); 916 917 // Undo the rename mapping only if it was really a change. 918 // Special regs that are not really renamed (like misc regs 919 // and the zero reg) can be recognized because the new mapping 920 // is the same as the old one. While it would be merely a 921 // waste of time to update the rename table, we definitely 922 // don't want to put these on the free list. 923 if (hb_it->newPhysReg != hb_it->prevPhysReg) { 924 // Tell the rename map to set the architected register to the 925 // previous physical register that it was renamed to. 926 renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg); 927 928 // Put the renamed physical register back on the free list. 929 freeList->addReg(hb_it->newPhysReg); 930 } 931 932 historyBuffer[tid].erase(hb_it++); 933 934 ++renameUndoneMaps; 935 } 936} 937 938template<class Impl> 939void 940DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid) 941{ 942 DPRINTF(Rename, "[tid:%u]: Removing a committed instruction from the " 943 "history buffer %u (size=%i), until [sn:%lli].\n", 944 tid, tid, historyBuffer[tid].size(), inst_seq_num); 945 946 typename std::list<RenameHistory>::iterator hb_it = 947 historyBuffer[tid].end(); 948 949 --hb_it; 950 951 if (historyBuffer[tid].empty()) { 952 DPRINTF(Rename, "[tid:%u]: History buffer is empty.\n", tid); 953 return; 954 } else if (hb_it->instSeqNum > inst_seq_num) { 955 DPRINTF(Rename, "[tid:%u]: Old sequence number encountered. Ensure " 956 "that a syscall happened recently.\n", tid); 957 return; 958 } 959 960 // Commit all the renames up until (and including) the committed sequence 961 // number. Some or even all of the committed instructions may not have 962 // rename histories if they did not have destination registers that were 963 // renamed. 964 while (!historyBuffer[tid].empty() && 965 hb_it != historyBuffer[tid].end() && 966 hb_it->instSeqNum <= inst_seq_num) { 967 968 DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, " 969 "[sn:%lli].\n", 970 tid, hb_it->prevPhysReg, hb_it->instSeqNum); 971 972 // Don't free special phys regs like misc and zero regs, which 973 // can be recognized because the new mapping is the same as 974 // the old one. 975 if (hb_it->newPhysReg != hb_it->prevPhysReg) { 976 freeList->addReg(hb_it->prevPhysReg); 977 } 978 979 ++renameCommittedMaps; 980 981 historyBuffer[tid].erase(hb_it--); 982 } 983} 984 985template <class Impl> 986inline void 987DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid) 988{ 989 ThreadContext *tc = inst->tcBase(); 990 RenameMap *map = renameMap[tid]; 991 unsigned num_src_regs = inst->numSrcRegs(); 992 993 // Get the architectual register numbers from the source and 994 // operands, and redirect them to the right physical register. 995 for (int src_idx = 0; src_idx < num_src_regs; src_idx++) { 996 RegIndex src_reg = inst->srcRegIdx(src_idx); 997 RegIndex rel_src_reg; 998 RegIndex flat_rel_src_reg; 999 PhysRegIndex renamed_reg; 1000 1001 switch (regIdxToClass(src_reg, &rel_src_reg)) { 1002 case IntRegClass: 1003 flat_rel_src_reg = tc->flattenIntIndex(rel_src_reg); 1004 renamed_reg = map->lookupInt(flat_rel_src_reg); 1005 intRenameLookups++; 1006 break; 1007 1008 case FloatRegClass: 1009 flat_rel_src_reg = tc->flattenFloatIndex(rel_src_reg); 1010 renamed_reg = map->lookupFloat(flat_rel_src_reg); 1011 fpRenameLookups++; 1012 break; 1013 1014 case CCRegClass: 1015 flat_rel_src_reg = tc->flattenCCIndex(rel_src_reg); 1016 renamed_reg = map->lookupCC(flat_rel_src_reg); 1017 break; 1018 1019 case MiscRegClass: 1020 // misc regs don't get flattened 1021 flat_rel_src_reg = rel_src_reg; 1022 renamed_reg = map->lookupMisc(flat_rel_src_reg); 1023 break; 1024 1025 default: 1026 panic("Reg index is out of bound: %d.", src_reg); 1027 } 1028 1029 DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i (flattened %i), " 1030 "got phys reg %i\n", tid, RegClassStrings[regIdxToClass(src_reg)], 1031 (int)src_reg, (int)flat_rel_src_reg, (int)renamed_reg); 1032 1033 inst->renameSrcReg(src_idx, renamed_reg); 1034 1035 // See if the register is ready or not. 1036 if (scoreboard->getReg(renamed_reg)) { 1037 DPRINTF(Rename, "[tid:%u]: Register %d is ready.\n", 1038 tid, renamed_reg); 1039 1040 inst->markSrcRegReady(src_idx); 1041 } else { 1042 DPRINTF(Rename, "[tid:%u]: Register %d is not ready.\n", 1043 tid, renamed_reg); 1044 } 1045 1046 ++renameRenameLookups; 1047 } 1048} 1049 1050template <class Impl> 1051inline void 1052DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid) 1053{ 1054 ThreadContext *tc = inst->tcBase(); 1055 RenameMap *map = renameMap[tid]; 1056 unsigned num_dest_regs = inst->numDestRegs(); 1057 1058 // Rename the destination registers. 1059 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) { 1060 RegIndex dest_reg = inst->destRegIdx(dest_idx); 1061 RegIndex rel_dest_reg; 1062 RegIndex flat_rel_dest_reg; 1063 RegIndex flat_uni_dest_reg; 1064 typename RenameMap::RenameInfo rename_result; 1065 1066 switch (regIdxToClass(dest_reg, &rel_dest_reg)) { 1067 case IntRegClass: 1068 flat_rel_dest_reg = tc->flattenIntIndex(rel_dest_reg); 1069 rename_result = map->renameInt(flat_rel_dest_reg); 1070 flat_uni_dest_reg = flat_rel_dest_reg; // 1:1 mapping 1071 break; 1072 1073 case FloatRegClass: 1074 flat_rel_dest_reg = tc->flattenFloatIndex(rel_dest_reg); 1075 rename_result = map->renameFloat(flat_rel_dest_reg); 1076 flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base; 1077 break; 1078 1079 case CCRegClass: 1080 flat_rel_dest_reg = tc->flattenCCIndex(rel_dest_reg); 1081 rename_result = map->renameCC(flat_rel_dest_reg); 1082 flat_uni_dest_reg = flat_rel_dest_reg + TheISA::CC_Reg_Base; 1083 break; 1084 1085 case MiscRegClass: 1086 // misc regs don't get flattened 1087 flat_rel_dest_reg = rel_dest_reg; 1088 rename_result = map->renameMisc(flat_rel_dest_reg); 1089 flat_uni_dest_reg = flat_rel_dest_reg + TheISA::Misc_Reg_Base; 1090 break; 1091 1092 default: 1093 panic("Reg index is out of bound: %d.", dest_reg); 1094 } 1095 1096 inst->flattenDestReg(dest_idx, flat_uni_dest_reg); 1097 1098 // Mark Scoreboard entry as not ready 1099 scoreboard->unsetReg(rename_result.first); 1100 1101 DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical " 1102 "reg %i.\n", tid, (int)flat_rel_dest_reg, 1103 (int)rename_result.first); 1104 1105 // Record the rename information so that a history can be kept. 1106 RenameHistory hb_entry(inst->seqNum, flat_uni_dest_reg, 1107 rename_result.first, 1108 rename_result.second); 1109 1110 historyBuffer[tid].push_front(hb_entry); 1111 1112 DPRINTF(Rename, "[tid:%u]: Adding instruction to history buffer " 1113 "(size=%i), [sn:%lli].\n",tid, 1114 historyBuffer[tid].size(), 1115 (*historyBuffer[tid].begin()).instSeqNum); 1116 1117 // Tell the instruction to rename the appropriate destination 1118 // register (dest_idx) to the new physical register 1119 // (rename_result.first), and record the previous physical 1120 // register that the same logical register was renamed to 1121 // (rename_result.second). 1122 inst->renameDestReg(dest_idx, 1123 rename_result.first, 1124 rename_result.second); 1125 1126 ++renameRenamedOperands; 1127 } 1128} 1129 1130template <class Impl> 1131inline int 1132DefaultRename<Impl>::calcFreeROBEntries(ThreadID tid) 1133{ 1134 int num_free = freeEntries[tid].robEntries - 1135 (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched); 1136 1137 //DPRINTF(Rename,"[tid:%i]: %i rob free\n",tid,num_free); 1138 1139 return num_free; 1140} 1141 1142template <class Impl> 1143inline int 1144DefaultRename<Impl>::calcFreeIQEntries(ThreadID tid) 1145{ 1146 int num_free = freeEntries[tid].iqEntries - 1147 (instsInProgress[tid] - fromIEW->iewInfo[tid].dispatched); 1148 1149 //DPRINTF(Rename,"[tid:%i]: %i iq free\n",tid,num_free); 1150 1151 return num_free; 1152} 1153 1154template <class Impl> 1155inline int 1156DefaultRename<Impl>::calcFreeLQEntries(ThreadID tid) 1157{ 1158 int num_free = freeEntries[tid].lqEntries - 1159 (loadsInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToLQ); 1160 DPRINTF(Rename, "calcFreeLQEntries: free lqEntries: %d, loadsInProgress: %d, " 1161 "loads dispatchedToLQ: %d\n", freeEntries[tid].lqEntries, 1162 loadsInProgress[tid], fromIEW->iewInfo[tid].dispatchedToLQ); 1163 return num_free; 1164} 1165 1166template <class Impl> 1167inline int 1168DefaultRename<Impl>::calcFreeSQEntries(ThreadID tid) 1169{ 1170 int num_free = freeEntries[tid].sqEntries - 1171 (storesInProgress[tid] - fromIEW->iewInfo[tid].dispatchedToSQ); 1172 DPRINTF(Rename, "calcFreeSQEntries: free sqEntries: %d, storesInProgress: %d, " 1173 "stores dispatchedToSQ: %d\n", freeEntries[tid].sqEntries, 1174 storesInProgress[tid], fromIEW->iewInfo[tid].dispatchedToSQ); 1175 return num_free; 1176} 1177 1178template <class Impl> 1179unsigned 1180DefaultRename<Impl>::validInsts() 1181{ 1182 unsigned inst_count = 0; 1183 1184 for (int i=0; i<fromDecode->size; i++) { 1185 if (!fromDecode->insts[i]->isSquashed()) 1186 inst_count++; 1187 } 1188 1189 return inst_count; 1190} 1191 1192template <class Impl> 1193void 1194DefaultRename<Impl>::readStallSignals(ThreadID tid) 1195{ 1196 if (fromIEW->iewBlock[tid]) { 1197 stalls[tid].iew = true; 1198 } 1199 1200 if (fromIEW->iewUnblock[tid]) { 1201 assert(stalls[tid].iew); 1202 stalls[tid].iew = false; 1203 } 1204} 1205 1206template <class Impl> 1207bool 1208DefaultRename<Impl>::checkStall(ThreadID tid) 1209{ 1210 bool ret_val = false; 1211 1212 if (stalls[tid].iew) { 1213 DPRINTF(Rename,"[tid:%i]: Stall from IEW stage detected.\n", tid); 1214 ret_val = true; 1215 } else if (calcFreeROBEntries(tid) <= 0) { 1216 DPRINTF(Rename,"[tid:%i]: Stall: ROB has 0 free entries.\n", tid); 1217 ret_val = true; 1218 } else if (calcFreeIQEntries(tid) <= 0) { 1219 DPRINTF(Rename,"[tid:%i]: Stall: IQ has 0 free entries.\n", tid); 1220 ret_val = true; 1221 } else if (calcFreeLQEntries(tid) <= 0 && calcFreeSQEntries(tid) <= 0) { 1222 DPRINTF(Rename,"[tid:%i]: Stall: LSQ has 0 free entries.\n", tid); 1223 ret_val = true; 1224 } else if (renameMap[tid]->numFreeEntries() <= 0) { 1225 DPRINTF(Rename,"[tid:%i]: Stall: RenameMap has 0 free entries.\n", tid); 1226 ret_val = true; 1227 } else if (renameStatus[tid] == SerializeStall && 1228 (!emptyROB[tid] || instsInProgress[tid])) { 1229 DPRINTF(Rename,"[tid:%i]: Stall: Serialize stall and ROB is not " 1230 "empty.\n", 1231 tid); 1232 ret_val = true; 1233 } 1234 1235 return ret_val; 1236} 1237 1238template <class Impl> 1239void 1240DefaultRename<Impl>::readFreeEntries(ThreadID tid) 1241{ 1242 if (fromIEW->iewInfo[tid].usedIQ) 1243 freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries; 1244 1245 if (fromIEW->iewInfo[tid].usedLSQ) { 1246 freeEntries[tid].lqEntries = fromIEW->iewInfo[tid].freeLQEntries; 1247 freeEntries[tid].sqEntries = fromIEW->iewInfo[tid].freeSQEntries; 1248 } 1249 1250 if (fromCommit->commitInfo[tid].usedROB) { 1251 freeEntries[tid].robEntries = 1252 fromCommit->commitInfo[tid].freeROBEntries; 1253 emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB; 1254 } 1255 1256 DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, " 1257 "Free LQ: %i, Free SQ: %i\n", 1258 tid, 1259 freeEntries[tid].iqEntries, 1260 freeEntries[tid].robEntries, 1261 freeEntries[tid].lqEntries, 1262 freeEntries[tid].sqEntries); 1263 1264 DPRINTF(Rename, "[tid:%i]: %i instructions not yet in ROB\n", 1265 tid, instsInProgress[tid]); 1266} 1267 1268template <class Impl> 1269bool 1270DefaultRename<Impl>::checkSignalsAndUpdate(ThreadID tid) 1271{ 1272 // Check if there's a squash signal, squash if there is 1273 // Check stall signals, block if necessary. 1274 // If status was blocked 1275 // check if stall conditions have passed 1276 // if so then go to unblocking 1277 // If status was Squashing 1278 // check if squashing is not high. Switch to running this cycle. 1279 // If status was serialize stall 1280 // check if ROB is empty and no insts are in flight to the ROB 1281 1282 readFreeEntries(tid); 1283 readStallSignals(tid); 1284 1285 if (fromCommit->commitInfo[tid].squash) { 1286 DPRINTF(Rename, "[tid:%u]: Squashing instructions due to squash from " 1287 "commit.\n", tid); 1288 1289 squash(fromCommit->commitInfo[tid].doneSeqNum, tid); 1290 1291 return true; 1292 } 1293 1294 if (checkStall(tid)) { 1295 return block(tid); 1296 } 1297 1298 if (renameStatus[tid] == Blocked) { 1299 DPRINTF(Rename, "[tid:%u]: Done blocking, switching to unblocking.\n", 1300 tid); 1301 1302 renameStatus[tid] = Unblocking; 1303 1304 unblock(tid); 1305 1306 return true; 1307 } 1308 1309 if (renameStatus[tid] == Squashing) { 1310 // Switch status to running if rename isn't being told to block or 1311 // squash this cycle. 1312 if (resumeSerialize) { 1313 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to serialize.\n", 1314 tid); 1315 1316 renameStatus[tid] = SerializeStall; 1317 return true; 1318 } else if (resumeUnblocking) { 1319 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to unblocking.\n", 1320 tid); 1321 renameStatus[tid] = Unblocking; 1322 return true; 1323 } else { 1324 DPRINTF(Rename, "[tid:%u]: Done squashing, switching to running.\n", 1325 tid); 1326 1327 renameStatus[tid] = Running; 1328 return false; 1329 } 1330 } 1331 1332 if (renameStatus[tid] == SerializeStall) { 1333 // Stall ends once the ROB is free. 1334 DPRINTF(Rename, "[tid:%u]: Done with serialize stall, switching to " 1335 "unblocking.\n", tid); 1336 1337 DynInstPtr serial_inst = serializeInst[tid]; 1338 1339 renameStatus[tid] = Unblocking; 1340 1341 unblock(tid); 1342 1343 DPRINTF(Rename, "[tid:%u]: Processing instruction [%lli] with " 1344 "PC %s.\n", tid, serial_inst->seqNum, serial_inst->pcState()); 1345 1346 // Put instruction into queue here. 1347 serial_inst->clearSerializeBefore(); 1348 1349 if (!skidBuffer[tid].empty()) { 1350 skidBuffer[tid].push_front(serial_inst); 1351 } else { 1352 insts[tid].push_front(serial_inst); 1353 } 1354 1355 DPRINTF(Rename, "[tid:%u]: Instruction must be processed by rename." 1356 " Adding to front of list.\n", tid); 1357 1358 serializeInst[tid] = NULL; 1359 1360 return true; 1361 } 1362 1363 // If we've reached this point, we have not gotten any signals that 1364 // cause rename to change its status. Rename remains the same as before. 1365 return false; 1366} 1367 1368template<class Impl> 1369void 1370DefaultRename<Impl>::serializeAfter(InstQueue &inst_list, ThreadID tid) 1371{ 1372 if (inst_list.empty()) { 1373 // Mark a bit to say that I must serialize on the next instruction. 1374 serializeOnNextInst[tid] = true; 1375 return; 1376 } 1377 1378 // Set the next instruction as serializing. 1379 inst_list.front()->setSerializeBefore(); 1380} 1381 1382template <class Impl> 1383inline void 1384DefaultRename<Impl>::incrFullStat(const FullSource &source) 1385{ 1386 switch (source) { 1387 case ROB: 1388 ++renameROBFullEvents; 1389 break; 1390 case IQ: 1391 ++renameIQFullEvents; 1392 break; 1393 case LQ: 1394 ++renameLQFullEvents; 1395 break; 1396 case SQ: 1397 ++renameSQFullEvents; 1398 break; 1399 default: 1400 panic("Rename full stall stat should be incremented for a reason!"); 1401 break; 1402 } 1403} 1404 1405template <class Impl> 1406void 1407DefaultRename<Impl>::dumpHistory() 1408{ 1409 typename std::list<RenameHistory>::iterator buf_it; 1410 1411 for (ThreadID tid = 0; tid < numThreads; tid++) { 1412 1413 buf_it = historyBuffer[tid].begin(); 1414 1415 while (buf_it != historyBuffer[tid].end()) { 1416 cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys " 1417 "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg, 1418 (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg); 1419 1420 buf_it++; 1421 } 1422 } 1423} 1424 1425#endif//__CPU_O3_RENAME_IMPL_HH__ 1426