rename_map.hh revision 12106:7784fac1b159
12929Sktlim@umich.edu/* 211504Sandreas.sandberg@arm.com * Copyright (c) 2015-2016 ARM Limited 311504Sandreas.sandberg@arm.com * All rights reserved. 411504Sandreas.sandberg@arm.com * 511504Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 611504Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 711504Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 811504Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 911504Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1011504Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1111504Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1211504Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1311504Sandreas.sandberg@arm.com * 1411504Sandreas.sandberg@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 152932Sktlim@umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc. 162929Sktlim@umich.edu * All rights reserved. 172929Sktlim@umich.edu * 182929Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without 192929Sktlim@umich.edu * modification, are permitted provided that the following conditions are 202929Sktlim@umich.edu * met: redistributions of source code must retain the above copyright 212929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer; 222929Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright 232929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the 242929Sktlim@umich.edu * documentation and/or other materials provided with the distribution; 252929Sktlim@umich.edu * neither the name of the copyright holders nor the names of its 262929Sktlim@umich.edu * contributors may be used to endorse or promote products derived from 272929Sktlim@umich.edu * this software without specific prior written permission. 282929Sktlim@umich.edu * 292929Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302929Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312929Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322929Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332929Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342929Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352929Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362929Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372929Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382929Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392929Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402932Sktlim@umich.edu * 412932Sktlim@umich.edu * Authors: Kevin Lim 422932Sktlim@umich.edu * Steve Reinhardt 4311504Sandreas.sandberg@arm.com */ 442929Sktlim@umich.edu 4512563Sgabeblack@google.com#ifndef __CPU_O3_RENAME_MAP_HH__ 4612563Sgabeblack@google.com#define __CPU_O3_RENAME_MAP_HH__ 472929Sktlim@umich.edu 4811504Sandreas.sandberg@arm.com#include <iostream> 4911504Sandreas.sandberg@arm.com#include <utility> 5011504Sandreas.sandberg@arm.com#include <vector> 5111504Sandreas.sandberg@arm.com 5211504Sandreas.sandberg@arm.com#include "arch/types.hh" 5311504Sandreas.sandberg@arm.com#include "config/the_isa.hh" 5411504Sandreas.sandberg@arm.com#include "cpu/o3/free_list.hh" 5512246Sgabeblack@google.com#include "cpu/o3/regfile.hh" 562929Sktlim@umich.edu#include "cpu/reg_class.hh" 572929Sktlim@umich.edu 582929Sktlim@umich.edu/** 598947Sandreas.hansson@arm.com * Register rename map for a single class of registers (e.g., integer 6012246Sgabeblack@google.com * or floating point). Because the register class is implicitly 618947Sandreas.hansson@arm.com * determined by the rename map instance being accessed, all 622929Sktlim@umich.edu * architectural register index parameters and values in this class 632929Sktlim@umich.edu * are relative (e.g., %fp2 is just index 2). 6411504Sandreas.sandberg@arm.com */ 6511504Sandreas.sandberg@arm.comclass SimpleRenameMap 6611504Sandreas.sandberg@arm.com{ 6711504Sandreas.sandberg@arm.com private: 6811504Sandreas.sandberg@arm.com using Arch2PhysMap = std::vector<PhysRegIdPtr>; 6911504Sandreas.sandberg@arm.com /** The acutal arch-to-phys register map */ 7011504Sandreas.sandberg@arm.com Arch2PhysMap map; 712929Sktlim@umich.edu 7211504Sandreas.sandberg@arm.com /** 7311504Sandreas.sandberg@arm.com * Pointer to the free list from which new physical registers 746007Ssteve.reinhardt@amd.com * should be allocated in rename() 756007Ssteve.reinhardt@amd.com */ 7611504Sandreas.sandberg@arm.com SimpleFreeList *freeList; 772929Sktlim@umich.edu 782929Sktlim@umich.edu /** 7911504Sandreas.sandberg@arm.com * The architectural index of the zero register. This register is 806007Ssteve.reinhardt@amd.com * mapped but read-only, so we ignore attempts to rename it via 816007Ssteve.reinhardt@amd.com * the rename() method. If there is no such register for this map 829781Sandreas.hansson@arm.com * table, it should be set to an invalid index so that it never 836007Ssteve.reinhardt@amd.com * matches. 8411504Sandreas.sandberg@arm.com */ 852929Sktlim@umich.edu RegId zeroReg; 862929Sktlim@umich.edu 8711504Sandreas.sandberg@arm.com public: 8811504Sandreas.sandberg@arm.com 8911504Sandreas.sandberg@arm.com SimpleRenameMap(); 9011504Sandreas.sandberg@arm.com 9111504Sandreas.sandberg@arm.com ~SimpleRenameMap() {}; 926007Ssteve.reinhardt@amd.com 9311504Sandreas.sandberg@arm.com /** 9411504Sandreas.sandberg@arm.com * Because we have an array of rename maps (one per thread) in the CPU, 9511504Sandreas.sandberg@arm.com * it's awkward to initialize this object via the constructor. 9611504Sandreas.sandberg@arm.com * Instead, this method is used for initialization. 976007Ssteve.reinhardt@amd.com */ 9811504Sandreas.sandberg@arm.com void init(unsigned size, SimpleFreeList *_freeList, RegIndex _zeroReg); 9911504Sandreas.sandberg@arm.com 10011504Sandreas.sandberg@arm.com /** 1016007Ssteve.reinhardt@amd.com * Pair of a physical register and a physical register. Used to 1022929Sktlim@umich.edu * return the physical register that a logical register has been 1032929Sktlim@umich.edu * renamed to, and the previous physical register that the same 1046007Ssteve.reinhardt@amd.com * logical register was previously mapped to. 1056007Ssteve.reinhardt@amd.com */ 1062929Sktlim@umich.edu typedef std::pair<PhysRegIdPtr, PhysRegIdPtr> RenameInfo; 1072929Sktlim@umich.edu 1086007Ssteve.reinhardt@amd.com /** 1092929Sktlim@umich.edu * Tell rename map to get a new free physical register to remap 1102929Sktlim@umich.edu * the specified architectural register. 11111504Sandreas.sandberg@arm.com * @param arch_reg The architectural register to remap. 1128947Sandreas.hansson@arm.com * @return A RenameInfo pair indicating both the new and previous 11311504Sandreas.sandberg@arm.com * physical registers. 11411504Sandreas.sandberg@arm.com */ 1158947Sandreas.hansson@arm.com RenameInfo rename(const RegId& arch_reg); 11611504Sandreas.sandberg@arm.com 11711504Sandreas.sandberg@arm.com /** 1188947Sandreas.hansson@arm.com * Look up the physical register mapped to an architectural register. 11911504Sandreas.sandberg@arm.com * @param arch_reg The architectural register to look up. 12011504Sandreas.sandberg@arm.com * @return The physical register it is currently mapped to. 12111504Sandreas.sandberg@arm.com */ 1228947Sandreas.hansson@arm.com PhysRegIdPtr lookup(const RegId& arch_reg) const 12311504Sandreas.sandberg@arm.com { 12411504Sandreas.sandberg@arm.com assert(arch_reg.flatIndex() <= map.size()); 12511504Sandreas.sandberg@arm.com return map[arch_reg.flatIndex()]; 12611504Sandreas.sandberg@arm.com } 12711542Sandreas.sandberg@arm.com 12811542Sandreas.sandberg@arm.com /** 12911542Sandreas.sandberg@arm.com * Update rename map with a specific mapping. Generally used to 13011542Sandreas.sandberg@arm.com * roll back to old mappings on a squash. 13111504Sandreas.sandberg@arm.com * @param arch_reg The architectural register to remap. 13211504Sandreas.sandberg@arm.com * @param phys_reg The physical register to remap it to. 13311504Sandreas.sandberg@arm.com */ 13411504Sandreas.sandberg@arm.com void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg) 13511542Sandreas.sandberg@arm.com { 13611504Sandreas.sandberg@arm.com assert(arch_reg.flatIndex() <= map.size()); 13711504Sandreas.sandberg@arm.com map[arch_reg.flatIndex()] = phys_reg; 13811504Sandreas.sandberg@arm.com } 13911504Sandreas.sandberg@arm.com 14011504Sandreas.sandberg@arm.com /** Return the number of free entries on the associated free list. */ 14112563Sgabeblack@google.com unsigned numFreeEntries() const { return freeList->numFreeRegs(); } 1422929Sktlim@umich.edu}; 1432929Sktlim@umich.edu 14411504Sandreas.sandberg@arm.com 1454937Sstever@gmail.com/** 1462929Sktlim@umich.edu * Unified register rename map for all classes of registers. Wraps a 14711504Sandreas.sandberg@arm.com * set of class-specific rename maps. Methods that do not specify a 1482929Sktlim@umich.edu * register class (e.g., rename()) take register ids, 14911504Sandreas.sandberg@arm.com * while methods that do specify a register class (e.g., renameInt()) 15011504Sandreas.sandberg@arm.com * take register indices. 1512929Sktlim@umich.edu */ 15211504Sandreas.sandberg@arm.comclass UnifiedRenameMap 15311504Sandreas.sandberg@arm.com{ 1542929Sktlim@umich.edu private: 15511504Sandreas.sandberg@arm.com 15611504Sandreas.sandberg@arm.com /** The integer register rename map */ 15711504Sandreas.sandberg@arm.com SimpleRenameMap intMap; 15811504Sandreas.sandberg@arm.com 15911504Sandreas.sandberg@arm.com /** The floating-point register rename map */ 16011504Sandreas.sandberg@arm.com SimpleRenameMap floatMap; 16111504Sandreas.sandberg@arm.com 16211504Sandreas.sandberg@arm.com /** The condition-code register rename map */ 16311504Sandreas.sandberg@arm.com SimpleRenameMap ccMap; 16411504Sandreas.sandberg@arm.com 16511504Sandreas.sandberg@arm.com /** 16611504Sandreas.sandberg@arm.com * The register file object is used only to get PhysRegIdPtr 16711542Sandreas.sandberg@arm.com * on MiscRegs, as they are stored in it. 16812563Sgabeblack@google.com */ 16912563Sgabeblack@google.com PhysRegFile *regFile; 17011504Sandreas.sandberg@arm.com 17111504Sandreas.sandberg@arm.com public: 17212563Sgabeblack@google.com 17312563Sgabeblack@google.com typedef SimpleRenameMap::RenameInfo RenameInfo; 17411504Sandreas.sandberg@arm.com 17511542Sandreas.sandberg@arm.com /** Default constructor. init() must be called prior to use. */ 17612563Sgabeblack@google.com UnifiedRenameMap() : regFile(nullptr) {}; 17712563Sgabeblack@google.com 17811504Sandreas.sandberg@arm.com /** Destructor. */ 17911504Sandreas.sandberg@arm.com ~UnifiedRenameMap() {}; 18012563Sgabeblack@google.com 18111504Sandreas.sandberg@arm.com /** Initializes rename map with given parameters. */ 18211504Sandreas.sandberg@arm.com void init(PhysRegFile *_regFile, 1832929Sktlim@umich.edu RegIndex _intZeroReg, 1842929Sktlim@umich.edu RegIndex _floatZeroReg, 1852929Sktlim@umich.edu UnifiedFreeList *freeList); 18611504Sandreas.sandberg@arm.com 1872929Sktlim@umich.edu /** 1882929Sktlim@umich.edu * Tell rename map to get a new free physical register to remap 1892929Sktlim@umich.edu * the specified architectural register. This version takes a 1902929Sktlim@umich.edu * RegId and reads the appropriate class-specific rename table. 19111504Sandreas.sandberg@arm.com * @param arch_reg The architectural register id to remap. 1922997Sstever@eecs.umich.edu * @return A RenameInfo pair indicating both the new and previous 1932929Sktlim@umich.edu * physical registers. 19411504Sandreas.sandberg@arm.com */ 19511504Sandreas.sandberg@arm.com RenameInfo rename(const RegId& arch_reg) 19611504Sandreas.sandberg@arm.com { 1972929Sktlim@umich.edu switch (arch_reg.classValue()) { 19811504Sandreas.sandberg@arm.com case IntRegClass: 19911504Sandreas.sandberg@arm.com return intMap.rename(arch_reg); 2002929Sktlim@umich.edu case FloatRegClass: 20111504Sandreas.sandberg@arm.com return floatMap.rename(arch_reg); 20211504Sandreas.sandberg@arm.com case CCRegClass: 2032997Sstever@eecs.umich.edu return ccMap.rename(arch_reg); 20411504Sandreas.sandberg@arm.com case MiscRegClass: 20511504Sandreas.sandberg@arm.com { 20611504Sandreas.sandberg@arm.com // misc regs aren't really renamed, just remapped 20711504Sandreas.sandberg@arm.com PhysRegIdPtr phys_reg = lookup(arch_reg); 2082997Sstever@eecs.umich.edu // Set the new register to the previous one to keep the same 20911504Sandreas.sandberg@arm.com // mapping throughout the execution. 21011504Sandreas.sandberg@arm.com return RenameInfo(phys_reg, phys_reg); 21111504Sandreas.sandberg@arm.com } 21211504Sandreas.sandberg@arm.com 21311504Sandreas.sandberg@arm.com default: 21411504Sandreas.sandberg@arm.com panic("rename rename(): unknown reg class %s\n", 2152929Sktlim@umich.edu arch_reg.className()); 2162997Sstever@eecs.umich.edu } 2178120Sgblack@eecs.umich.edu } 21811504Sandreas.sandberg@arm.com 2192997Sstever@eecs.umich.edu /** 22011504Sandreas.sandberg@arm.com * Look up the physical register mapped to an architectural register. 2212929Sktlim@umich.edu * This version takes a flattened architectural register id 2222997Sstever@eecs.umich.edu * and calls the appropriate class-specific rename table. 2232929Sktlim@umich.edu * @param arch_reg The architectural register to look up. 22411504Sandreas.sandberg@arm.com * @return The physical register it is currently mapped to. 22511504Sandreas.sandberg@arm.com */ 2262929Sktlim@umich.edu PhysRegIdPtr lookup(const RegId& arch_reg) const 22711504Sandreas.sandberg@arm.com { 22811504Sandreas.sandberg@arm.com switch (arch_reg.classValue()) { 2293691Shsul@eecs.umich.edu case IntRegClass: 23011504Sandreas.sandberg@arm.com return intMap.lookup(arch_reg); 2313005Sstever@eecs.umich.edu 23211504Sandreas.sandberg@arm.com case FloatRegClass: 23311105Spower.jg@gmail.com return floatMap.lookup(arch_reg); 23411504Sandreas.sandberg@arm.com 23511504Sandreas.sandberg@arm.com case CCRegClass: 23611504Sandreas.sandberg@arm.com return ccMap.lookup(arch_reg); 2376166Ssteve.reinhardt@amd.com 23811504Sandreas.sandberg@arm.com case MiscRegClass: 23911504Sandreas.sandberg@arm.com // misc regs aren't really renamed, they keep the same 24011504Sandreas.sandberg@arm.com // mapping throughout the execution. 24112563Sgabeblack@google.com return regFile->getMiscRegId(arch_reg.flatIndex()); 24211504Sandreas.sandberg@arm.com 24311504Sandreas.sandberg@arm.com default: 24411504Sandreas.sandberg@arm.com panic("rename lookup(): unknown reg class %s\n", 24511504Sandreas.sandberg@arm.com arch_reg.className()); 24611504Sandreas.sandberg@arm.com } 24711504Sandreas.sandberg@arm.com } 24811504Sandreas.sandberg@arm.com 24911504Sandreas.sandberg@arm.com /** 25011504Sandreas.sandberg@arm.com * Update rename map with a specific mapping. Generally used to 25111504Sandreas.sandberg@arm.com * roll back to old mappings on a squash. This version takes a 252 * flattened architectural register id and calls the 253 * appropriate class-specific rename table. 254 * @param arch_reg The architectural register to remap. 255 * @param phys_reg The physical register to remap it to. 256 */ 257 void setEntry(const RegId& arch_reg, PhysRegIdPtr phys_reg) 258 { 259 switch (arch_reg.classValue()) { 260 case IntRegClass: 261 assert(phys_reg->isIntPhysReg()); 262 return intMap.setEntry(arch_reg, phys_reg); 263 264 case FloatRegClass: 265 assert(phys_reg->isFloatPhysReg()); 266 return floatMap.setEntry(arch_reg, phys_reg); 267 268 case CCRegClass: 269 assert(phys_reg->isCCPhysReg()); 270 return ccMap.setEntry(arch_reg, phys_reg); 271 272 case MiscRegClass: 273 // Misc registers do not actually rename, so don't change 274 // their mappings. We end up here when a commit or squash 275 // tries to update or undo a hardwired misc reg nmapping, 276 // which should always be setting it to what it already is. 277 assert(phys_reg == lookup(arch_reg)); 278 return; 279 280 default: 281 panic("rename setEntry(): unknown reg class %s\n", 282 arch_reg.className()); 283 } 284 } 285 286 /** 287 * Return the minimum number of free entries across all of the 288 * register classes. The minimum is used so we guarantee that 289 * this number of entries is available regardless of which class 290 * of registers is requested. 291 */ 292 unsigned numFreeEntries() const 293 { 294 return std::min(intMap.numFreeEntries(), floatMap.numFreeEntries()); 295 } 296 297 /** 298 * Return whether there are enough registers to serve the request. 299 */ 300 bool canRename(uint32_t intRegs, uint32_t floatRegs, uint32_t ccRegs) const 301 { 302 return intRegs <= intMap.numFreeEntries() && 303 floatRegs <= floatMap.numFreeEntries() && 304 ccRegs <= ccMap.numFreeEntries(); 305 } 306 307}; 308 309#endif //__CPU_O3_RENAME_MAP_HH__ 310