summaryrefslogtreecommitdiff
path: root/src/cpu/o3/rename_map.hh
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.hh
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.hh')
-rw-r--r--src/cpu/o3/rename_map.hh302
1 files changed, 225 insertions, 77 deletions
diff --git a/src/cpu/o3/rename_map.hh b/src/cpu/o3/rename_map.hh
index 51d8db4d8..c989fb88f 100644
--- a/src/cpu/o3/rename_map.hh
+++ b/src/cpu/o3/rename_map.hh
@@ -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
@@ -26,6 +27,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
+ * Steve Reinhardt
*/
// Todo: Create destructor.
@@ -42,18 +44,54 @@
#include "arch/types.hh"
#include "config/the_isa.hh"
#include "cpu/o3/free_list.hh"
-
+#include "cpu/o3/regfile.hh"
+#include "cpu/reg_class.hh"
+
+/**
+ * Register rename map for a single class of registers (e.g., integer
+ * or floating point). Because the register class is implicitly
+ * determined by the rename map instance being accessed, all
+ * architectural register index parameters and values in this class
+ * are relative (e.g., %fp2 is just index 2).
+ */
class SimpleRenameMap
{
- protected:
+ public:
+
typedef TheISA::RegIndex RegIndex;
+
+ private:
+
+ /** The acutal arch-to-phys register map */
+ std::vector<PhysRegIndex> map;
+
+ /**
+ * Pointer to the free list from which new physical registers
+ * should be allocated in rename()
+ */
+ SimpleFreeList *freeList;
+
+ /**
+ * The architectural index of the zero register. This register is
+ * mapped but read-only, so we ignore attempts to rename it via
+ * the rename() method. If there is no such register for this map
+ * table, it should be set to an invalid index so that it never
+ * matches.
+ */
+ RegIndex zeroReg;
+
public:
+
+ SimpleRenameMap();
+
+ ~SimpleRenameMap() {};
+
/**
- * Pair of a logical register and a physical register. Tells the
- * previous mapping of a logical register to a physical register.
- * Used to roll back the rename map to a previous state.
+ * Because we have an array of rename maps (one per thread) in the CPU,
+ * it's awkward to initialize this object via the constructor.
+ * Instead, this method is used for initialization.
*/
- typedef std::pair<RegIndex, PhysRegIndex> UnmapInfo;
+ void init(unsigned size, SimpleFreeList *_freeList, RegIndex _zeroReg);
/**
* Pair of a physical register and a physical register. Used to
@@ -63,106 +101,216 @@ class SimpleRenameMap
*/
typedef std::pair<PhysRegIndex, PhysRegIndex> RenameInfo;
- public:
- /** Default constructor. init() must be called prior to use. */
- SimpleRenameMap() {};
-
- /** Destructor. */
- ~SimpleRenameMap();
-
- /** Initializes rename map with given parameters. */
- void init(unsigned _numLogicalIntRegs,
- unsigned _numPhysicalIntRegs,
- PhysRegIndex &_int_reg_start,
+ /**
+ * Tell rename map to get a new free physical register to remap
+ * the specified architectural register.
+ * @param arch_reg The architectural register to remap.
+ * @return A RenameInfo pair indicating both the new and previous
+ * physical registers.
+ */
+ RenameInfo rename(RegIndex arch_reg);
- unsigned _numLogicalFloatRegs,
- unsigned _numPhysicalFloatRegs,
- PhysRegIndex &_float_reg_start,
+ /**
+ * Look up the physical register mapped to an architectural register.
+ * @param arch_reg The architectural register to look up.
+ * @return The physical register it is currently mapped to.
+ */
+ PhysRegIndex lookup(RegIndex arch_reg) const
+ {
+ assert(arch_reg < map.size());
+ return map[arch_reg];
+ }
- unsigned _numMiscRegs,
+ /**
+ * Update rename map with a specific mapping. Generally used to
+ * roll back to old mappings on a squash.
+ * @param arch_reg The architectural register to remap.
+ * @param phys_reg The physical register to remap it to.
+ */
+ void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+ {
+ map[arch_reg] = phys_reg;
+ }
- RegIndex _intZeroReg,
- RegIndex _floatZeroReg,
+ /** Return the number of free entries on the associated free list. */
+ unsigned numFreeEntries() const { return freeList->numFreeRegs(); }
+};
- int id,
- bool bindRegs);
- /** Sets the free list used with this rename map. */
- void setFreeList(SimpleFreeList *fl_ptr);
+/**
+ * Unified register rename map for all classes of registers. Wraps a
+ * set of class-specific rename maps. Methods that do not specify a
+ * register class (e.g., rename()) take unified register indices,
+ * while methods that do specify a register class (e.g., renameInt())
+ * take relative register indices. See http://gem5.org/Register_Indexing.
+ */
+class UnifiedRenameMap
+{
+ private:
- //Tell rename map to get a free physical register for a given
- //architected register. Not sure it should have a return value,
- //but perhaps it should have some sort of fault in case there are
- //no free registers.
- RenameInfo rename(RegIndex arch_reg);
+ /** The integer register rename map */
+ SimpleRenameMap intMap;
- PhysRegIndex lookup(RegIndex phys_reg);
+ /** The floating-point register rename map */
+ SimpleRenameMap floatMap;
/**
- * Marks the given register as ready, meaning that its value has been
- * calculated and written to the register file.
- * @param ready_reg The index of the physical register that is now ready.
+ * The register file object is used only to distinguish integer
+ * from floating-point physical register indices, which in turn is
+ * used only for assert statements that make sure the physical
+ * register indices that get passed in and handed out are of the
+ * proper class.
*/
- void setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg);
+ PhysRegFile *regFile;
+
+ public:
+ typedef TheISA::RegIndex RegIndex;
- int numFreeEntries();
+ typedef SimpleRenameMap::RenameInfo RenameInfo;
- private:
- /** Rename Map ID */
- int id;
+ /** Default constructor. init() must be called prior to use. */
+ UnifiedRenameMap() {};
- /** Number of logical integer registers. */
- int numLogicalIntRegs;
+ /** Destructor. */
+ ~UnifiedRenameMap() {};
- /** Number of physical integer registers. */
- int numPhysicalIntRegs;
+ /** Initializes rename map with given parameters. */
+ void init(PhysRegFile *_regFile,
+ RegIndex _intZeroReg,
+ RegIndex _floatZeroReg,
+ UnifiedFreeList *freeList);
- /** Number of logical floating point registers. */
- int numLogicalFloatRegs;
+ /**
+ * Tell rename map to get a new free physical register to remap
+ * the specified architectural register. This version takes a
+ * unified flattened architectural register index and calls the
+ * appropriate class-specific rename table.
+ * @param arch_reg The unified architectural register index to remap.
+ * @return A RenameInfo pair indicating both the new and previous
+ * physical registers.
+ */
+ RenameInfo rename(RegIndex arch_reg);
- /** Number of physical floating point registers. */
- int numPhysicalFloatRegs;
+ /**
+ * Perform rename() on an integer register, given a relative
+ * integer register index.
+ */
+ RenameInfo renameInt(RegIndex rel_arch_reg)
+ {
+ RenameInfo info = intMap.rename(rel_arch_reg);
+ assert(regFile->isIntPhysReg(info.first));
+ return info;
+ }
+
+ /**
+ * Perform rename() on a floating-point register, given a relative
+ * floating-point register index.
+ */
+ RenameInfo renameFloat(RegIndex rel_arch_reg)
+ {
+ RenameInfo info = floatMap.rename(rel_arch_reg);
+ assert(regFile->isFloatPhysReg(info.first));
+ return info;
+ }
- /** Number of miscellaneous registers. */
- int numMiscRegs;
+ /**
+ * Perform rename() on a misc register, given a relative
+ * misc register index.
+ */
+ RenameInfo renameMisc(RegIndex rel_arch_reg)
+ {
+ // misc regs aren't really renamed, just remapped
+ PhysRegIndex phys_reg = lookupMisc(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.
+ return RenameInfo(phys_reg, phys_reg);
+ }
- /** Number of logical integer + float registers. */
- int numLogicalRegs;
- /** Number of physical integer + float registers. */
- int numPhysicalRegs;
+ /**
+ * Look up the physical register mapped to an architectural register.
+ * This version takes a unified flattened architectural register index
+ * and calls the appropriate class-specific rename table.
+ * @param arch_reg The unified architectural register to look up.
+ * @return The physical register it is currently mapped to.
+ */
+ PhysRegIndex lookup(RegIndex arch_reg) const;
- /** The integer zero register. This implementation assumes it is always
- * zero and never can be anything else.
+ /**
+ * Perform lookup() on an integer register, given a relative
+ * integer register index.
*/
- RegIndex intZeroReg;
+ PhysRegIndex lookupInt(RegIndex rel_arch_reg) const
+ {
+ PhysRegIndex phys_reg = intMap.lookup(rel_arch_reg);
+ assert(regFile->isIntPhysReg(phys_reg));
+ return phys_reg;
+ }
- /** The floating point zero register. This implementation assumes it is
- * always zero and never can be anything else.
+ /**
+ * Perform lookup() on a floating-point register, given a relative
+ * floating-point register index.
*/
- RegIndex floatZeroReg;
+ PhysRegIndex lookupFloat(RegIndex rel_arch_reg) const
+ {
+ PhysRegIndex phys_reg = floatMap.lookup(rel_arch_reg);
+ assert(regFile->isFloatPhysReg(phys_reg));
+ return phys_reg;
+ }
- class RenameEntry
+ /**
+ * Perform lookup() on a misc register, given a relative
+ * misc register index.
+ */
+ PhysRegIndex lookupMisc(RegIndex rel_arch_reg) const
{
- public:
- PhysRegIndex physical_reg;
- bool valid;
+ // misc regs aren't really renamed, just given an index
+ // beyond the range of actual physical registers
+ PhysRegIndex phys_reg = rel_arch_reg + regFile->totalNumPhysRegs();
+ return phys_reg;
+ }
- RenameEntry()
- : physical_reg(0), valid(false)
- { }
- };
+ /**
+ * Update rename map with a specific mapping. Generally used to
+ * roll back to old mappings on a squash. This version takes a
+ * unified flattened architectural register index and calls the
+ * appropriate class-specific rename table.
+ * @param arch_reg The unified architectural register to remap.
+ * @param phys_reg The physical register to remap it to.
+ */
+ void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg);
- private:
- /** Integer rename map. */
- std::vector<RenameEntry> intRenameMap;
+ /**
+ * Perform setEntry() on an integer register, given a relative
+ * integer register index.
+ */
+ void setIntEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+ {
+ assert(regFile->isIntPhysReg(phys_reg));
+ intMap.setEntry(arch_reg, phys_reg);
+ }
- /** Floating point rename map. */
- std::vector<RenameEntry> floatRenameMap;
+ /**
+ * Perform setEntry() on a floating-point register, given a relative
+ * floating-point register index.
+ */
+ void setFloatEntry(RegIndex arch_reg, PhysRegIndex phys_reg)
+ {
+ assert(regFile->isFloatPhysReg(phys_reg));
+ floatMap.setEntry(arch_reg, phys_reg);
+ }
- private:
- /** Free list interface. */
- SimpleFreeList *freeList;
+ /**
+ * Return the minimum number of free entries across all of the
+ * register classes. The minimum is used so we guarantee that
+ * this number of entries is available regardless of which class
+ * of registers is requested.
+ */
+ unsigned numFreeEntries() const
+ {
+ return std::min(intMap.numFreeEntries(), floatMap.numFreeEntries());
+ }
};
#endif //__CPU_O3_RENAME_MAP_HH__