iew_impl.hh revision 2107
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29// @todo: Fix the instantaneous communication among all the stages within 30// iew. There's a clear delay between issue and execute, yet backwards 31// communication happens simultaneously. 32// Update the statuses for each stage. 33 34#include <queue> 35 36#include "base/timebuf.hh" 37#include "cpu/o3/iew.hh" 38 39template<class Impl> 40SimpleIEW<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, 41 SimpleIEW<Impl> *_iew) 42 : Event(&mainEventQueue, CPU_Tick_Pri), inst(_inst), iewStage(_iew) 43{ 44 this->setFlags(Event::AutoDelete); 45} 46 47template<class Impl> 48void 49SimpleIEW<Impl>::WritebackEvent::process() 50{ 51 DPRINTF(IEW, "IEW: WRITEBACK EVENT!!!!\n"); 52 53 // Need to insert instruction into queue to commit 54 iewStage->instToCommit(inst); 55 // Need to execute second half of the instruction, do actual writing to 56 // registers and such 57 inst->execute(); 58} 59 60template<class Impl> 61const char * 62SimpleIEW<Impl>::WritebackEvent::description() 63{ 64 return "LSQ writeback event"; 65} 66 67template<class Impl> 68SimpleIEW<Impl>::SimpleIEW(Params ¶ms) 69 : // Just make this time buffer really big for now 70 issueToExecQueue(5, 5), 71 instQueue(params), 72 ldstQueue(params), 73 commitToIEWDelay(params.commitToIEWDelay), 74 renameToIEWDelay(params.renameToIEWDelay), 75 issueToExecuteDelay(params.issueToExecuteDelay), 76 issueReadWidth(params.issueWidth), 77 issueWidth(params.issueWidth), 78 executeWidth(params.executeWidth) 79{ 80 DPRINTF(IEW, "IEW: executeIntWidth: %i.\n", params.executeIntWidth); 81 _status = Idle; 82 _issueStatus = Idle; 83 _exeStatus = Idle; 84 _wbStatus = Idle; 85 86 // Setup wire to read instructions coming from issue. 87 fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay); 88 89 // Instruction queue needs the queue between issue and execute. 90 instQueue.setIssueToExecuteQueue(&issueToExecQueue); 91 92 ldstQueue.setIEW(this); 93} 94 95template <class Impl> 96void 97SimpleIEW<Impl>::regStats() 98{ 99 instQueue.regStats(); 100 101 iewIdleCycles 102 .name(name() + ".iewIdleCycles") 103 .desc("Number of cycles IEW is idle"); 104 105 iewSquashCycles 106 .name(name() + ".iewSquashCycles") 107 .desc("Number of cycles IEW is squashing"); 108 109 iewBlockCycles 110 .name(name() + ".iewBlockCycles") 111 .desc("Number of cycles IEW is blocking"); 112 113 iewUnblockCycles 114 .name(name() + ".iewUnblockCycles") 115 .desc("Number of cycles IEW is unblocking"); 116 117// iewWBInsts; 118 119 iewDispatchedInsts 120 .name(name() + ".iewDispatchedInsts") 121 .desc("Number of instructions dispatched to IQ"); 122 123 iewDispSquashedInsts 124 .name(name() + ".iewDispSquashedInsts") 125 .desc("Number of squashed instructions skipped by dispatch"); 126 127 iewDispLoadInsts 128 .name(name() + ".iewDispLoadInsts") 129 .desc("Number of dispatched load instructions"); 130 131 iewDispStoreInsts 132 .name(name() + ".iewDispStoreInsts") 133 .desc("Number of dispatched store instructions"); 134 135 iewDispNonSpecInsts 136 .name(name() + ".iewDispNonSpecInsts") 137 .desc("Number of dispatched non-speculative instructions"); 138 139 iewIQFullEvents 140 .name(name() + ".iewIQFullEvents") 141 .desc("Number of times the IQ has become full, causing a stall"); 142 143 iewExecutedInsts 144 .name(name() + ".iewExecutedInsts") 145 .desc("Number of executed instructions"); 146 147 iewExecLoadInsts 148 .name(name() + ".iewExecLoadInsts") 149 .desc("Number of load instructions executed"); 150 151 iewExecStoreInsts 152 .name(name() + ".iewExecStoreInsts") 153 .desc("Number of store instructions executed"); 154 155 iewExecSquashedInsts 156 .name(name() + ".iewExecSquashedInsts") 157 .desc("Number of squashed instructions skipped in execute"); 158 159 memOrderViolationEvents 160 .name(name() + ".memOrderViolationEvents") 161 .desc("Number of memory order violations"); 162 163 predictedTakenIncorrect 164 .name(name() + ".predictedTakenIncorrect") 165 .desc("Number of branches that were predicted taken incorrectly"); 166} 167 168template<class Impl> 169void 170SimpleIEW<Impl>::setCPU(FullCPU *cpu_ptr) 171{ 172 DPRINTF(IEW, "IEW: Setting CPU pointer.\n"); 173 cpu = cpu_ptr; 174 175 instQueue.setCPU(cpu_ptr); 176 ldstQueue.setCPU(cpu_ptr); 177} 178 179template<class Impl> 180void 181SimpleIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr) 182{ 183 DPRINTF(IEW, "IEW: Setting time buffer pointer.\n"); 184 timeBuffer = tb_ptr; 185 186 // Setup wire to read information from time buffer, from commit. 187 fromCommit = timeBuffer->getWire(-commitToIEWDelay); 188 189 // Setup wire to write information back to previous stages. 190 toRename = timeBuffer->getWire(0); 191 192 // Instruction queue also needs main time buffer. 193 instQueue.setTimeBuffer(tb_ptr); 194} 195 196template<class Impl> 197void 198SimpleIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr) 199{ 200 DPRINTF(IEW, "IEW: Setting rename queue pointer.\n"); 201 renameQueue = rq_ptr; 202 203 // Setup wire to read information from rename queue. 204 fromRename = renameQueue->getWire(-renameToIEWDelay); 205} 206 207template<class Impl> 208void 209SimpleIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr) 210{ 211 DPRINTF(IEW, "IEW: Setting IEW queue pointer.\n"); 212 iewQueue = iq_ptr; 213 214 // Setup wire to write instructions to commit. 215 toCommit = iewQueue->getWire(0); 216} 217 218template<class Impl> 219void 220SimpleIEW<Impl>::setRenameMap(RenameMap *rm_ptr) 221{ 222 DPRINTF(IEW, "IEW: Setting rename map pointer.\n"); 223 renameMap = rm_ptr; 224} 225 226template<class Impl> 227void 228SimpleIEW<Impl>::squash() 229{ 230 DPRINTF(IEW, "IEW: Squashing all instructions.\n"); 231 _status = Squashing; 232 233 // Tell the IQ to start squashing. 234 instQueue.squash(); 235 236 // Tell the LDSTQ to start squashing. 237 ldstQueue.squash(fromCommit->commitInfo.doneSeqNum); 238} 239 240template<class Impl> 241void 242SimpleIEW<Impl>::squashDueToBranch(DynInstPtr &inst) 243{ 244 DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n", 245 inst->PC); 246 // Perhaps leave the squashing up to the ROB stage to tell it when to 247 // squash? 248 _status = Squashing; 249 250 // Tell rename to squash through the time buffer. 251 toCommit->squash = true; 252 // Also send PC update information back to prior stages. 253 toCommit->squashedSeqNum = inst->seqNum; 254 toCommit->mispredPC = inst->readPC(); 255 toCommit->nextPC = inst->readNextPC(); 256 toCommit->branchMispredict = true; 257 // Prediction was incorrect, so send back inverse. 258 toCommit->branchTaken = inst->readNextPC() != 259 (inst->readPC() + sizeof(TheISA::MachInst)); 260} 261 262template<class Impl> 263void 264SimpleIEW<Impl>::squashDueToMem(DynInstPtr &inst) 265{ 266 DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n", 267 inst->PC); 268 // Perhaps leave the squashing up to the ROB stage to tell it when to 269 // squash? 270 _status = Squashing; 271 272 // Tell rename to squash through the time buffer. 273 toCommit->squash = true; 274 // Also send PC update information back to prior stages. 275 toCommit->squashedSeqNum = inst->seqNum; 276 toCommit->nextPC = inst->readNextPC(); 277} 278 279template<class Impl> 280void 281SimpleIEW<Impl>::block() 282{ 283 DPRINTF(IEW, "IEW: Blocking.\n"); 284 // Set the status to Blocked. 285 _status = Blocked; 286 287 // Add the current inputs to the skid buffer so they can be 288 // reprocessed when this stage unblocks. 289 skidBuffer.push(*fromRename); 290 291 // Note that this stage only signals previous stages to stall when 292 // it is the cause of the stall originates at this stage. Otherwise 293 // the previous stages are expected to check all possible stall signals. 294} 295 296template<class Impl> 297inline void 298SimpleIEW<Impl>::unblock() 299{ 300 // Check if there's information in the skid buffer. If there is, then 301 // set status to unblocking, otherwise set it directly to running. 302 DPRINTF(IEW, "IEW: Reading instructions out of the skid " 303 "buffer.\n"); 304 // Remove the now processed instructions from the skid buffer. 305 skidBuffer.pop(); 306 307 // If there's still information in the skid buffer, then 308 // continue to tell previous stages to stall. They will be 309 // able to restart once the skid buffer is empty. 310 if (!skidBuffer.empty()) { 311 toRename->iewInfo.stall = true; 312 } else { 313 DPRINTF(IEW, "IEW: Stage is done unblocking.\n"); 314 _status = Running; 315 } 316} 317 318template<class Impl> 319void 320SimpleIEW<Impl>::wakeDependents(DynInstPtr &inst) 321{ 322 instQueue.wakeDependents(inst); 323} 324 325 326template<class Impl> 327void 328SimpleIEW<Impl>::instToCommit(DynInstPtr &inst) 329{ 330 331} 332 333template <class Impl> 334void 335SimpleIEW<Impl>::dispatchInsts() 336{ 337 //////////////////////////////////////// 338 // DISPATCH/ISSUE stage 339 //////////////////////////////////////// 340 341 //Put into its own function? 342 //Add instructions to IQ if there are any instructions there 343 344 // Check if there are any instructions coming from rename, and we're. 345 // not squashing. 346 if (fromRename->size > 0) { 347 int insts_to_add = fromRename->size; 348 349 // Loop through the instructions, putting them in the instruction 350 // queue. 351 for (int inst_num = 0; inst_num < insts_to_add; ++inst_num) 352 { 353 DynInstPtr inst = fromRename->insts[inst_num]; 354 355 // Make sure there's a valid instruction there. 356 assert(inst); 357 358 DPRINTF(IEW, "IEW: Issue: Adding PC %#x to IQ.\n", 359 inst->readPC()); 360 361 // Be sure to mark these instructions as ready so that the 362 // commit stage can go ahead and execute them, and mark 363 // them as issued so the IQ doesn't reprocess them. 364 if (inst->isSquashed()) { 365 ++iewDispSquashedInsts; 366 continue; 367 } else if (instQueue.isFull()) { 368 DPRINTF(IEW, "IEW: Issue: IQ has become full.\n"); 369 // Call function to start blocking. 370 block(); 371 // Tell previous stage to stall. 372 toRename->iewInfo.stall = true; 373 374 ++iewIQFullEvents; 375 break; 376 } else if (inst->isLoad()) { 377 DPRINTF(IEW, "IEW: Issue: Memory instruction " 378 "encountered, adding to LDSTQ.\n"); 379 380 // Reserve a spot in the load store queue for this 381 // memory access. 382 ldstQueue.insertLoad(inst); 383 384 ++iewDispLoadInsts; 385 } else if (inst->isStore()) { 386 ldstQueue.insertStore(inst); 387 388 ++iewDispStoreInsts; 389 } else if (inst->isNonSpeculative()) { 390 DPRINTF(IEW, "IEW: Issue: Nonspeculative instruction " 391 "encountered, skipping.\n"); 392 393 // Same hack as with stores. 394 inst->setCanCommit(); 395 396 // Specificall insert it as nonspeculative. 397 instQueue.insertNonSpec(inst); 398 399 ++iewDispNonSpecInsts; 400 401 continue; 402 } else if (inst->isNop()) { 403 DPRINTF(IEW, "IEW: Issue: Nop instruction encountered " 404 ", skipping.\n"); 405 406 inst->setIssued(); 407 inst->setExecuted(); 408 inst->setCanCommit(); 409 410 instQueue.advanceTail(inst); 411 412 continue; 413 } else if (inst->isExecuted()) { 414 assert(0 && "Instruction shouldn't be executed.\n"); 415 DPRINTF(IEW, "IEW: Issue: Executed branch encountered, " 416 "skipping.\n"); 417 418 inst->setIssued(); 419 inst->setCanCommit(); 420 421 instQueue.advanceTail(inst); 422 423 continue; 424 } 425 426 // If the instruction queue is not full, then add the 427 // instruction. 428 instQueue.insert(fromRename->insts[inst_num]); 429 430 ++iewDispatchedInsts; 431 } 432 } 433} 434 435template <class Impl> 436void 437SimpleIEW<Impl>::executeInsts() 438{ 439 //////////////////////////////////////// 440 //EXECUTE/WRITEBACK stage 441 //////////////////////////////////////// 442 443 //Put into its own function? 444 //Similarly should probably have separate execution for int vs FP. 445 // Above comment is handled by the issue queue only issuing a valid 446 // mix of int/fp instructions. 447 //Actually okay to just have one execution, buuuuuut will need 448 //somewhere that defines the execution latency of all instructions. 449 // @todo: Move to the FU pool used in the current full cpu. 450 451 int fu_usage = 0; 452 bool fetch_redirect = false; 453 int inst_slot = 0; 454 int time_slot = 0; 455 456 // Execute/writeback any instructions that are available. 457 for (int inst_num = 0; 458 fu_usage < executeWidth && /* Haven't exceeded available FU's. */ 459 inst_num < issueWidth && 460 fromIssue->insts[inst_num]; 461 ++inst_num) { 462 463 DPRINTF(IEW, "IEW: Execute: Executing instructions from IQ.\n"); 464 465 // Get instruction from issue's queue. 466 DynInstPtr inst = fromIssue->insts[inst_num]; 467 468 DPRINTF(IEW, "IEW: Execute: Processing PC %#x.\n", inst->readPC()); 469 470 // Check if the instruction is squashed; if so then skip it 471 // and don't count it towards the FU usage. 472 if (inst->isSquashed()) { 473 DPRINTF(IEW, "IEW: Execute: Instruction was squashed.\n"); 474 475 // Consider this instruction executed so that commit can go 476 // ahead and retire the instruction. 477 inst->setExecuted(); 478 479 toCommit->insts[inst_num] = inst; 480 481 ++iewExecSquashedInsts; 482 483 continue; 484 } 485 486 inst->setExecuted(); 487 488 // If an instruction is executed, then count it towards FU usage. 489 ++fu_usage; 490 491 // Execute instruction. 492 // Note that if the instruction faults, it will be handled 493 // at the commit stage. 494 if (inst->isMemRef()) { 495 DPRINTF(IEW, "IEW: Execute: Calculating address for memory " 496 "reference.\n"); 497 498 // Tell the LDSTQ to execute this instruction (if it is a load). 499 if (inst->isLoad()) { 500 ldstQueue.executeLoad(inst); 501 502 ++iewExecLoadInsts; 503 } else if (inst->isStore()) { 504 ldstQueue.executeStore(inst); 505 506 ++iewExecStoreInsts; 507 } else { 508 panic("IEW: Unexpected memory type!\n"); 509 } 510 511 } else { 512 inst->execute(); 513 514 ++iewExecutedInsts; 515 } 516 517 // First check the time slot that this instruction will write 518 // to. If there are free write ports at the time, then go ahead 519 // and write the instruction to that time. If there are not, 520 // keep looking back to see where's the first time there's a 521 // free slot. What happens if you run out of free spaces? 522 // For now naively assume that all instructions take one cycle. 523 // Otherwise would have to look into the time buffer based on the 524 // latency of the instruction. 525 (*iewQueue)[time_slot].insts[inst_slot]; 526 while ((*iewQueue)[time_slot].insts[inst_slot]) { 527 if (inst_slot < issueWidth) { 528 ++inst_slot; 529 } else { 530 ++time_slot; 531 inst_slot = 0; 532 } 533 534 assert(time_slot < 5); 535 } 536 537 // May actually have to work this out, especially with loads and stores 538 539 // Add finished instruction to queue to commit. 540 (*iewQueue)[time_slot].insts[inst_slot] = inst; 541 (*iewQueue)[time_slot].size++; 542 543 // Check if branch was correct. This check happens after the 544 // instruction is added to the queue because even if the branch 545 // is mispredicted, the branch instruction itself is still valid. 546 // Only handle this if there hasn't already been something that 547 // redirects fetch in this group of instructions. 548 if (!fetch_redirect) { 549 if (inst->mispredicted()) { 550 fetch_redirect = true; 551 552 DPRINTF(IEW, "IEW: Execute: Branch mispredict detected.\n"); 553 DPRINTF(IEW, "IEW: Execute: Redirecting fetch to PC: %#x.\n", 554 inst->nextPC); 555 556 // If incorrect, then signal the ROB that it must be squashed. 557 squashDueToBranch(inst); 558 559 if (inst->predTaken()) { 560 predictedTakenIncorrect++; 561 } 562 } else if (ldstQueue.violation()) { 563 fetch_redirect = true; 564 565 // Get the DynInst that caused the violation. 566 DynInstPtr violator = ldstQueue.getMemDepViolator(); 567 568 DPRINTF(IEW, "IEW: LDSTQ detected a violation. Violator PC: " 569 "%#x, inst PC: %#x. Addr is: %#x.\n", 570 violator->readPC(), inst->readPC(), inst->physEffAddr); 571 572 // Tell the instruction queue that a violation has occured. 573 instQueue.violation(inst, violator); 574 575 // Squash. 576 squashDueToMem(inst); 577 578 ++memOrderViolationEvents; 579 } 580 } 581 } 582} 583 584template<class Impl> 585void 586SimpleIEW<Impl>::tick() 587{ 588 // Considering putting all the state-determining stuff in this section. 589 590 // Try to fill up issue queue with as many instructions as bandwidth 591 // allows. 592 // Decode should try to execute as many instructions as its bandwidth 593 // will allow, as long as it is not currently blocked. 594 595 // Check if the stage is in a running status. 596 if (_status != Blocked && _status != Squashing) { 597 DPRINTF(IEW, "IEW: Status is not blocked, attempting to run " 598 "stage.\n"); 599 iew(); 600 601 // If it's currently unblocking, check to see if it should switch 602 // to running. 603 if (_status == Unblocking) { 604 unblock(); 605 606 ++iewUnblockCycles; 607 } 608 } else if (_status == Squashing) { 609 610 DPRINTF(IEW, "IEW: Still squashing.\n"); 611 612 // Check if stage should remain squashing. Stop squashing if the 613 // squash signal clears. 614 if (!fromCommit->commitInfo.squash && 615 !fromCommit->commitInfo.robSquashing) { 616 DPRINTF(IEW, "IEW: Done squashing, changing status to " 617 "running.\n"); 618 619 _status = Running; 620 instQueue.stopSquash(); 621 } else { 622 instQueue.doSquash(); 623 } 624 625 ++iewSquashCycles; 626 } else if (_status == Blocked) { 627 // Continue to tell previous stage to stall. 628 toRename->iewInfo.stall = true; 629 630 // Check if possible stall conditions have cleared. 631 if (!fromCommit->commitInfo.stall && 632 !instQueue.isFull()) { 633 DPRINTF(IEW, "IEW: Stall signals cleared, going to unblock.\n"); 634 _status = Unblocking; 635 } 636 637 // If there's still instructions coming from rename, continue to 638 // put them on the skid buffer. 639 if (fromRename->size == 0) { 640 block(); 641 } 642 643 if (fromCommit->commitInfo.squash || 644 fromCommit->commitInfo.robSquashing) { 645 squash(); 646 } 647 648 ++iewBlockCycles; 649 } 650 651 // @todo: Maybe put these at the beginning, so if it's idle it can 652 // return early. 653 // Write back number of free IQ entries here. 654 toRename->iewInfo.freeIQEntries = instQueue.numFreeEntries(); 655 656 ldstQueue.writebackStores(); 657 658 // Check the committed load/store signals to see if there's a load 659 // or store to commit. Also check if it's being told to execute a 660 // nonspeculative instruction. 661 // This is pretty inefficient... 662 if (!fromCommit->commitInfo.squash && 663 !fromCommit->commitInfo.robSquashing) { 664 ldstQueue.commitStores(fromCommit->commitInfo.doneSeqNum); 665 ldstQueue.commitLoads(fromCommit->commitInfo.doneSeqNum); 666 } 667 668 if (fromCommit->commitInfo.nonSpecSeqNum != 0) { 669 instQueue.scheduleNonSpec(fromCommit->commitInfo.nonSpecSeqNum); 670 } 671 672 DPRINTF(IEW, "IEW: IQ has %i free entries.\n", 673 instQueue.numFreeEntries()); 674} 675 676template<class Impl> 677void 678SimpleIEW<Impl>::iew() 679{ 680 // Might want to put all state checks in the tick() function. 681 // Check if being told to stall from commit. 682 if (fromCommit->commitInfo.stall) { 683 block(); 684 return; 685 } else if (fromCommit->commitInfo.squash || 686 fromCommit->commitInfo.robSquashing) { 687 // Also check if commit is telling this stage to squash. 688 squash(); 689 return; 690 } 691 692 dispatchInsts(); 693 694 // Have the instruction queue try to schedule any ready instructions. 695 instQueue.scheduleReadyInsts(); 696 697 executeInsts(); 698 699 // Loop through the head of the time buffer and wake any dependents. 700 // These instructions are about to write back. In the simple model 701 // this loop can really happen within the previous loop, but when 702 // instructions have actual latencies, this loop must be separate. 703 // Also mark scoreboard that this instruction is finally complete. 704 // Either have IEW have direct access to rename map, or have this as 705 // part of backwards communication. 706 for (int inst_num = 0; inst_num < issueWidth && 707 toCommit->insts[inst_num]; inst_num++) 708 { 709 DynInstPtr inst = toCommit->insts[inst_num]; 710 711 DPRINTF(IEW, "IEW: Sending instructions to commit, PC %#x.\n", 712 inst->readPC()); 713 714 if(!inst->isSquashed()) { 715 instQueue.wakeDependents(inst); 716 717 for (int i = 0; i < inst->numDestRegs(); i++) 718 { 719 renameMap->markAsReady(inst->renamedDestRegIdx(i)); 720 } 721 } 722 } 723 724 // Also should advance its own time buffers if the stage ran. 725 // Not the best place for it, but this works (hopefully). 726 issueToExecQueue.advance(); 727} 728 729#if !FULL_SYSTEM 730template<class Impl> 731void 732SimpleIEW<Impl>::lsqWriteback() 733{ 734 ldstQueue.writebackAllInsts(); 735} 736#endif 737