summaryrefslogtreecommitdiff
path: root/src/cpu/o3/free_list.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/free_list.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/free_list.hh')
-rw-r--r--src/cpu/o3/free_list.hh176
1 files changed, 80 insertions, 96 deletions
diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh
index fec076097..3919d0afb 100644
--- a/src/cpu/o3/free_list.hh
+++ b/src/cpu/o3/free_list.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
@@ -34,14 +35,51 @@
#include <iostream>
#include <queue>
-#include "arch/registers.hh"
#include "base/misc.hh"
#include "base/trace.hh"
-#include "config/the_isa.hh"
#include "cpu/o3/comm.hh"
+#include "cpu/o3/regfile.hh"
#include "debug/FreeList.hh"
/**
+ * Free list 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 SimpleFreeList
+{
+ private:
+
+ /** The actual free list */
+ std::queue<PhysRegIndex> freeRegs;
+
+ public:
+
+ SimpleFreeList() {};
+
+ /** Add a physical register to the free list */
+ void addReg(PhysRegIndex reg) { freeRegs.push(reg); }
+
+ /** Get the next available register from the free list */
+ PhysRegIndex getReg()
+ {
+ assert(!freeRegs.empty());
+ PhysRegIndex free_reg = freeRegs.front();
+ freeRegs.pop();
+ return free_reg;
+ }
+
+ /** Return the number of free registers on the list. */
+ unsigned numFreeRegs() const { return freeRegs.size(); }
+
+ /** True iff there are free registers on the list. */
+ bool hasFreeRegs() const { return !freeRegs.empty(); }
+};
+
+
+/**
* FreeList class that simply holds the list of free integer and floating
* point registers. Can request for a free register of either type, and
* also send back free registers of either type. This is a very simple
@@ -54,125 +92,86 @@
* class can be named simply "FreeList".
* @todo: Give a better name to the base FP dependency.
*/
-class SimpleFreeList
+class UnifiedFreeList
{
private:
- /** The list of free integer registers. */
- std::queue<PhysRegIndex> freeIntRegs;
- /** The list of free floating point registers. */
- std::queue<PhysRegIndex> freeFloatRegs;
-
- /** Number of logical integer registers. */
- int numLogicalIntRegs;
+ /** The object name, for DPRINTF. We have to declare this
+ * explicitly because Scoreboard is not a SimObject. */
+ const std::string _name;
- /** Number of physical integer registers. */
- int numPhysicalIntRegs;
+ /** The list of free integer registers. */
+ SimpleFreeList intList;
- /** Number of logical floating point registers. */
- int numLogicalFloatRegs;
+ /** The list of free floating point registers. */
+ SimpleFreeList floatList;
- /** Number of physical floating point registers. */
- int numPhysicalFloatRegs;
+ /**
+ * The register file object is used only to distinguish integer
+ * from floating-point physical register indices.
+ */
+ PhysRegFile *regFile;
- /** Total number of physical registers. */
- int numPhysicalRegs;
+ /*
+ * We give UnifiedRenameMap internal access so it can get at the
+ * internal per-class free lists and associate those with its
+ * per-class rename maps. See UnifiedRenameMap::init().
+ */
+ friend class UnifiedRenameMap;
public:
/** Constructs a free list.
- * @param activeThreads Number of active threads.
- * @param _numLogicalIntRegs Number of logical integer registers.
* @param _numPhysicalIntRegs Number of physical integer registers.
- * @param _numLogicalFloatRegs Number of logical fp registers.
+ * @param reservedIntRegs Number of integer registers already
+ * used by initial mappings.
* @param _numPhysicalFloatRegs Number of physical fp registers.
+ * @param reservedFloatRegs Number of fp registers already
+ * used by initial mappings.
*/
- SimpleFreeList(ThreadID activeThreads,
- unsigned _numLogicalIntRegs,
- unsigned _numPhysicalIntRegs,
- unsigned _numLogicalFloatRegs,
- unsigned _numPhysicalFloatRegs);
+ UnifiedFreeList(const std::string &_my_name, PhysRegFile *_regFile);
/** Gives the name of the freelist. */
- std::string name() const;
+ std::string name() const { return _name; };
/** Gets a free integer register. */
- inline PhysRegIndex getIntReg();
+ PhysRegIndex getIntReg() { return intList.getReg(); }
/** Gets a free fp register. */
- inline PhysRegIndex getFloatReg();
+ PhysRegIndex getFloatReg() { return floatList.getReg(); }
/** Adds a register back to the free list. */
- inline void addReg(PhysRegIndex freed_reg);
+ void addReg(PhysRegIndex freed_reg);
/** Adds an integer register back to the free list. */
- inline void addIntReg(PhysRegIndex freed_reg);
+ void addIntReg(PhysRegIndex freed_reg) { intList.addReg(freed_reg); }
/** Adds a fp register back to the free list. */
- inline void addFloatReg(PhysRegIndex freed_reg);
+ void addFloatReg(PhysRegIndex freed_reg) { floatList.addReg(freed_reg); }
/** Checks if there are any free integer registers. */
- bool hasFreeIntRegs()
- { return !freeIntRegs.empty(); }
+ bool hasFreeIntRegs() const { return intList.hasFreeRegs(); }
/** Checks if there are any free fp registers. */
- bool hasFreeFloatRegs()
- { return !freeFloatRegs.empty(); }
+ bool hasFreeFloatRegs() const { return floatList.hasFreeRegs(); }
/** Returns the number of free integer registers. */
- int numFreeIntRegs()
- { return freeIntRegs.size(); }
+ unsigned numFreeIntRegs() const { return intList.numFreeRegs(); }
/** Returns the number of free fp registers. */
- int numFreeFloatRegs()
- { return freeFloatRegs.size(); }
+ unsigned numFreeFloatRegs() const { return floatList.numFreeRegs(); }
};
-inline PhysRegIndex
-SimpleFreeList::getIntReg()
-{
- DPRINTF(FreeList, "Trying to get free integer register.\n");
-
- if (freeIntRegs.empty()) {
- panic("No free integer registers!");
- }
-
- PhysRegIndex free_reg = freeIntRegs.front();
-
- freeIntRegs.pop();
-
- return(free_reg);
-}
-
-inline PhysRegIndex
-SimpleFreeList::getFloatReg()
-{
- DPRINTF(FreeList, "Trying to get free float register.\n");
-
- if (freeFloatRegs.empty()) {
- panic("No free integer registers!");
- }
-
- PhysRegIndex free_reg = freeFloatRegs.front();
-
- freeFloatRegs.pop();
-
- return(free_reg);
-}
-
inline void
-SimpleFreeList::addReg(PhysRegIndex freed_reg)
+UnifiedFreeList::addReg(PhysRegIndex freed_reg)
{
DPRINTF(FreeList,"Freeing register %i.\n", freed_reg);
//Might want to add in a check for whether or not this register is
//already in there. A bit vector or something similar would be useful.
- if (freed_reg < numPhysicalIntRegs) {
- if (freed_reg != TheISA::ZeroReg)
- freeIntRegs.push(freed_reg);
- } else if (freed_reg < numPhysicalRegs) {
-#if THE_ISA == ALPHA_ISA
- if (freed_reg != (TheISA::ZeroReg + numPhysicalIntRegs))
-#endif
- freeFloatRegs.push(freed_reg);
+ if (regFile->isIntPhysReg(freed_reg)) {
+ intList.addReg(freed_reg);
+ } else {
+ assert(regFile->isFloatPhysReg(freed_reg));
+ floatList.addReg(freed_reg);
}
// These assert conditions ensure that the number of free
@@ -188,20 +187,5 @@ SimpleFreeList::addReg(PhysRegIndex freed_reg)
// assert(freeFloatRegs.size() <= numPhysicalFloatRegs);
}
-inline void
-SimpleFreeList::addIntReg(PhysRegIndex freed_reg)
-{
- DPRINTF(FreeList,"Freeing int register %i.\n", freed_reg);
-
- freeIntRegs.push(freed_reg);
-}
-
-inline void
-SimpleFreeList::addFloatReg(PhysRegIndex freed_reg)
-{
- DPRINTF(FreeList,"Freeing float register %i.\n", freed_reg);
-
- freeFloatRegs.push(freed_reg);
-}
#endif // __CPU_O3_FREE_LIST_HH__