diff options
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)]); } } |