summaryrefslogtreecommitdiff
path: root/src/cpu/o3/rename_map.hh
diff options
context:
space:
mode:
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__