summaryrefslogtreecommitdiff
path: root/src/cpu/o3/rename_map.cc
diff options
context:
space:
mode:
authorSteve Reinhardt <steve.reinhardt@amd.com>2013-10-15 14:22:44 -0400
committerSteve Reinhardt <steve.reinhardt@amd.com>2013-10-15 14:22:44 -0400
commit552622184752dc798bc81f9b0b395db68aee9511 (patch)
treef8867449ca560470442878da448118277f561cbd /src/cpu/o3/rename_map.cc
parent219c423f1fb0f9a559bfa87f9812426d5e2c3e29 (diff)
downloadgem5-552622184752dc798bc81f9b0b395db68aee9511.tar.xz
cpu/o3: clean up rename map and free list
Restructured rename map and free list to clean up some extraneous code and separate out common code that can be reused across different register classes (int and fp at this point). Both components now consist of a set of Simple* objects that are stand-alone rename map & free list for each class, plus a Unified* object that presents a unified interface across all register classes and then redirects accesses to the appropriate Simple* object as needed. Moved free list initialization to PhysRegFile to better isolate knowledge of physical register index mappings to that class (and remove the need to pass a number of parameters to the free list constructor). Causes a small change to these stats: cpu.rename.int_rename_lookups cpu.rename.fp_rename_lookups because they are now categorized on a per-operand basis rather than a per-instruction basis. That is, an instruction with mixed fp/int/misc operand types will have each operand categorized independently, where previously the lookup was categorized based on the instruction type.
Diffstat (limited to 'src/cpu/o3/rename_map.cc')
-rw-r--r--src/cpu/o3/rename_map.cc272
1 files changed, 93 insertions, 179 deletions
diff --git a/src/cpu/o3/rename_map.cc b/src/cpu/o3/rename_map.cc
index 57caa76be..ecee4c721 100644
--- a/src/cpu/o3/rename_map.cc
+++ b/src/cpu/o3/rename_map.cc
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,222 +36,135 @@
using namespace std;
-// @todo: Consider making inline bool functions that determine if the
-// register is a logical int, logical fp, physical int, physical fp,
-// etc.
+/**** SimpleRenameMap methods ****/
-SimpleRenameMap::~SimpleRenameMap()
+SimpleRenameMap::SimpleRenameMap()
+ : freeList(NULL)
{
}
-void
-SimpleRenameMap::init(unsigned _numLogicalIntRegs,
- unsigned _numPhysicalIntRegs,
- PhysRegIndex &ireg_idx,
-
- unsigned _numLogicalFloatRegs,
- unsigned _numPhysicalFloatRegs,
- PhysRegIndex &freg_idx,
- unsigned _numMiscRegs,
+void
+SimpleRenameMap::init(unsigned size, SimpleFreeList *_freeList,
+ RegIndex _zeroReg)
+{
+ assert(freeList == NULL);
+ assert(map.empty());
- RegIndex _intZeroReg,
- RegIndex _floatZeroReg,
+ map.resize(size);
+ freeList = _freeList;
+ zeroReg = _zeroReg;
+}
- int map_id,
- bool bindRegs)
+SimpleRenameMap::RenameInfo
+SimpleRenameMap::rename(RegIndex arch_reg)
{
- id = map_id;
-
- numLogicalIntRegs = _numLogicalIntRegs;
+ PhysRegIndex renamed_reg;
- numLogicalFloatRegs = _numLogicalFloatRegs;
+ // Record the current physical register that is renamed to the
+ // requested architected register.
+ PhysRegIndex prev_reg = map[arch_reg];
- numPhysicalIntRegs = _numPhysicalIntRegs;
+ // If it's not referencing the zero register, then rename the
+ // register.
+ if (arch_reg != zeroReg) {
+ renamed_reg = freeList->getReg();
- numPhysicalFloatRegs = _numPhysicalFloatRegs;
+ map[arch_reg] = renamed_reg;
+ } else {
+ // Otherwise return the zero register so nothing bad happens.
+ assert(prev_reg == zeroReg);
+ renamed_reg = zeroReg;
+ }
- numMiscRegs = _numMiscRegs;
+ DPRINTF(Rename, "Renamed reg %d to physical reg %d old mapping was %d\n",
+ arch_reg, renamed_reg, prev_reg);
- intZeroReg = _intZeroReg;
- floatZeroReg = _floatZeroReg;
+ return RenameInfo(renamed_reg, prev_reg);
+}
- DPRINTF(Rename, "Creating rename map %i. Phys: %i / %i, Float: "
- "%i / %i.\n", id, numLogicalIntRegs, numPhysicalIntRegs,
- numLogicalFloatRegs, numPhysicalFloatRegs);
- numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
+/**** UnifiedRenameMap methods ****/
- numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
+void
+UnifiedRenameMap::init(PhysRegFile *_regFile,
+ RegIndex _intZeroReg,
+ RegIndex _floatZeroReg,
+ UnifiedFreeList *freeList)
+{
+ regFile = _regFile;
- //Create the rename maps
- intRenameMap.resize(numLogicalIntRegs);
- floatRenameMap.resize(numLogicalRegs);
+ intMap.init(TheISA::NumIntRegs, &(freeList->intList), _intZeroReg);
- if (bindRegs) {
- DPRINTF(Rename, "Binding registers into rename map %i\n",id);
+ floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg);
+}
- // Initialize the entries in the integer rename map to point to the
- // physical registers of the same index
- for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
- {
- intRenameMap[index].physical_reg = ireg_idx++;
- }
- // Initialize the entries in the floating point rename map to point to
- // the physical registers of the same index
- // Although the index refers purely to architected registers, because
- // the floating reg indices come after the integer reg indices, they
- // may exceed the size of a normal RegIndex (short).
- for (PhysRegIndex index = numLogicalIntRegs;
- index < numLogicalRegs; ++index)
- {
- floatRenameMap[index].physical_reg = freg_idx++;
- }
- } else {
- DPRINTF(Rename, "Binding registers into rename map %i\n",id);
+UnifiedRenameMap::RenameInfo
+UnifiedRenameMap::rename(RegIndex arch_reg)
+{
+ RegIndex rel_arch_reg;
- PhysRegIndex temp_ireg = ireg_idx;
+ switch (regIdxToClass(arch_reg, &rel_arch_reg)) {
+ case IntRegClass:
+ return renameInt(rel_arch_reg);
- for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
- {
- intRenameMap[index].physical_reg = temp_ireg++;
- }
+ case FloatRegClass:
+ return renameFloat(rel_arch_reg);
- PhysRegIndex temp_freg = freg_idx;
+ case MiscRegClass:
+ return renameMisc(rel_arch_reg);
- for (PhysRegIndex index = numLogicalIntRegs;
- index < numLogicalRegs; ++index)
- {
- floatRenameMap[index].physical_reg = temp_freg++;
- }
+ default:
+ panic("rename rename(): unknown reg class %s\n",
+ RegClassStrings[regIdxToClass(arch_reg)]);
}
}
-void
-SimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
-{
- freeList = fl_ptr;
-}
-
-SimpleRenameMap::RenameInfo
-SimpleRenameMap::rename(RegIndex arch_reg)
+PhysRegIndex
+UnifiedRenameMap::lookup(RegIndex arch_reg) const
{
- PhysRegIndex renamed_reg;
- PhysRegIndex prev_reg;
-
- if (arch_reg < numLogicalIntRegs) {
-
- // Record the current physical register that is renamed to the
- // requested architected register.
- prev_reg = intRenameMap[arch_reg].physical_reg;
-
- // If it's not referencing the zero register, then rename the
- // register.
- if (arch_reg != intZeroReg) {
- renamed_reg = freeList->getIntReg();
-
- intRenameMap[arch_reg].physical_reg = renamed_reg;
-
- assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);
-
- } else {
- // Otherwise return the zero register so nothing bad happens.
- renamed_reg = intZeroReg;
- prev_reg = intZeroReg;
- }
- } else if (arch_reg < numLogicalRegs) {
- // Record the current physical register that is renamed to the
- // requested architected register.
- prev_reg = floatRenameMap[arch_reg].physical_reg;
-
- // If it's not referencing the zero register, then rename the
- // register.
-#if THE_ISA == ALPHA_ISA
- if (arch_reg != floatZeroReg) {
-#endif
- renamed_reg = freeList->getFloatReg();
-
- floatRenameMap[arch_reg].physical_reg = renamed_reg;
-
- assert(renamed_reg < numPhysicalRegs &&
- renamed_reg >= numPhysicalIntRegs);
-#if THE_ISA == ALPHA_ISA
- } else {
- // Otherwise return the zero register so nothing bad happens.
- renamed_reg = floatZeroReg;
- }
-#endif
- } else {
- // Subtract off the base offset for miscellaneous registers.
- arch_reg = arch_reg - numLogicalRegs;
+ RegIndex rel_arch_reg;
- DPRINTF(Rename, "Renamed misc reg %d\n", arch_reg);
+ switch (regIdxToClass(arch_reg, &rel_arch_reg)) {
+ case IntRegClass:
+ return lookupInt(rel_arch_reg);
- // No renaming happens to the misc. registers. They are
- // simply the registers that come after all the physical
- // registers; thus take the base architected register and add
- // the physical registers to it.
- renamed_reg = arch_reg + numPhysicalRegs;
+ case FloatRegClass:
+ return lookupFloat(rel_arch_reg);
- // Set the previous register to the same register; mainly it must be
- // known that the prev reg was outside the range of normal registers
- // so the free list can avoid adding it.
- prev_reg = renamed_reg;
- }
-
- DPRINTF(Rename, "Renamed reg %d to physical reg %d old mapping was %d\n",
- arch_reg, renamed_reg, prev_reg);
+ case MiscRegClass:
+ return lookupMisc(rel_arch_reg);
- return RenameInfo(renamed_reg, prev_reg);
-}
-
-PhysRegIndex
-SimpleRenameMap::lookup(RegIndex arch_reg)
-{
- if (arch_reg < numLogicalIntRegs) {
- return intRenameMap[arch_reg].physical_reg;
- } else if (arch_reg < numLogicalRegs) {
- return floatRenameMap[arch_reg].physical_reg;
- } else {
- // Subtract off the misc registers offset.
- arch_reg = arch_reg - numLogicalRegs;
-
- // Misc. regs don't rename, so simply add the base arch reg to
- // the number of physical registers.
- return numPhysicalRegs + arch_reg;
+ default:
+ panic("rename lookup(): unknown reg class %s\n",
+ RegClassStrings[regIdxToClass(arch_reg)]);
}
}
void
-SimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
+UnifiedRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
{
- // In this implementation the miscellaneous registers do not
- // actually rename, so this function does not allow you to try to
- // change their mappings.
- if (arch_reg < numLogicalIntRegs) {
- DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
- (int)arch_reg, renamed_reg);
-
- intRenameMap[arch_reg].physical_reg = renamed_reg;
- } else if (arch_reg < numLogicalIntRegs + numLogicalFloatRegs) {
- DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
- (int)arch_reg - numLogicalIntRegs, renamed_reg);
-
- floatRenameMap[arch_reg].physical_reg = renamed_reg;
- }
-}
-
-int
-SimpleRenameMap::numFreeEntries()
-{
- int free_int_regs = freeList->numFreeIntRegs();
- int free_float_regs = freeList->numFreeFloatRegs();
-
- if (free_int_regs < free_float_regs) {
- return free_int_regs;
- } else {
- return free_float_regs;
+ RegIndex rel_arch_reg;
+
+ switch (regIdxToClass(arch_reg, &rel_arch_reg)) {
+ case IntRegClass:
+ return setIntEntry(rel_arch_reg, phys_reg);
+
+ case FloatRegClass:
+ return setFloatEntry(rel_arch_reg, phys_reg);
+
+ case MiscRegClass:
+ // Misc registers do not actually rename, so don't change
+ // their mappings. We end up here when a commit or squash
+ // tries to update or undo a hardwired misc reg nmapping,
+ // which should always be setting it to what it already is.
+ assert(phys_reg == lookupMisc(rel_arch_reg));
+ return;
+
+ default:
+ panic("rename setEntry(): unknown reg class %s\n",
+ RegClassStrings[regIdxToClass(arch_reg)]);
}
}