2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
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.
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.
31 #include "config/full_system.hh"
32 #include "cpu/o3/rename.hh"
35 SimpleRename<Impl>::SimpleRename(Params ¶ms)
36 : iewToRenameDelay(params.iewToRenameDelay),
37 decodeToRenameDelay(params.decodeToRenameDelay),
38 commitToRenameDelay(params.commitToRenameDelay),
39 renameWidth(params.renameWidth),
40 commitWidth(params.commitWidth),
48 SimpleRename<Impl>::regStats()
51 .name(name() + ".renameSquashCycles")
52 .desc("Number of cycles rename is squashing")
53 .prereq(renameSquashCycles);
55 .name(name() + ".renameIdleCycles")
56 .desc("Number of cycles rename is idle")
57 .prereq(renameIdleCycles);
59 .name(name() + ".renameBlockCycles")
60 .desc("Number of cycles rename is blocking")
61 .prereq(renameBlockCycles);
63 .name(name() + ".renameUnblockCycles")
64 .desc("Number of cycles rename is unblocking")
65 .prereq(renameUnblockCycles);
67 .name(name() + ".renameRenamedInsts")
68 .desc("Number of instructions processed by rename")
69 .prereq(renameRenamedInsts);
71 .name(name() + ".renameSquashedInsts")
72 .desc("Number of squashed instructions processed by rename")
73 .prereq(renameSquashedInsts);
75 .name(name() + ".renameROBFullEvents")
76 .desc("Number of times rename has considered the ROB 'full'")
77 .prereq(renameROBFullEvents);
79 .name(name() + ".renameIQFullEvents")
80 .desc("Number of times rename has considered the IQ 'full'")
81 .prereq(renameIQFullEvents);
82 renameFullRegistersEvents
83 .name(name() + ".renameFullRegisterEvents")
84 .desc("Number of times there has been no free registers")
85 .prereq(renameFullRegistersEvents);
87 .name(name() + ".renameRenamedOperands")
88 .desc("Number of destination operands rename has renamed")
89 .prereq(renameRenamedOperands);
91 .name(name() + ".renameRenameLookups")
92 .desc("Number of register rename lookups that rename has made")
93 .prereq(renameRenameLookups);
95 .name(name() + ".renameHBPlaceHolders")
96 .desc("Number of place holders added to the history buffer")
97 .prereq(renameHBPlaceHolders);
99 .name(name() + ".renameCommittedMaps")
100 .desc("Number of HB maps that are committed")
101 .prereq(renameCommittedMaps);
103 .name(name() + ".renameUndoneMaps")
104 .desc("Number of HB maps that are undone due to squashing")
105 .prereq(renameUndoneMaps);
106 renameValidUndoneMaps
107 .name(name() + ".renameValidUndoneMaps")
108 .desc("Number of HB maps that are undone, and are not place holders")
109 .prereq(renameValidUndoneMaps);
112 template <class Impl>
114 SimpleRename<Impl>::setCPU(FullCPU *cpu_ptr)
116 DPRINTF(Rename, "Rename: Setting CPU pointer.\n");
120 template <class Impl>
122 SimpleRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
124 DPRINTF(Rename, "Rename: Setting time buffer pointer.\n");
127 // Setup wire to read information from time buffer, from IEW stage.
128 fromIEW = timeBuffer->getWire(-iewToRenameDelay);
130 // Setup wire to read infromation from time buffer, from commit stage.
131 fromCommit = timeBuffer->getWire(-commitToRenameDelay);
133 // Setup wire to write information to previous stages.
134 toDecode = timeBuffer->getWire(0);
137 template <class Impl>
139 SimpleRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
141 DPRINTF(Rename, "Rename: Setting rename queue pointer.\n");
142 renameQueue = rq_ptr;
144 // Setup wire to write information to future stages.
145 toIEW = renameQueue->getWire(0);
148 template <class Impl>
150 SimpleRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr)
152 DPRINTF(Rename, "Rename: Setting decode queue pointer.\n");
153 decodeQueue = dq_ptr;
155 // Setup wire to get information from decode.
156 fromDecode = decodeQueue->getWire(-decodeToRenameDelay);
159 template <class Impl>
161 SimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr)
163 DPRINTF(Rename, "Rename: Setting rename map pointer.\n");
167 template <class Impl>
169 SimpleRename<Impl>::setFreeList(FreeList *fl_ptr)
171 DPRINTF(Rename, "Rename: Setting free list pointer.\n");
175 template <class Impl>
177 SimpleRename<Impl>::dumpHistory()
179 typename list<RenameHistory>::iterator buf_it = historyBuffer.begin();
181 while (buf_it != historyBuffer.end())
183 cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "
184 "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,
185 (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);
191 template <class Impl>
193 SimpleRename<Impl>::block()
195 DPRINTF(Rename, "Rename: Blocking.\n");
196 // Set status to Blocked.
199 // Add the current inputs onto the skid buffer, so they can be
200 // reprocessed when this stage unblocks.
201 skidBuffer.push(*fromDecode);
203 // Note that this stage only signals previous stages to stall when
204 // it is the cause of the stall originates at this stage. Otherwise
205 // the previous stages are expected to check all possible stall signals.
208 template <class Impl>
210 SimpleRename<Impl>::unblock()
212 DPRINTF(Rename, "Rename: Read instructions out of skid buffer this "
214 // Remove the now processed instructions from the skid buffer.
217 // If there's still information in the skid buffer, then
218 // continue to tell previous stages to stall. They will be
219 // able to restart once the skid buffer is empty.
220 if (!skidBuffer.empty()) {
221 toDecode->renameInfo.stall = true;
223 DPRINTF(Rename, "Rename: Done unblocking.\n");
228 template <class Impl>
230 SimpleRename<Impl>::doSquash()
232 typename list<RenameHistory>::iterator hb_it = historyBuffer.begin();
234 InstSeqNum squashed_seq_num = fromCommit->commitInfo.doneSeqNum;
237 assert(!historyBuffer.empty());
239 // After a syscall squashes everything, the history buffer may be empty
240 // but the ROB may still be squashing instructions.
241 if (historyBuffer.empty()) {
244 #endif // FULL_SYSTEM
246 // Go through the most recent instructions, undoing the mappings
247 // they did and freeing up the registers.
248 while ((*hb_it).instSeqNum > squashed_seq_num)
250 assert(hb_it != historyBuffer.end());
252 DPRINTF(Rename, "Rename: Removing history entry with sequence "
253 "number %i.\n", (*hb_it).instSeqNum);
255 // If it's not simply a place holder, then add the registers.
256 if (!(*hb_it).placeHolder) {
257 // Tell the rename map to set the architected register to the
258 // previous physical register that it was renamed to.
259 renameMap->setEntry(hb_it->archReg, hb_it->prevPhysReg);
261 // Put the renamed physical register back on the free list.
262 freeList->addReg(hb_it->newPhysReg);
264 ++renameValidUndoneMaps;
267 historyBuffer.erase(hb_it++);
273 template <class Impl>
275 SimpleRename<Impl>::squash()
277 DPRINTF(Rename, "Rename: Squashing instructions.\n");
278 // Set the status to Squashing.
283 // Clear the skid buffer in case it has any data in it.
284 while (!skidBuffer.empty())
294 SimpleRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num)
296 DPRINTF(Rename, "Rename: Removing a committed instruction from the "
297 "history buffer, until sequence number %lli.\n", inst_seq_num);
298 typename list<RenameHistory>::iterator hb_it = historyBuffer.end();
302 if (hb_it->instSeqNum > inst_seq_num) {
303 DPRINTF(Rename, "Rename: Old sequence number encountered. Ensure "
304 "that a syscall happened recently.\n");
308 while ((*hb_it).instSeqNum != inst_seq_num)
310 // Make sure we haven't gone off the end of the list.
311 assert(hb_it != historyBuffer.end());
313 // In theory instructions at the end of the history buffer
314 // should be older than the instruction being removed, which
315 // means they will have a lower sequence number. Also the
316 // instruction being removed from the history really should
317 // be the last instruction in the list, as it is the instruction
318 // that was just committed that is being removed.
319 assert(hb_it->instSeqNum < inst_seq_num);
320 DPRINTF(Rename, "Rename: Freeing up older rename of reg %i, sequence"
322 (*hb_it).prevPhysReg, (*hb_it).instSeqNum);
324 if (!(*hb_it).placeHolder) {
325 freeList->addReg((*hb_it).prevPhysReg);
326 ++renameCommittedMaps;
329 historyBuffer.erase(hb_it--);
332 // Finally free up the previous register of the finished instruction
334 if (!(*hb_it).placeHolder) {
335 freeList->addReg(hb_it->prevPhysReg);
336 ++renameCommittedMaps;
339 historyBuffer.erase(hb_it);
342 template <class Impl>
344 SimpleRename<Impl>::renameSrcRegs(DynInstPtr &inst)
346 unsigned num_src_regs = inst->numSrcRegs();
348 // Get the architectual register numbers from the source and
349 // destination operands, and redirect them to the right register.
350 // Will need to mark dependencies though.
351 for (int src_idx = 0; src_idx < num_src_regs; src_idx++)
353 RegIndex src_reg = inst->srcRegIdx(src_idx);
355 // Look up the source registers to get the phys. register they've
356 // been renamed to, and set the sources to those registers.
357 PhysRegIndex renamed_reg = renameMap->lookup(src_reg);
359 DPRINTF(Rename, "Rename: Looking up arch reg %i, got "
360 "physical reg %i.\n", (int)src_reg, (int)renamed_reg);
362 inst->renameSrcReg(src_idx, renamed_reg);
364 // Either incorporate it into the info passed back,
365 // or make another function call to see if that register is
367 if (renameMap->isReady(renamed_reg)) {
368 DPRINTF(Rename, "Rename: Register is ready.\n");
370 inst->markSrcRegReady(src_idx);
373 ++renameRenameLookups;
377 template <class Impl>
379 SimpleRename<Impl>::renameDestRegs(DynInstPtr &inst)
381 typename SimpleRenameMap::RenameInfo rename_result;
383 unsigned num_dest_regs = inst->numDestRegs();
385 // If it's an instruction with no destination registers, then put
386 // a placeholder within the history buffer. It might be better
387 // to not put it in the history buffer at all (other than branches,
388 // which always need at least a place holder), and differentiate
389 // between instructions with and without destination registers
390 // when getting from commit the instructions that committed.
391 if (num_dest_regs == 0) {
392 RenameHistory hb_entry(inst->seqNum);
394 historyBuffer.push_front(hb_entry);
396 DPRINTF(Rename, "Rename: Adding placeholder instruction to "
397 "history buffer, sequence number %lli.\n",
400 ++renameHBPlaceHolders;
403 // Rename the destination registers.
404 for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++)
406 RegIndex dest_reg = inst->destRegIdx(dest_idx);
408 // Get the physical register that the destination will be
410 rename_result = renameMap->rename(dest_reg);
412 DPRINTF(Rename, "Rename: Renaming arch reg %i to physical "
413 "reg %i.\n", (int)dest_reg,
414 (int)rename_result.first);
416 // Record the rename information so that a history can be kept.
417 RenameHistory hb_entry(inst->seqNum, dest_reg,
419 rename_result.second);
421 historyBuffer.push_front(hb_entry);
423 DPRINTF(Rename, "Rename: Adding instruction to history buffer, "
424 "sequence number %lli.\n",
425 (*historyBuffer.begin()).instSeqNum);
427 // Tell the instruction to rename the appropriate destination
428 // register (dest_idx) to the new physical register
429 // (rename_result.first), and record the previous physical
430 // register that the same logical register was renamed to
431 // (rename_result.second).
432 inst->renameDestReg(dest_idx,
434 rename_result.second);
436 ++renameRenamedOperands;
441 template <class Impl>
443 SimpleRename<Impl>::calcFreeROBEntries()
445 return fromCommit->commitInfo.freeROBEntries -
446 renameWidth * iewToRenameDelay;
449 template <class Impl>
451 SimpleRename<Impl>::calcFreeIQEntries()
453 return fromIEW->iewInfo.freeIQEntries - renameWidth * iewToRenameDelay;
458 SimpleRename<Impl>::tick()
460 // Rename will need to try to rename as many instructions as it
461 // has bandwidth, unless it is blocked.
463 // Check if _status is BarrierStall. If so, then check if the number
464 // of free ROB entries is equal to the number of total ROB entries.
465 // Once equal then wake this stage up. Set status to unblocking maybe.
467 if (_status != Blocked && _status != Squashing) {
468 DPRINTF(Rename, "Rename: Status is not blocked, will attempt to "
470 // Make sure that the skid buffer has something in it if the
471 // status is unblocking.
472 assert(_status == Unblocking ? !skidBuffer.empty() : 1);
476 // If the status was unblocking, then instructions from the skid
477 // buffer were used. Remove those instructions and handle
478 // the rest of unblocking.
479 if (_status == Unblocking) {
480 ++renameUnblockCycles;
482 if (fromDecode->size > 0) {
483 // Add the current inputs onto the skid buffer, so they can be
484 // reprocessed when this stage unblocks.
485 skidBuffer.push(*fromDecode);
490 } else if (_status == Blocked) {
493 // If stage is blocked and still receiving valid instructions,
494 // make sure to store them in the skid buffer.
495 if (fromDecode->size > 0) {
499 // Continue to tell previous stage to stall.
500 toDecode->renameInfo.stall = true;
503 if (!fromIEW->iewInfo.stall &&
504 !fromCommit->commitInfo.stall &&
505 calcFreeROBEntries() > 0 &&
506 calcFreeIQEntries() > 0 &&
507 renameMap->numFreeEntries() > 0) {
509 // Need to be sure to check all blocking conditions above.
510 // If they have cleared, then start unblocking.
511 DPRINTF(Rename, "Rename: Stall signals cleared, going to "
513 _status = Unblocking;
515 // Continue to tell previous stage to block until this stage
516 // is done unblocking.
517 toDecode->renameInfo.stall = true;
519 // Otherwise no conditions have changed. Tell previous
520 // stage to continue blocking.
521 toDecode->renameInfo.stall = true;
524 if (fromCommit->commitInfo.squash ||
525 fromCommit->commitInfo.robSquashing) {
529 } else if (_status == Squashing) {
530 ++renameSquashCycles;
532 if (fromCommit->commitInfo.squash) {
534 } else if (!fromCommit->commitInfo.squash &&
535 !fromCommit->commitInfo.robSquashing) {
537 DPRINTF(Rename, "Rename: Done squashing, going to running.\n");
545 // Ugly code, revamp all of the tick() functions eventually.
546 if (fromCommit->commitInfo.doneSeqNum != 0 && _status != Squashing) {
548 if (!fromCommit->commitInfo.squash) {
549 removeFromHistory(fromCommit->commitInfo.doneSeqNum);
552 removeFromHistory(fromCommit->commitInfo.doneSeqNum);
560 SimpleRename<Impl>::rename()
562 // Check if any of the stages ahead of rename are telling rename
563 // to squash. The squash() function will also take care of fixing up
564 // the rename map and the free list.
565 if (fromCommit->commitInfo.squash ||
566 fromCommit->commitInfo.robSquashing) {
567 DPRINTF(Rename, "Rename: Receiving signal from Commit to squash.\n");
572 // Check if time buffer is telling this stage to stall.
573 if (fromIEW->iewInfo.stall ||
574 fromCommit->commitInfo.stall) {
575 DPRINTF(Rename, "Rename: Receiving signal from IEW/Commit to "
581 // Check if the current status is squashing. If so, set its status
582 // to running and resume execution the next cycle.
583 if (_status == Squashing) {
584 DPRINTF(Rename, "Rename: Done squashing.\n");
589 // Check the decode queue to see if instructions are available.
590 // If there are no available instructions to rename, then do nothing.
591 // Or, if the stage is currently unblocking, then go ahead and run it.
592 if (fromDecode->size == 0 && _status != Unblocking) {
593 DPRINTF(Rename, "Rename: Nothing to do, breaking out early.\n");
594 // Should I change status to idle?
598 ////////////////////////////////////
599 // Actual rename part.
600 ////////////////////////////////////
604 // If we're unblocking, then we may be in the middle of an instruction
605 // group. Subtract off numInst to get the proper number of instructions
607 int insts_available = _status == Unblocking ?
608 skidBuffer.front().size - numInst :
611 bool block_this_cycle = false;
613 // Will have to do a different calculation for the number of free
614 // entries. Number of free entries recorded on this cycle -
615 // renameWidth * renameToDecodeDelay
616 int free_rob_entries = calcFreeROBEntries();
617 int free_iq_entries = calcFreeIQEntries();
618 int min_iq_rob = min(free_rob_entries, free_iq_entries);
620 unsigned to_iew_index = 0;
622 // Check if there's any space left.
623 if (min_iq_rob <= 0) {
624 DPRINTF(Rename, "Rename: Blocking due to no free ROB or IQ "
626 "Rename: ROB has %d free entries.\n"
627 "Rename: IQ has %d free entries.\n",
631 // Tell previous stage to stall.
632 toDecode->renameInfo.stall = true;
634 if (free_rob_entries <= 0) {
635 ++renameROBFullEvents;
637 ++renameIQFullEvents;
641 } else if (min_iq_rob < insts_available) {
642 DPRINTF(Rename, "Rename: Will have to block this cycle. Only "
643 "%i insts can be renamed due to IQ/ROB limits.\n",
646 insts_available = min_iq_rob;
648 block_this_cycle = true;
650 if (free_rob_entries < free_iq_entries) {
651 ++renameROBFullEvents;
653 ++renameIQFullEvents;
657 while (insts_available > 0) {
658 DPRINTF(Rename, "Rename: Sending instructions to iew.\n");
660 // Get the next instruction either from the skid buffer or the
662 inst = _status == Unblocking ? skidBuffer.front().insts[numInst] :
663 fromDecode->insts[numInst];
665 if (inst->isSquashed()) {
666 DPRINTF(Rename, "Rename: instruction %i with PC %#x is "
667 "squashed, skipping.\n",
668 inst->seqNum, inst->readPC());
670 // Go to the next instruction.
673 ++renameSquashedInsts;
675 // Decrement how many instructions are available.
681 DPRINTF(Rename, "Rename: Processing instruction %i with PC %#x.\n",
682 inst->seqNum, inst->readPC());
684 // If it's a trap instruction, then it needs to wait here within
685 // rename until the ROB is empty. Needs a way to detect that the
686 // ROB is empty. Maybe an event?
687 // Would be nice if it could be avoided putting this into a
688 // specific stage and instead just put it into the AlphaFullCPU.
689 // Might not really be feasible though...
691 if (inst->isSerializing()) {
692 panic("Rename: Serializing instruction encountered.\n");
693 DPRINTF(Rename, "Rename: Serializing instruction "
696 // Change status over to BarrierStall so that other stages know
697 // what this is blocked on.
698 _status = BarrierStall;
700 block_this_cycle = true;
705 // Check here to make sure there are enough destination registers
706 // to rename to. Otherwise block.
707 if (renameMap->numFreeEntries() < inst->numDestRegs())
709 DPRINTF(Rename, "Rename: Blocking due to lack of free "
710 "physical registers to rename to.\n");
711 // Need some sort of event based on a register being freed.
713 block_this_cycle = true;
715 ++renameFullRegistersEvents;
722 renameDestRegs(inst);
724 // Put instruction in rename queue.
725 toIEW->insts[to_iew_index] = inst;
728 // Decrease the number of free ROB and IQ entries.
732 // Increment which instruction we're on.
736 ++renameRenamedInsts;
738 // Decrement how many instructions are available.
742 // Check if there's any instructions left that haven't yet been renamed.
744 if (block_this_cycle) {
747 toDecode->renameInfo.stall = true;
749 // If we had a successful rename and didn't have to exit early, then
750 // reset numInst so it will refer to the correct instruction on next