diff options
Diffstat (limited to 'src/cpu/o3/rename_impl.hh')
-rw-r--r-- | src/cpu/o3/rename_impl.hh | 135 |
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); |