summaryrefslogtreecommitdiff
path: root/src/cpu/o3/rename_impl.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3/rename_impl.hh')
-rw-r--r--src/cpu/o3/rename_impl.hh135
1 files changed, 69 insertions, 66 deletions
diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh
index 60a929551..6bfc7d952 100644
--- a/src/cpu/o3/rename_impl.hh
+++ b/src/cpu/o3/rename_impl.hh
@@ -871,18 +871,26 @@ DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
// Go through the most recent instructions, undoing the mappings
// they did and freeing up the registers.
while (!historyBuffer[tid].empty() &&
- (*hb_it).instSeqNum > squashed_seq_num) {
+ hb_it->instSeqNum > squashed_seq_num) {
assert(hb_it != historyBuffer[tid].end());
DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "
- "number %i.\n", tid, (*hb_it).instSeqNum);
-
- // Tell the rename map to set the architected register to the
- // previous physical register that it was renamed to.
- renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
-
- // Put the renamed physical register back on the free list.
- freeList->addReg(hb_it->newPhysReg);
+ "number %i.\n", tid, hb_it->instSeqNum);
+
+ // Undo the rename mapping only if it was really a change.
+ // Special regs that are not really renamed (like misc regs
+ // and the zero reg) can be recognized because the new mapping
+ // is the same as the old one. While it would be merely a
+ // waste of time to update the rename table, we definitely
+ // don't want to put these on the free list.
+ if (hb_it->newPhysReg != hb_it->prevPhysReg) {
+ // Tell the rename map to set the architected register to the
+ // previous physical register that it was renamed to.
+ renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
+
+ // Put the renamed physical register back on the free list.
+ freeList->addReg(hb_it->newPhysReg);
+ }
historyBuffer[tid].erase(hb_it++);
@@ -918,13 +926,19 @@ DefaultRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num, ThreadID tid)
// renamed.
while (!historyBuffer[tid].empty() &&
hb_it != historyBuffer[tid].end() &&
- (*hb_it).instSeqNum <= inst_seq_num) {
+ hb_it->instSeqNum <= inst_seq_num) {
DPRINTF(Rename, "[tid:%u]: Freeing up older rename of reg %i, "
"[sn:%lli].\n",
- tid, (*hb_it).prevPhysReg, (*hb_it).instSeqNum);
+ tid, hb_it->prevPhysReg, hb_it->instSeqNum);
+
+ // Don't free special phys regs like misc and zero regs, which
+ // can be recognized because the new mapping is the same as
+ // the old one.
+ if (hb_it->newPhysReg != hb_it->prevPhysReg) {
+ freeList->addReg(hb_it->prevPhysReg);
+ }
- freeList->addReg((*hb_it).prevPhysReg);
++renameCommittedMaps;
historyBuffer[tid].erase(hb_it--);
@@ -935,54 +949,49 @@ template <class Impl>
inline void
DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
{
- assert(renameMap[tid] != 0);
-
+ ThreadContext *tc = inst->tcBase();
+ RenameMap *map = renameMap[tid];
unsigned num_src_regs = inst->numSrcRegs();
// Get the architectual register numbers from the source and
- // destination operands, and redirect them to the right register.
- // Will need to mark dependencies though.
+ // operands, and redirect them to the right physical register.
for (int src_idx = 0; src_idx < num_src_regs; src_idx++) {
RegIndex src_reg = inst->srcRegIdx(src_idx);
- RegIndex flat_src_reg = src_reg;
- switch (regIdxToClass(src_reg)) {
+ RegIndex rel_src_reg;
+ RegIndex flat_rel_src_reg;
+ PhysRegIndex renamed_reg;
+
+ switch (regIdxToClass(src_reg, &rel_src_reg)) {
case IntRegClass:
- flat_src_reg = inst->tcBase()->flattenIntIndex(src_reg);
- DPRINTF(Rename, "Flattening index %d to %d.\n",
- (int)src_reg, (int)flat_src_reg);
+ flat_rel_src_reg = tc->flattenIntIndex(rel_src_reg);
+ renamed_reg = map->lookupInt(flat_rel_src_reg);
+ intRenameLookups++;
break;
case FloatRegClass:
- src_reg = src_reg - TheISA::FP_Reg_Base;
- flat_src_reg = inst->tcBase()->flattenFloatIndex(src_reg);
- DPRINTF(Rename, "Flattening index %d to %d.\n",
- (int)src_reg, (int)flat_src_reg);
- flat_src_reg += TheISA::NumIntRegs;
+ flat_rel_src_reg = tc->flattenFloatIndex(rel_src_reg);
+ renamed_reg = map->lookupFloat(flat_rel_src_reg);
+ fpRenameLookups++;
break;
case MiscRegClass:
- flat_src_reg = src_reg - TheISA::Misc_Reg_Base +
- TheISA::NumFloatRegs + TheISA::NumIntRegs;
- DPRINTF(Rename, "Adjusting reg index from %d to %d.\n",
- src_reg, flat_src_reg);
+ // misc regs don't get flattened
+ flat_rel_src_reg = rel_src_reg;
+ renamed_reg = map->lookupMisc(flat_rel_src_reg);
break;
default:
panic("Reg index is out of bound: %d.", src_reg);
}
- // Look up the source registers to get the phys. register they've
- // been renamed to, and set the sources to those registers.
- PhysRegIndex renamed_reg = renameMap[tid]->lookup(flat_src_reg);
-
- DPRINTF(Rename, "[tid:%u]: Looking up arch reg %i, got "
- "physical reg %i.\n", tid, (int)flat_src_reg,
- (int)renamed_reg);
+ DPRINTF(Rename, "[tid:%u]: Looking up %s arch reg %i (flattened %i), "
+ "got phys reg %i\n", tid, RegClassStrings[regIdxToClass(src_reg)],
+ (int)src_reg, (int)flat_rel_src_reg, (int)renamed_reg);
inst->renameSrcReg(src_idx, renamed_reg);
// See if the register is ready or not.
- if (scoreboard->getReg(renamed_reg) == true) {
+ if (scoreboard->getReg(renamed_reg)) {
DPRINTF(Rename, "[tid:%u]: Register %d is ready.\n",
tid, renamed_reg);
@@ -993,7 +1002,6 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
}
++renameRenameLookups;
- inst->isFloating() ? fpRenameLookups++ : intRenameLookups++;
}
}
@@ -1001,58 +1009,53 @@ template <class Impl>
inline void
DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
{
- typename RenameMap::RenameInfo rename_result;
-
+ ThreadContext *tc = inst->tcBase();
+ RenameMap *map = renameMap[tid];
unsigned num_dest_regs = inst->numDestRegs();
// Rename the destination registers.
for (int dest_idx = 0; dest_idx < num_dest_regs; dest_idx++) {
RegIndex dest_reg = inst->destRegIdx(dest_idx);
- RegIndex flat_dest_reg = dest_reg;
- switch (regIdxToClass(dest_reg)) {
+ RegIndex rel_dest_reg;
+ RegIndex flat_rel_dest_reg;
+ RegIndex flat_uni_dest_reg;
+ typename RenameMap::RenameInfo rename_result;
+
+ switch (regIdxToClass(dest_reg, &rel_dest_reg)) {
case IntRegClass:
- // Integer registers are flattened.
- flat_dest_reg = inst->tcBase()->flattenIntIndex(dest_reg);
- DPRINTF(Rename, "Flattening index %d to %d.\n",
- (int)dest_reg, (int)flat_dest_reg);
+ flat_rel_dest_reg = tc->flattenIntIndex(rel_dest_reg);
+ rename_result = map->renameInt(flat_rel_dest_reg);
+ flat_uni_dest_reg = flat_rel_dest_reg; // 1:1 mapping
break;
case FloatRegClass:
- dest_reg = dest_reg - TheISA::FP_Reg_Base;
- flat_dest_reg = inst->tcBase()->flattenFloatIndex(dest_reg);
- DPRINTF(Rename, "Flattening index %d to %d.\n",
- (int)dest_reg, (int)flat_dest_reg);
- flat_dest_reg += TheISA::NumIntRegs;
+ flat_rel_dest_reg = tc->flattenFloatIndex(rel_dest_reg);
+ rename_result = map->renameFloat(flat_rel_dest_reg);
+ flat_uni_dest_reg = flat_rel_dest_reg + TheISA::FP_Reg_Base;
break;
case MiscRegClass:
- // Floating point and Miscellaneous registers need their indexes
- // adjusted to account for the expanded number of flattened int regs.
- flat_dest_reg = dest_reg - TheISA::Misc_Reg_Base +
- TheISA::NumIntRegs + TheISA::NumFloatRegs;
- DPRINTF(Rename, "Adjusting reg index from %d to %d.\n",
- dest_reg, flat_dest_reg);
+ // misc regs don't get flattened
+ flat_rel_dest_reg = rel_dest_reg;
+ rename_result = map->renameMisc(flat_rel_dest_reg);
+ flat_uni_dest_reg = flat_rel_dest_reg + TheISA::Misc_Reg_Base;
break;
default:
panic("Reg index is out of bound: %d.", dest_reg);
}
- inst->flattenDestReg(dest_idx, flat_dest_reg);
-
- // Get the physical register that the destination will be
- // renamed to.
- rename_result = renameMap[tid]->rename(flat_dest_reg);
+ inst->flattenDestReg(dest_idx, flat_uni_dest_reg);
- //Mark Scoreboard entry as not ready
+ // Mark Scoreboard entry as not ready
scoreboard->unsetReg(rename_result.first);
DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
- "reg %i.\n", tid, (int)flat_dest_reg,
+ "reg %i.\n", tid, (int)flat_rel_dest_reg,
(int)rename_result.first);
// Record the rename information so that a history can be kept.
- RenameHistory hb_entry(inst->seqNum, flat_dest_reg,
+ RenameHistory hb_entry(inst->seqNum, flat_uni_dest_reg,
rename_result.first,
rename_result.second);