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