diff options
author | Steve Reinhardt <steve.reinhardt@amd.com> | 2013-10-15 14:22:44 -0400 |
---|---|---|
committer | Steve Reinhardt <steve.reinhardt@amd.com> | 2013-10-15 14:22:44 -0400 |
commit | 552622184752dc798bc81f9b0b395db68aee9511 (patch) | |
tree | f8867449ca560470442878da448118277f561cbd /src/cpu/o3/rename_map.cc | |
parent | 219c423f1fb0f9a559bfa87f9812426d5e2c3e29 (diff) | |
download | gem5-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.cc | 272 |
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)]); } } |