rename_map.hh revision 9919:803903a8dac1
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; 10 * redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution; 13 * neither the name of the copyright holders nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * Authors: Kevin Lim 30 * Steve Reinhardt 31 */ 32 33// Todo: Create destructor. 34// Have it so that there's a more meaningful name given to the variable 35// that marks the beginning of the FP registers. 36 37#ifndef __CPU_O3_RENAME_MAP_HH__ 38#define __CPU_O3_RENAME_MAP_HH__ 39 40#include <iostream> 41#include <utility> 42#include <vector> 43 44#include "arch/types.hh" 45#include "config/the_isa.hh" 46#include "cpu/o3/free_list.hh" 47#include "cpu/o3/regfile.hh" 48#include "cpu/reg_class.hh" 49 50/** 51 * Register rename map for a single class of registers (e.g., integer 52 * or floating point). Because the register class is implicitly 53 * determined by the rename map instance being accessed, all 54 * architectural register index parameters and values in this class 55 * are relative (e.g., %fp2 is just index 2). 56 */ 57class SimpleRenameMap 58{ 59 public: 60 61 typedef TheISA::RegIndex RegIndex; 62 63 private: 64 65 /** The acutal arch-to-phys register map */ 66 std::vector<PhysRegIndex> map; 67 68 /** 69 * Pointer to the free list from which new physical registers 70 * should be allocated in rename() 71 */ 72 SimpleFreeList *freeList; 73 74 /** 75 * The architectural index of the zero register. This register is 76 * mapped but read-only, so we ignore attempts to rename it via 77 * the rename() method. If there is no such register for this map 78 * table, it should be set to an invalid index so that it never 79 * matches. 80 */ 81 RegIndex zeroReg; 82 83 public: 84 85 SimpleRenameMap(); 86 87 ~SimpleRenameMap() {}; 88 89 /** 90 * Because we have an array of rename maps (one per thread) in the CPU, 91 * it's awkward to initialize this object via the constructor. 92 * Instead, this method is used for initialization. 93 */ 94 void init(unsigned size, SimpleFreeList *_freeList, RegIndex _zeroReg); 95 96 /** 97 * Pair of a physical register and a physical register. Used to 98 * return the physical register that a logical register has been 99 * renamed to, and the previous physical register that the same 100 * logical register was previously mapped to. 101 */ 102 typedef std::pair<PhysRegIndex, PhysRegIndex> RenameInfo; 103 104 /** 105 * Tell rename map to get a new free physical register to remap 106 * the specified architectural register. 107 * @param arch_reg The architectural register to remap. 108 * @return A RenameInfo pair indicating both the new and previous 109 * physical registers. 110 */ 111 RenameInfo rename(RegIndex arch_reg); 112 113 /** 114 * Look up the physical register mapped to an architectural register. 115 * @param arch_reg The architectural register to look up. 116 * @return The physical register it is currently mapped to. 117 */ 118 PhysRegIndex lookup(RegIndex arch_reg) const 119 { 120 assert(arch_reg < map.size()); 121 return map[arch_reg]; 122 } 123 124 /** 125 * Update rename map with a specific mapping. Generally used to 126 * roll back to old mappings on a squash. 127 * @param arch_reg The architectural register to remap. 128 * @param phys_reg The physical register to remap it to. 129 */ 130 void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg) 131 { 132 map[arch_reg] = phys_reg; 133 } 134 135 /** Return the number of free entries on the associated free list. */ 136 unsigned numFreeEntries() const { return freeList->numFreeRegs(); } 137}; 138 139 140/** 141 * Unified register rename map for all classes of registers. Wraps a 142 * set of class-specific rename maps. Methods that do not specify a 143 * register class (e.g., rename()) take unified register indices, 144 * while methods that do specify a register class (e.g., renameInt()) 145 * take relative register indices. See http://gem5.org/Register_Indexing. 146 */ 147class UnifiedRenameMap 148{ 149 private: 150 151 /** The integer register rename map */ 152 SimpleRenameMap intMap; 153 154 /** The floating-point register rename map */ 155 SimpleRenameMap floatMap; 156 157 /** 158 * The register file object is used only to distinguish integer 159 * from floating-point physical register indices, which in turn is 160 * used only for assert statements that make sure the physical 161 * register indices that get passed in and handed out are of the 162 * proper class. 163 */ 164 PhysRegFile *regFile; 165 166 public: 167 typedef TheISA::RegIndex RegIndex; 168 169 typedef SimpleRenameMap::RenameInfo RenameInfo; 170 171 /** Default constructor. init() must be called prior to use. */ 172 UnifiedRenameMap() {}; 173 174 /** Destructor. */ 175 ~UnifiedRenameMap() {}; 176 177 /** Initializes rename map with given parameters. */ 178 void init(PhysRegFile *_regFile, 179 RegIndex _intZeroReg, 180 RegIndex _floatZeroReg, 181 UnifiedFreeList *freeList); 182 183 /** 184 * Tell rename map to get a new free physical register to remap 185 * the specified architectural register. This version takes a 186 * unified flattened architectural register index and calls the 187 * appropriate class-specific rename table. 188 * @param arch_reg The unified architectural register index to remap. 189 * @return A RenameInfo pair indicating both the new and previous 190 * physical registers. 191 */ 192 RenameInfo rename(RegIndex arch_reg); 193 194 /** 195 * Perform rename() on an integer register, given a relative 196 * integer register index. 197 */ 198 RenameInfo renameInt(RegIndex rel_arch_reg) 199 { 200 RenameInfo info = intMap.rename(rel_arch_reg); 201 assert(regFile->isIntPhysReg(info.first)); 202 return info; 203 } 204 205 /** 206 * Perform rename() on a floating-point register, given a relative 207 * floating-point register index. 208 */ 209 RenameInfo renameFloat(RegIndex rel_arch_reg) 210 { 211 RenameInfo info = floatMap.rename(rel_arch_reg); 212 assert(regFile->isFloatPhysReg(info.first)); 213 return info; 214 } 215 216 /** 217 * Perform rename() on a misc register, given a relative 218 * misc register index. 219 */ 220 RenameInfo renameMisc(RegIndex rel_arch_reg) 221 { 222 // misc regs aren't really renamed, just remapped 223 PhysRegIndex phys_reg = lookupMisc(rel_arch_reg); 224 // Set the previous register to the same register; mainly it must be 225 // known that the prev reg was outside the range of normal registers 226 // so the free list can avoid adding it. 227 return RenameInfo(phys_reg, phys_reg); 228 } 229 230 231 /** 232 * Look up the physical register mapped to an architectural register. 233 * This version takes a unified flattened architectural register index 234 * and calls the appropriate class-specific rename table. 235 * @param arch_reg The unified architectural register to look up. 236 * @return The physical register it is currently mapped to. 237 */ 238 PhysRegIndex lookup(RegIndex arch_reg) const; 239 240 /** 241 * Perform lookup() on an integer register, given a relative 242 * integer register index. 243 */ 244 PhysRegIndex lookupInt(RegIndex rel_arch_reg) const 245 { 246 PhysRegIndex phys_reg = intMap.lookup(rel_arch_reg); 247 assert(regFile->isIntPhysReg(phys_reg)); 248 return phys_reg; 249 } 250 251 /** 252 * Perform lookup() on a floating-point register, given a relative 253 * floating-point register index. 254 */ 255 PhysRegIndex lookupFloat(RegIndex rel_arch_reg) const 256 { 257 PhysRegIndex phys_reg = floatMap.lookup(rel_arch_reg); 258 assert(regFile->isFloatPhysReg(phys_reg)); 259 return phys_reg; 260 } 261 262 /** 263 * Perform lookup() on a misc register, given a relative 264 * misc register index. 265 */ 266 PhysRegIndex lookupMisc(RegIndex rel_arch_reg) const 267 { 268 // misc regs aren't really renamed, just given an index 269 // beyond the range of actual physical registers 270 PhysRegIndex phys_reg = rel_arch_reg + regFile->totalNumPhysRegs(); 271 return phys_reg; 272 } 273 274 /** 275 * Update rename map with a specific mapping. Generally used to 276 * roll back to old mappings on a squash. This version takes a 277 * unified flattened architectural register index and calls the 278 * appropriate class-specific rename table. 279 * @param arch_reg The unified architectural register to remap. 280 * @param phys_reg The physical register to remap it to. 281 */ 282 void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg); 283 284 /** 285 * Perform setEntry() on an integer register, given a relative 286 * integer register index. 287 */ 288 void setIntEntry(RegIndex arch_reg, PhysRegIndex phys_reg) 289 { 290 assert(regFile->isIntPhysReg(phys_reg)); 291 intMap.setEntry(arch_reg, phys_reg); 292 } 293 294 /** 295 * Perform setEntry() on a floating-point register, given a relative 296 * floating-point register index. 297 */ 298 void setFloatEntry(RegIndex arch_reg, PhysRegIndex phys_reg) 299 { 300 assert(regFile->isFloatPhysReg(phys_reg)); 301 floatMap.setEntry(arch_reg, phys_reg); 302 } 303 304 /** 305 * Return the minimum number of free entries across all of the 306 * register classes. The minimum is used so we guarantee that 307 * this number of entries is available regardless of which class 308 * of registers is requested. 309 */ 310 unsigned numFreeEntries() const 311 { 312 return std::min(intMap.numFreeEntries(), floatMap.numFreeEntries()); 313 } 314}; 315 316#endif //__CPU_O3_RENAME_MAP_HH__ 317