rename_map.cc revision 8232
11689SN/A/* 21689SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 291689SN/A */ 301464SN/A 311464SN/A#include <vector> 321060SN/A 331717SN/A#include "cpu/o3/rename_map.hh" 348232Snate@binkert.org#include "debug/Rename.hh" 351060SN/A 361464SN/Ausing namespace std; 371464SN/A 382329SN/A// @todo: Consider making inline bool functions that determine if the 392329SN/A// register is a logical int, logical fp, physical int, physical fp, 402329SN/A// etc. 411060SN/A 422292SN/ASimpleRenameMap::~SimpleRenameMap() 431060SN/A{ 442292SN/A} 452292SN/A 462292SN/Avoid 472292SN/ASimpleRenameMap::init(unsigned _numLogicalIntRegs, 482292SN/A unsigned _numPhysicalIntRegs, 492292SN/A PhysRegIndex &ireg_idx, 502292SN/A 512292SN/A unsigned _numLogicalFloatRegs, 522292SN/A unsigned _numPhysicalFloatRegs, 532292SN/A PhysRegIndex &freg_idx, 542292SN/A 552292SN/A unsigned _numMiscRegs, 562292SN/A 572292SN/A RegIndex _intZeroReg, 582292SN/A RegIndex _floatZeroReg, 592292SN/A 602292SN/A int map_id, 612292SN/A bool bindRegs) 622292SN/A{ 632292SN/A id = map_id; 642292SN/A 652292SN/A numLogicalIntRegs = _numLogicalIntRegs; 662292SN/A 672292SN/A numLogicalFloatRegs = _numLogicalFloatRegs; 682292SN/A 692292SN/A numPhysicalIntRegs = _numPhysicalIntRegs; 702292SN/A 712292SN/A numPhysicalFloatRegs = _numPhysicalFloatRegs; 722292SN/A 732292SN/A numMiscRegs = _numMiscRegs; 742292SN/A 752292SN/A intZeroReg = _intZeroReg; 762292SN/A floatZeroReg = _floatZeroReg; 772292SN/A 782292SN/A DPRINTF(Rename, "Creating rename map %i. Phys: %i / %i, Float: " 792292SN/A "%i / %i.\n", id, numLogicalIntRegs, numPhysicalIntRegs, 801060SN/A numLogicalFloatRegs, numPhysicalFloatRegs); 811060SN/A 821060SN/A numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs; 831060SN/A 841060SN/A numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs; 851060SN/A 862292SN/A //Create the rename maps 872292SN/A intRenameMap.resize(numLogicalIntRegs); 882292SN/A floatRenameMap.resize(numLogicalRegs); 891060SN/A 902292SN/A if (bindRegs) { 912292SN/A DPRINTF(Rename, "Binding registers into rename map %i",id); 921060SN/A 932292SN/A // Initialize the entries in the integer rename map to point to the 942292SN/A // physical registers of the same index 952292SN/A for (RegIndex index = 0; index < numLogicalIntRegs; ++index) 962292SN/A { 972292SN/A intRenameMap[index].physical_reg = ireg_idx++; 982292SN/A } 992292SN/A 1002292SN/A // Initialize the entries in the floating point rename map to point to 1012292SN/A // the physical registers of the same index 1022292SN/A // Although the index refers purely to architected registers, because 1032292SN/A // the floating reg indices come after the integer reg indices, they 1042292SN/A // may exceed the size of a normal RegIndex (short). 1052329SN/A for (PhysRegIndex index = numLogicalIntRegs; 1062329SN/A index < numLogicalRegs; ++index) 1072292SN/A { 1082292SN/A floatRenameMap[index].physical_reg = freg_idx++; 1092292SN/A } 1102292SN/A } else { 1112292SN/A DPRINTF(Rename, "Binding registers into rename map %i",id); 1122292SN/A 1132292SN/A PhysRegIndex temp_ireg = ireg_idx; 1142292SN/A 1152292SN/A for (RegIndex index = 0; index < numLogicalIntRegs; ++index) 1162292SN/A { 1172292SN/A intRenameMap[index].physical_reg = temp_ireg++; 1182292SN/A } 1192292SN/A 1202292SN/A PhysRegIndex temp_freg = freg_idx; 1212292SN/A 1222292SN/A for (PhysRegIndex index = numLogicalIntRegs; 1232292SN/A index < numLogicalRegs; ++index) 1242292SN/A { 1252292SN/A floatRenameMap[index].physical_reg = temp_freg++; 1262292SN/A } 1271060SN/A } 1281061SN/A} 1291061SN/A 1301060SN/Avoid 1311060SN/ASimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr) 1321060SN/A{ 1331060SN/A freeList = fl_ptr; 1341060SN/A} 1351060SN/A 1361060SN/A 1371060SN/ASimpleRenameMap::RenameInfo 1381060SN/ASimpleRenameMap::rename(RegIndex arch_reg) 1391060SN/A{ 1401060SN/A PhysRegIndex renamed_reg; 1411060SN/A PhysRegIndex prev_reg; 1421060SN/A 1431060SN/A if (arch_reg < numLogicalIntRegs) { 1441060SN/A 1451060SN/A // Record the current physical register that is renamed to the 1461060SN/A // requested architected register. 1471060SN/A prev_reg = intRenameMap[arch_reg].physical_reg; 1481060SN/A 1492329SN/A // If it's not referencing the zero register, then rename the 1502329SN/A // register. 1511060SN/A if (arch_reg != intZeroReg) { 1521060SN/A renamed_reg = freeList->getIntReg(); 1531060SN/A 1541060SN/A intRenameMap[arch_reg].physical_reg = renamed_reg; 1551060SN/A 1561061SN/A assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs); 1571061SN/A 1581060SN/A } else { 1591060SN/A // Otherwise return the zero register so nothing bad happens. 1601060SN/A renamed_reg = intZeroReg; 1611060SN/A } 1621060SN/A } else if (arch_reg < numLogicalRegs) { 1631060SN/A // Record the current physical register that is renamed to the 1641060SN/A // requested architected register. 1651060SN/A prev_reg = floatRenameMap[arch_reg].physical_reg; 1661060SN/A 1672329SN/A // If it's not referencing the zero register, then rename the 1682329SN/A // register. 1694642Sgblack@eecs.umich.edu#if THE_ISA == ALPHA_ISA 1701060SN/A if (arch_reg != floatZeroReg) { 1714642Sgblack@eecs.umich.edu#endif 1721060SN/A renamed_reg = freeList->getFloatReg(); 1731060SN/A 1741060SN/A floatRenameMap[arch_reg].physical_reg = renamed_reg; 1751060SN/A 1761061SN/A assert(renamed_reg < numPhysicalRegs && 1771061SN/A renamed_reg >= numPhysicalIntRegs); 1784642Sgblack@eecs.umich.edu#if THE_ISA == ALPHA_ISA 1791060SN/A } else { 1801060SN/A // Otherwise return the zero register so nothing bad happens. 1811060SN/A renamed_reg = floatZeroReg; 1821060SN/A } 1834642Sgblack@eecs.umich.edu#endif 1841060SN/A } else { 1851060SN/A // Subtract off the base offset for miscellaneous registers. 1861060SN/A arch_reg = arch_reg - numLogicalRegs; 1871060SN/A 1883867Sbinkertn@umich.edu DPRINTF(Rename, "Renamed misc reg %d\n", arch_reg); 1893867Sbinkertn@umich.edu 1902329SN/A // No renaming happens to the misc. registers. They are 1912329SN/A // simply the registers that come after all the physical 1922329SN/A // registers; thus take the base architected register and add 1932329SN/A // the physical registers to it. 1941060SN/A renamed_reg = arch_reg + numPhysicalRegs; 1951060SN/A 1961060SN/A // Set the previous register to the same register; mainly it must be 1971060SN/A // known that the prev reg was outside the range of normal registers 1981060SN/A // so the free list can avoid adding it. 1991060SN/A prev_reg = renamed_reg; 2001060SN/A } 2011060SN/A 2023867Sbinkertn@umich.edu DPRINTF(Rename, "Renamed reg %d to physical reg %d old mapping was %d\n", 2033867Sbinkertn@umich.edu arch_reg, renamed_reg, prev_reg); 2043867Sbinkertn@umich.edu 2051060SN/A return RenameInfo(renamed_reg, prev_reg); 2061060SN/A} 2071060SN/A 2081060SN/APhysRegIndex 2091060SN/ASimpleRenameMap::lookup(RegIndex arch_reg) 2101060SN/A{ 2111060SN/A if (arch_reg < numLogicalIntRegs) { 2121060SN/A return intRenameMap[arch_reg].physical_reg; 2131060SN/A } else if (arch_reg < numLogicalRegs) { 2141060SN/A return floatRenameMap[arch_reg].physical_reg; 2151060SN/A } else { 2161060SN/A // Subtract off the misc registers offset. 2171060SN/A arch_reg = arch_reg - numLogicalRegs; 2181060SN/A 2191060SN/A // Misc. regs don't rename, so simply add the base arch reg to 2201060SN/A // the number of physical registers. 2211060SN/A return numPhysicalRegs + arch_reg; 2221060SN/A } 2231060SN/A} 2241060SN/A 2251060SN/Avoid 2261060SN/ASimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg) 2271060SN/A{ 2282329SN/A // In this implementation the miscellaneous registers do not 2292329SN/A // actually rename, so this function does not allow you to try to 2302329SN/A // change their mappings. 2311060SN/A if (arch_reg < numLogicalIntRegs) { 2321060SN/A DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n", 2331060SN/A (int)arch_reg, renamed_reg); 2341060SN/A 2351060SN/A intRenameMap[arch_reg].physical_reg = renamed_reg; 2362292SN/A } else if (arch_reg < numLogicalIntRegs + numLogicalFloatRegs) { 2371060SN/A DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n", 2381061SN/A (int)arch_reg - numLogicalIntRegs, renamed_reg); 2391060SN/A 2401060SN/A floatRenameMap[arch_reg].physical_reg = renamed_reg; 2411060SN/A } 2421060SN/A} 2431060SN/A 2441060SN/Aint 2451060SN/ASimpleRenameMap::numFreeEntries() 2461060SN/A{ 2471060SN/A int free_int_regs = freeList->numFreeIntRegs(); 2481060SN/A int free_float_regs = freeList->numFreeFloatRegs(); 2491060SN/A 2501060SN/A if (free_int_regs < free_float_regs) { 2511060SN/A return free_int_regs; 2521060SN/A } else { 2531060SN/A return free_float_regs; 2541060SN/A } 2551060SN/A} 256