Merge zizzer:/bk/m5 into zeep.eecs.umich.edu:/z/saidi/work/m5-clean
[gem5.git] / cpu / o3 / iew_impl.hh
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
39 template<class Impl>
40 SimpleIEW<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
47 template<class Impl>
48 void
49 SimpleIEW<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
60 template<class Impl>
61 const char *
62 SimpleIEW<Impl>::WritebackEvent::description()
63 {
64 return "LSQ writeback event";
65 }
66
67 template<class Impl>
68 SimpleIEW<Impl>::SimpleIEW(Params &params)
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
95 template <class Impl>
96 void
97 SimpleIEW<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
168 template<class Impl>
169 void
170 SimpleIEW<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
179 template<class Impl>
180 void
181 SimpleIEW<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
196 template<class Impl>
197 void
198 SimpleIEW<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
207 template<class Impl>
208 void
209 SimpleIEW<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
218 template<class Impl>
219 void
220 SimpleIEW<Impl>::setRenameMap(RenameMap *rm_ptr)
221 {
222 DPRINTF(IEW, "IEW: Setting rename map pointer.\n");
223 renameMap = rm_ptr;
224 }
225
226 template<class Impl>
227 void
228 SimpleIEW<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
240 template<class Impl>
241 void
242 SimpleIEW<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(MachInst));
260 }
261
262 template<class Impl>
263 void
264 SimpleIEW<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
279 template<class Impl>
280 void
281 SimpleIEW<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
296 template<class Impl>
297 inline void
298 SimpleIEW<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
318 template<class Impl>
319 void
320 SimpleIEW<Impl>::wakeDependents(DynInstPtr &inst)
321 {
322 instQueue.wakeDependents(inst);
323 }
324
325
326 template<class Impl>
327 void
328 SimpleIEW<Impl>::instToCommit(DynInstPtr &inst)
329 {
330
331 }
332
333 template <class Impl>
334 void
335 SimpleIEW<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
435 template <class Impl>
436 void
437 SimpleIEW<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
584 template<class Impl>
585 void
586 SimpleIEW<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
676 template<class Impl>
677 void
678 SimpleIEW<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 #ifndef FULL_SYSTEM
730 template<class Impl>
731 void
732 SimpleIEW<Impl>::lsqWriteback()
733 {
734 ldstQueue.writebackAllInsts();
735 }
736 #endif