rename_map.hh revision 10537
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 /** The condition-code register rename map */ 167 SimpleRenameMap ccMap; 168 169 public: 170 typedef TheISA::RegIndex RegIndex; 171 172 typedef SimpleRenameMap::RenameInfo RenameInfo; 173 174 /** Default constructor. init() must be called prior to use. */ 175 UnifiedRenameMap() : regFile(nullptr) {}; 176 177 /** Destructor. */ 178 ~UnifiedRenameMap() {}; 179 180 /** Initializes rename map with given parameters. */ 181 void init(PhysRegFile *_regFile, 182 RegIndex _intZeroReg, 183 RegIndex _floatZeroReg, 184 UnifiedFreeList *freeList); 185 186 /** 187 * Tell rename map to get a new free physical register to remap 188 * the specified architectural register. This version takes a 189 * unified flattened architectural register index and calls the 190 * appropriate class-specific rename table. 191 * @param arch_reg The unified architectural register index to remap. 192 * @return A RenameInfo pair indicating both the new and previous 193 * physical registers. 194 */ 195 RenameInfo rename(RegIndex arch_reg); 196 197 /** 198 * Perform rename() on an integer register, given a relative 199 * integer register index. 200 */ 201 RenameInfo renameInt(RegIndex rel_arch_reg) 202 { 203 RenameInfo info = intMap.rename(rel_arch_reg); 204 assert(regFile->isIntPhysReg(info.first)); 205 return info; 206 } 207 208 /** 209 * Perform rename() on a floating-point register, given a relative 210 * floating-point register index. 211 */ 212 RenameInfo renameFloat(RegIndex rel_arch_reg) 213 { 214 RenameInfo info = floatMap.rename(rel_arch_reg); 215 assert(regFile->isFloatPhysReg(info.first)); 216 return info; 217 } 218 219 /** 220 * Perform rename() on a condition-code register, given a relative 221 * condition-code register index. 222 */ 223 RenameInfo renameCC(RegIndex rel_arch_reg) 224 { 225 RenameInfo info = ccMap.rename(rel_arch_reg); 226 assert(regFile->isCCPhysReg(info.first)); 227 return info; 228 } 229 230 /** 231 * Perform rename() on a misc register, given a relative 232 * misc register index. 233 */ 234 RenameInfo renameMisc(RegIndex rel_arch_reg) 235 { 236 // misc regs aren't really renamed, just remapped 237 PhysRegIndex phys_reg = lookupMisc(rel_arch_reg); 238 // Set the previous register to the same register; mainly it must be 239 // known that the prev reg was outside the range of normal registers 240 // so the free list can avoid adding it. 241 return RenameInfo(phys_reg, phys_reg); 242 } 243 244 245 /** 246 * Look up the physical register mapped to an architectural register. 247 * This version takes a unified flattened architectural register index 248 * and calls the appropriate class-specific rename table. 249 * @param arch_reg The unified architectural register to look up. 250 * @return The physical register it is currently mapped to. 251 */ 252 PhysRegIndex lookup(RegIndex arch_reg) const; 253 254 /** 255 * Perform lookup() on an integer register, given a relative 256 * integer register index. 257 */ 258 PhysRegIndex lookupInt(RegIndex rel_arch_reg) const 259 { 260 PhysRegIndex phys_reg = intMap.lookup(rel_arch_reg); 261 assert(regFile->isIntPhysReg(phys_reg)); 262 return phys_reg; 263 } 264 265 /** 266 * Perform lookup() on a floating-point register, given a relative 267 * floating-point register index. 268 */ 269 PhysRegIndex lookupFloat(RegIndex rel_arch_reg) const 270 { 271 PhysRegIndex phys_reg = floatMap.lookup(rel_arch_reg); 272 assert(regFile->isFloatPhysReg(phys_reg)); 273 return phys_reg; 274 } 275 276 /** 277 * Perform lookup() on a condition-code register, given a relative 278 * condition-code register index. 279 */ 280 PhysRegIndex lookupCC(RegIndex rel_arch_reg) const 281 { 282 PhysRegIndex phys_reg = ccMap.lookup(rel_arch_reg); 283 assert(regFile->isCCPhysReg(phys_reg)); 284 return phys_reg; 285 } 286 287 /** 288 * Perform lookup() on a misc register, given a relative 289 * misc register index. 290 */ 291 PhysRegIndex lookupMisc(RegIndex rel_arch_reg) const 292 { 293 // misc regs aren't really renamed, just given an index 294 // beyond the range of actual physical registers 295 PhysRegIndex phys_reg = rel_arch_reg + regFile->totalNumPhysRegs(); 296 return phys_reg; 297 } 298 299 /** 300 * Update rename map with a specific mapping. Generally used to 301 * roll back to old mappings on a squash. This version takes a 302 * unified flattened architectural register index and calls the 303 * appropriate class-specific rename table. 304 * @param arch_reg The unified architectural register to remap. 305 * @param phys_reg The physical register to remap it to. 306 */ 307 void setEntry(RegIndex arch_reg, PhysRegIndex phys_reg); 308 309 /** 310 * Perform setEntry() on an integer register, given a relative 311 * integer register index. 312 */ 313 void setIntEntry(RegIndex arch_reg, PhysRegIndex phys_reg) 314 { 315 assert(regFile->isIntPhysReg(phys_reg)); 316 intMap.setEntry(arch_reg, phys_reg); 317 } 318 319 /** 320 * Perform setEntry() on a floating-point register, given a relative 321 * floating-point register index. 322 */ 323 void setFloatEntry(RegIndex arch_reg, PhysRegIndex phys_reg) 324 { 325 assert(regFile->isFloatPhysReg(phys_reg)); 326 floatMap.setEntry(arch_reg, phys_reg); 327 } 328 329 /** 330 * Perform setEntry() on a condition-code register, given a relative 331 * condition-code register index. 332 */ 333 void setCCEntry(RegIndex arch_reg, PhysRegIndex phys_reg) 334 { 335 assert(regFile->isCCPhysReg(phys_reg)); 336 ccMap.setEntry(arch_reg, phys_reg); 337 } 338 339 /** 340 * Return the minimum number of free entries across all of the 341 * register classes. The minimum is used so we guarantee that 342 * this number of entries is available regardless of which class 343 * of registers is requested. 344 */ 345 unsigned numFreeEntries() const 346 { 347 return std::min(intMap.numFreeEntries(), floatMap.numFreeEntries()); 348 } 349}; 350 351#endif //__CPU_O3_RENAME_MAP_HH__ 352