iew_impl.hh revision 1062
110448Snilay@cs.wisc.edu// @todo: Fix the instantaneous communication among all the stages within 210448Snilay@cs.wisc.edu// iew. There's a clear delay between issue and execute, yet backwards 310448Snilay@cs.wisc.edu// communication happens simultaneously. Might not be that bad really... 410448Snilay@cs.wisc.edu// it might skew stats a bit though. Issue would otherwise try to issue 510448Snilay@cs.wisc.edu// instructions that would never be executed if there were a delay; without 610448Snilay@cs.wisc.edu// it issue will simply squash. Make this stage block properly. 710448Snilay@cs.wisc.edu// Update the statuses for each stage. 810448Snilay@cs.wisc.edu// Actually read instructions out of the skid buffer. 910448Snilay@cs.wisc.edu 1010448Snilay@cs.wisc.edu#include <queue> 1110448Snilay@cs.wisc.edu 1210448Snilay@cs.wisc.edu#include "base/timebuf.hh" 1310448Snilay@cs.wisc.edu#include "cpu/beta_cpu/iew.hh" 1410448Snilay@cs.wisc.edu 1510448Snilay@cs.wisc.edutemplate<class Impl, class IQ> 1610448Snilay@cs.wisc.eduSimpleIEW<Impl, IQ>::SimpleIEW(Params ¶ms) 1710448Snilay@cs.wisc.edu : // Just make this time buffer really big for now 1810448Snilay@cs.wisc.edu issueToExecQueue(5, 5), 1910448Snilay@cs.wisc.edu instQueue(params), 2010448Snilay@cs.wisc.edu ldstQueue(params), 2110448Snilay@cs.wisc.edu commitToIEWDelay(params.commitToIEWDelay), 2210447Snilay@cs.wisc.edu renameToIEWDelay(params.renameToIEWDelay), 2310447Snilay@cs.wisc.edu issueToExecuteDelay(params.issueToExecuteDelay), 2410447Snilay@cs.wisc.edu issueReadWidth(params.issueWidth), 2510447Snilay@cs.wisc.edu issueWidth(params.issueWidth), 2610447Snilay@cs.wisc.edu executeWidth(params.executeWidth) 2710447Snilay@cs.wisc.edu{ 2810447Snilay@cs.wisc.edu DPRINTF(IEW, "IEW: executeIntWidth: %i.\n", params.executeIntWidth); 2910447Snilay@cs.wisc.edu _status = Idle; 3010447Snilay@cs.wisc.edu _issueStatus = Idle; 3110447Snilay@cs.wisc.edu _exeStatus = Idle; 3210447Snilay@cs.wisc.edu _wbStatus = Idle; 3310447Snilay@cs.wisc.edu 3410447Snilay@cs.wisc.edu // Setup wire to read instructions coming from issue. 3510447Snilay@cs.wisc.edu fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay); 3610447Snilay@cs.wisc.edu 3710447Snilay@cs.wisc.edu // Instruction queue needs the queue between issue and execute. 3810447Snilay@cs.wisc.edu instQueue.setIssueToExecuteQueue(&issueToExecQueue); 3910447Snilay@cs.wisc.edu} 4010447Snilay@cs.wisc.edu 4110447Snilay@cs.wisc.edutemplate <class Impl, class IQ> 4210447Snilay@cs.wisc.eduvoid 4310447Snilay@cs.wisc.eduSimpleIEW<Impl, IQ>::regStats() 4410447Snilay@cs.wisc.edu{ 4510447Snilay@cs.wisc.edu instQueue.regStats(); 4610447Snilay@cs.wisc.edu 4710447Snilay@cs.wisc.edu iewIdleCycles 4810447Snilay@cs.wisc.edu .name(name() + ".iewIdleCycles") 4910447Snilay@cs.wisc.edu .desc("Number of cycles IEW is idle"); 5010447Snilay@cs.wisc.edu 5110447Snilay@cs.wisc.edu iewSquashCycles 5210447Snilay@cs.wisc.edu .name(name() + ".iewSquashCycles") 5310447Snilay@cs.wisc.edu .desc("Number of cycles IEW is squashing"); 5410447Snilay@cs.wisc.edu 5510447Snilay@cs.wisc.edu iewBlockCycles 5610447Snilay@cs.wisc.edu .name(name() + ".iewBlockCycles") 5710447Snilay@cs.wisc.edu .desc("Number of cycles IEW is blocking"); 5810447Snilay@cs.wisc.edu 5910447Snilay@cs.wisc.edu iewUnblockCycles 6010447Snilay@cs.wisc.edu .name(name() + ".iewUnblockCycles") 6110447Snilay@cs.wisc.edu .desc("Number of cycles IEW is unblocking"); 6210447Snilay@cs.wisc.edu 6310447Snilay@cs.wisc.edu// iewWBInsts; 6410447Snilay@cs.wisc.edu 65 iewDispatchedInsts 66 .name(name() + ".iewDispatchedInsts") 67 .desc("Number of instructions dispatched to IQ"); 68 69 iewDispSquashedInsts 70 .name(name() + ".iewDispSquashedInsts") 71 .desc("Number of squashed instructions skipped by dispatch"); 72 73 iewDispLoadInsts 74 .name(name() + ".iewDispLoadInsts") 75 .desc("Number of dispatched load instructions"); 76 77 iewDispStoreInsts 78 .name(name() + ".iewDispStoreInsts") 79 .desc("Number of dispatched store instructions"); 80 81 iewDispNonSpecInsts 82 .name(name() + ".iewDispNonSpecInsts") 83 .desc("Number of dispatched non-speculative instructions"); 84 85 iewIQFullEvents 86 .name(name() + ".iewIQFullEvents") 87 .desc("Number of times the IQ has become full, causing a stall"); 88 89 iewExecutedInsts 90 .name(name() + ".iewExecutedInsts") 91 .desc("Number of executed instructions"); 92 93 iewExecLoadInsts 94 .name(name() + ".iewExecLoadInsts") 95 .desc("Number of load instructions executed"); 96 97 iewExecStoreInsts 98 .name(name() + ".iewExecStoreInsts") 99 .desc("Number of store instructions executed"); 100 101 iewExecSquashedInsts 102 .name(name() + ".iewExecSquashedInsts") 103 .desc("Number of squashed instructions skipped in execute"); 104 105 memOrderViolationEvents 106 .name(name() + ".memOrderViolationEvents") 107 .desc("Number of memory order violations"); 108 109 predictedTakenIncorrect 110 .name(name() + ".predictedTakenIncorrect") 111 .desc("Number of branches that were predicted taken incorrectly"); 112} 113 114template<class Impl, class IQ> 115void 116SimpleIEW<Impl, IQ>::setCPU(FullCPU *cpu_ptr) 117{ 118 DPRINTF(IEW, "IEW: Setting CPU pointer.\n"); 119 cpu = cpu_ptr; 120 121 instQueue.setCPU(cpu_ptr); 122 ldstQueue.setCPU(cpu_ptr); 123} 124 125template<class Impl, class IQ> 126void 127SimpleIEW<Impl, IQ>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 128{ 129 DPRINTF(IEW, "IEW: Setting time buffer pointer.\n"); 130 timeBuffer = tb_ptr; 131 132 // Setup wire to read information from time buffer, from commit. 133 fromCommit = timeBuffer->getWire(-commitToIEWDelay); 134 135 // Setup wire to write information back to previous stages. 136 toRename = timeBuffer->getWire(0); 137 138 // Instruction queue also needs main time buffer. 139 instQueue.setTimeBuffer(tb_ptr); 140} 141 142template<class Impl, class IQ> 143void 144SimpleIEW<Impl, IQ>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 145{ 146 DPRINTF(IEW, "IEW: Setting rename queue pointer.\n"); 147 renameQueue = rq_ptr; 148 149 // Setup wire to read information from rename queue. 150 fromRename = renameQueue->getWire(-renameToIEWDelay); 151} 152 153template<class Impl, class IQ> 154void 155SimpleIEW<Impl, IQ>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) 156{ 157 DPRINTF(IEW, "IEW: Setting IEW queue pointer.\n"); 158 iewQueue = iq_ptr; 159 160 // Setup wire to write instructions to commit. 161 toCommit = iewQueue->getWire(0); 162} 163 164template<class Impl, class IQ> 165void 166SimpleIEW<Impl, IQ>::setRenameMap(RenameMap *rm_ptr) 167{ 168 DPRINTF(IEW, "IEW: Setting rename map pointer.\n"); 169 renameMap = rm_ptr; 170} 171 172template<class Impl, class IQ> 173void 174SimpleIEW<Impl, IQ>::wakeDependents(DynInstPtr &inst) 175{ 176 instQueue.wakeDependents(inst); 177} 178 179template<class Impl, class IQ> 180void 181SimpleIEW<Impl, IQ>::block() 182{ 183 DPRINTF(IEW, "IEW: Blocking.\n"); 184 // Set the status to Blocked. 185 _status = Blocked; 186 187 // Add the current inputs to the skid buffer so they can be 188 // reprocessed when this stage unblocks. 189 skidBuffer.push(*fromRename); 190 191 // Note that this stage only signals previous stages to stall when 192 // it is the cause of the stall originates at this stage. Otherwise 193 // the previous stages are expected to check all possible stall signals. 194} 195 196template<class Impl, class IQ> 197inline void 198SimpleIEW<Impl, IQ>::unblock() 199{ 200 // Check if there's information in the skid buffer. If there is, then 201 // set status to unblocking, otherwise set it directly to running. 202 DPRINTF(IEW, "IEW: Reading instructions out of the skid " 203 "buffer.\n"); 204 // Remove the now processed instructions from the skid buffer. 205 skidBuffer.pop(); 206 207 // If there's still information in the skid buffer, then 208 // continue to tell previous stages to stall. They will be 209 // able to restart once the skid buffer is empty. 210 if (!skidBuffer.empty()) { 211 toRename->iewInfo.stall = true; 212 } else { 213 DPRINTF(IEW, "IEW: Stage is done unblocking.\n"); 214 _status = Running; 215 } 216} 217 218template<class Impl, class IQ> 219void 220SimpleIEW<Impl, IQ>::squash() 221{ 222 DPRINTF(IEW, "IEW: Squashing all instructions.\n"); 223 _status = Squashing; 224 225 // Tell the IQ to start squashing. 226 instQueue.squash(); 227 228 // Tell the LDSTQ to start squashing. 229 ldstQueue.squash(fromCommit->commitInfo.doneSeqNum); 230} 231 232template<class Impl, class IQ> 233void 234SimpleIEW<Impl, IQ>::squashDueToBranch(DynInstPtr &inst) 235{ 236 DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n", 237 inst->PC); 238 // Perhaps leave the squashing up to the ROB stage to tell it when to 239 // squash? 240 _status = Squashing; 241 242 // Tell rename to squash through the time buffer. 243 toCommit->squash = true; 244 // Also send PC update information back to prior stages. 245 toCommit->squashedSeqNum = inst->seqNum; 246 toCommit->mispredPC = inst->readPC(); 247 toCommit->nextPC = inst->readCalcTarg(); 248 toCommit->branchMispredict = true; 249 // Prediction was incorrect, so send back inverse. 250 toCommit->branchTaken = inst->readCalcTarg() != 251 (inst->readPC() + sizeof(MachInst)); 252// toCommit->globalHist = inst->readGlobalHist(); 253} 254 255template<class Impl, class IQ> 256void 257SimpleIEW<Impl, IQ>::squashDueToMem(DynInstPtr &inst) 258{ 259 DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n", 260 inst->PC); 261 // Perhaps leave the squashing up to the ROB stage to tell it when to 262 // squash? 263 _status = Squashing; 264 265 // Tell rename to squash through the time buffer. 266 toCommit->squash = true; 267 // Also send PC update information back to prior stages. 268 toCommit->squashedSeqNum = inst->seqNum; 269 toCommit->nextPC = inst->readCalcTarg(); 270} 271 272template <class Impl, class IQ> 273void 274SimpleIEW<Impl, IQ>::dispatchInsts() 275{ 276 //////////////////////////////////////// 277 // DISPATCH/ISSUE stage 278 //////////////////////////////////////// 279 280 //Put into its own function? 281 //Add instructions to IQ if there are any instructions there 282 283 // Check if there are any instructions coming from rename, and we're. 284 // not squashing. 285 if (fromRename->size > 0) { 286 int insts_to_add = fromRename->size; 287 288 // Loop through the instructions, putting them in the instruction 289 // queue. 290 for (int inst_num = 0; inst_num < insts_to_add; ++inst_num) 291 { 292 DynInstPtr inst = fromRename->insts[inst_num]; 293 294 // Make sure there's a valid instruction there. 295 assert(inst); 296 297 DPRINTF(IEW, "IEW: Issue: Adding PC %#x to IQ.\n", 298 inst->readPC()); 299 300 // Be sure to mark these instructions as ready so that the 301 // commit stage can go ahead and execute them, and mark 302 // them as issued so the IQ doesn't reprocess them. 303 if (inst->isSquashed()) { 304 ++iewDispSquashedInsts; 305 continue; 306 } else if (instQueue.isFull()) { 307 DPRINTF(IEW, "IEW: Issue: IQ has become full.\n"); 308 // Call function to start blocking. 309 block(); 310 // Tell previous stage to stall. 311 toRename->iewInfo.stall = true; 312 313 ++iewIQFullEvents; 314 break; 315 } else if (inst->isLoad()) { 316 DPRINTF(IEW, "IEW: Issue: Memory instruction " 317 "encountered, adding to LDSTQ.\n"); 318 319 // Reserve a spot in the load store queue for this 320 // memory access. 321 ldstQueue.insertLoad(inst); 322 323 ++iewDispLoadInsts; 324 } else if (inst->isStore()) { 325 ldstQueue.insertStore(inst); 326 327 // A bit of a hack. Set that it can commit so that 328 // the commit stage will try committing it, and then 329 // once commit realizes it's a store it will send back 330 // a signal to this stage to issue and execute that 331 // store. Change to be a bit that says the instruction 332 // has extra work to do at commit. 333 inst->setCanCommit(); 334 335 instQueue.insertNonSpec(inst); 336 337 ++iewDispStoreInsts; 338 ++iewDispNonSpecInsts; 339 340 continue; 341 } else if (inst->isNonSpeculative()) { 342 DPRINTF(IEW, "IEW: Issue: Nonspeculative instruction " 343 "encountered, skipping.\n"); 344 345 // Same hack as with stores. 346 inst->setCanCommit(); 347 348 // Specificall insert it as nonspeculative. 349 instQueue.insertNonSpec(inst); 350 351 ++iewDispNonSpecInsts; 352 353 continue; 354 } else if (inst->isNop()) { 355 DPRINTF(IEW, "IEW: Issue: Nop instruction encountered " 356 ", skipping.\n"); 357 358 inst->setIssued(); 359 inst->setExecuted(); 360 inst->setCanCommit(); 361 362 instQueue.advanceTail(inst); 363 364 continue; 365 } else if (inst->isExecuted()) { 366 DPRINTF(IEW, "IEW: Issue: Executed branch encountered, " 367 "skipping.\n"); 368 369 assert(inst->isDirectCtrl()); 370 371 inst->setIssued(); 372 inst->setCanCommit(); 373 374 instQueue.advanceTail(inst); 375 376 continue; 377 } 378 379 // If the instruction queue is not full, then add the 380 // instruction. 381 instQueue.insert(fromRename->insts[inst_num]); 382 383 ++iewDispatchedInsts; 384 } 385 } 386} 387 388template <class Impl, class IQ> 389void 390SimpleIEW<Impl, IQ>::executeInsts() 391{ 392 //////////////////////////////////////// 393 //EXECUTE/WRITEBACK stage 394 //////////////////////////////////////// 395 396 //Put into its own function? 397 //Similarly should probably have separate execution for int vs FP. 398 // Above comment is handled by the issue queue only issuing a valid 399 // mix of int/fp instructions. 400 //Actually okay to just have one execution, buuuuuut will need 401 //somewhere that defines the execution latency of all instructions. 402 // @todo: Move to the FU pool used in the current full cpu. 403 404 int fu_usage = 0; 405 bool fetch_redirect = false; 406 407 // Execute/writeback any instructions that are available. 408 for (int inst_num = 0; 409 fu_usage < executeWidth && /* Haven't exceeded available FU's. */ 410 inst_num < issueWidth && 411 fromIssue->insts[inst_num]; 412 ++inst_num) { 413 414 DPRINTF(IEW, "IEW: Execute: Executing instructions from IQ.\n"); 415 416 // Get instruction from issue's queue. 417 DynInstPtr inst = fromIssue->insts[inst_num]; 418 419 DPRINTF(IEW, "IEW: Execute: Processing PC %#x.\n", inst->readPC()); 420 421 // Check if the instruction is squashed; if so then skip it 422 // and don't count it towards the FU usage. 423 if (inst->isSquashed()) { 424 DPRINTF(IEW, "IEW: Execute: Instruction was squashed.\n"); 425 426 // Consider this instruction executed so that commit can go 427 // ahead and retire the instruction. 428 inst->setExecuted(); 429 430 toCommit->insts[inst_num] = inst; 431 432 ++iewExecSquashedInsts; 433 434 continue; 435 } 436 437 inst->setExecuted(); 438 439 // If an instruction is executed, then count it towards FU usage. 440 ++fu_usage; 441 442 // Execute instruction. 443 // Note that if the instruction faults, it will be handled 444 // at the commit stage. 445 if (inst->isMemRef()) { 446 DPRINTF(IEW, "IEW: Execute: Calculating address for memory " 447 "reference.\n"); 448 449 // Tell the LDSTQ to execute this instruction (if it is a load). 450 if (inst->isLoad()) { 451 ldstQueue.executeLoad(inst); 452 453 ++iewExecLoadInsts; 454 } else if (inst->isStore()) { 455 ldstQueue.executeStore(); 456 457 ++iewExecStoreInsts; 458 } else { 459 panic("IEW: Unexpected memory type!\n"); 460 } 461 462 } else { 463 inst->execute(); 464 465 ++iewExecutedInsts; 466 } 467 468 // First check the time slot that this instruction will write 469 // to. If there are free write ports at the time, then go ahead 470 // and write the instruction to that time. If there are not, 471 // keep looking back to see where's the first time there's a 472 // free slot. What happens if you run out of free spaces? 473 // For now naively assume that all instructions take one cycle. 474 // Otherwise would have to look into the time buffer based on the 475 // latency of the instruction. 476 477 // Add finished instruction to queue to commit. 478 toCommit->insts[inst_num] = inst; 479 480 // Check if branch was correct. This check happens after the 481 // instruction is added to the queue because even if the branch 482 // is mispredicted, the branch instruction itself is still valid. 483 // Only handle this if there hasn't already been something that 484 // redirects fetch in this group of instructions. 485 if (!fetch_redirect) { 486 if (inst->mispredicted()) { 487 fetch_redirect = true; 488 489 DPRINTF(IEW, "IEW: Execute: Branch mispredict detected.\n"); 490 DPRINTF(IEW, "IEW: Execute: Redirecting fetch to PC: %#x.\n", 491 inst->nextPC); 492 493 // If incorrect, then signal the ROB that it must be squashed. 494 squashDueToBranch(inst); 495 496 if (inst->predTaken()) { 497 predictedTakenIncorrect++; 498 } 499 } else if (ldstQueue.violation()) { 500 fetch_redirect = true; 501 502 // Get the DynInst that caused the violation. 503 DynInstPtr violator = ldstQueue.getMemDepViolator(); 504 505 DPRINTF(IEW, "IEW: LDSTQ detected a violation. Violator PC: " 506 "%#x, inst PC: %#x. Addr is: %#x.\n", 507 violator->readPC(), inst->readPC(), inst->physEffAddr); 508 509 // Tell the instruction queue that a violation has occured. 510 instQueue.violation(inst, violator); 511 512 // Squash. 513 squashDueToMem(inst); 514 515 ++memOrderViolationEvents; 516 } 517 } 518 } 519} 520 521template<class Impl, class IQ> 522void 523SimpleIEW<Impl, IQ>::tick() 524{ 525 // Considering putting all the state-determining stuff in this section. 526 527 // Try to fill up issue queue with as many instructions as bandwidth 528 // allows. 529 // Decode should try to execute as many instructions as its bandwidth 530 // will allow, as long as it is not currently blocked. 531 532 // Check if the stage is in a running status. 533 if (_status != Blocked && _status != Squashing) { 534 DPRINTF(IEW, "IEW: Status is not blocked, attempting to run " 535 "stage.\n"); 536 iew(); 537 538 // If it's currently unblocking, check to see if it should switch 539 // to running. 540 if (_status == Unblocking) { 541 unblock(); 542 543 ++iewUnblockCycles; 544 } 545 } else if (_status == Squashing) { 546 547 DPRINTF(IEW, "IEW: Still squashing.\n"); 548 549 // Check if stage should remain squashing. Stop squashing if the 550 // squash signal clears. 551 if (!fromCommit->commitInfo.squash && 552 !fromCommit->commitInfo.robSquashing) { 553 DPRINTF(IEW, "IEW: Done squashing, changing status to " 554 "running.\n"); 555 556 _status = Running; 557 instQueue.stopSquash(); 558 } else { 559 instQueue.doSquash(); 560 } 561 562 ++iewSquashCycles; 563 564 // Also should advance its own time buffers if the stage ran. 565 // Not sure about this... 566// issueToExecQueue.advance(); 567 } else if (_status == Blocked) { 568 // Continue to tell previous stage to stall. 569 toRename->iewInfo.stall = true; 570 571 // Check if possible stall conditions have cleared. 572 if (!fromCommit->commitInfo.stall && 573 !instQueue.isFull()) { 574 DPRINTF(IEW, "IEW: Stall signals cleared, going to unblock.\n"); 575 _status = Unblocking; 576 } 577 578 // If there's still instructions coming from rename, continue to 579 // put them on the skid buffer. 580 if (fromRename->size == 0) { 581 block(); 582 } 583 584 if (fromCommit->commitInfo.squash || 585 fromCommit->commitInfo.robSquashing) { 586 squash(); 587 } 588 589 ++iewBlockCycles; 590 } 591 592 // @todo: Maybe put these at the beginning, so if it's idle it can 593 // return early. 594 // Write back number of free IQ entries here. 595 toRename->iewInfo.freeIQEntries = instQueue.numFreeEntries(); 596 597 // Check the committed load/store signals to see if there's a load 598 // or store to commit. Also check if it's being told to execute a 599 // nonspeculative instruction. 600 if (fromCommit->commitInfo.commitIsStore) { 601 ldstQueue.commitStores(fromCommit->commitInfo.doneSeqNum); 602 } else if (fromCommit->commitInfo.commitIsLoad) { 603 ldstQueue.commitLoads(fromCommit->commitInfo.doneSeqNum); 604 } 605 606 if (fromCommit->commitInfo.nonSpecSeqNum != 0) { 607 instQueue.scheduleNonSpec(fromCommit->commitInfo.nonSpecSeqNum); 608 } 609 610 DPRINTF(IEW, "IEW: IQ has %i free entries.\n", 611 instQueue.numFreeEntries()); 612} 613 614template<class Impl, class IQ> 615void 616SimpleIEW<Impl, IQ>::iew() 617{ 618 // Might want to put all state checks in the tick() function. 619 // Check if being told to stall from commit. 620 if (fromCommit->commitInfo.stall) { 621 block(); 622 return; 623 } else if (fromCommit->commitInfo.squash || 624 fromCommit->commitInfo.robSquashing) { 625 // Also check if commit is telling this stage to squash. 626 squash(); 627 return; 628 } 629 630 dispatchInsts(); 631 632 // Have the instruction queue try to schedule any ready instructions. 633 instQueue.scheduleReadyInsts(); 634 635 executeInsts(); 636 637 // Loop through the head of the time buffer and wake any dependents. 638 // These instructions are about to write back. In the simple model 639 // this loop can really happen within the previous loop, but when 640 // instructions have actual latencies, this loop must be separate. 641 // Also mark scoreboard that this instruction is finally complete. 642 // Either have IEW have direct access to rename map, or have this as 643 // part of backwards communication. 644 for (int inst_num = 0; inst_num < issueWidth && 645 toCommit->insts[inst_num]; inst_num++) 646 { 647 DynInstPtr inst = toCommit->insts[inst_num]; 648 649 DPRINTF(IEW, "IEW: Sending instructions to commit, PC %#x.\n", 650 inst->readPC()); 651 652 if(!inst->isSquashed()) { 653 instQueue.wakeDependents(inst); 654 655 for (int i = 0; i < inst->numDestRegs(); i++) 656 { 657 renameMap->markAsReady(inst->renamedDestRegIdx(i)); 658 } 659 } 660 } 661 662 // Also should advance its own time buffers if the stage ran. 663 // Not the best place for it, but this works (hopefully). 664 issueToExecQueue.advance(); 665} 666