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