rename_map.cc revision 3867
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" 341060SN/A 351464SN/Ausing namespace std; 361464SN/A 372329SN/A// @todo: Consider making inline bool functions that determine if the 382329SN/A// register is a logical int, logical fp, physical int, physical fp, 392329SN/A// etc. 401060SN/A 412292SN/ASimpleRenameMap::~SimpleRenameMap() 421060SN/A{ 432292SN/A} 442292SN/A 452292SN/Avoid 462292SN/ASimpleRenameMap::init(unsigned _numLogicalIntRegs, 472292SN/A unsigned _numPhysicalIntRegs, 482292SN/A PhysRegIndex &ireg_idx, 492292SN/A 502292SN/A unsigned _numLogicalFloatRegs, 512292SN/A unsigned _numPhysicalFloatRegs, 522292SN/A PhysRegIndex &freg_idx, 532292SN/A 542292SN/A unsigned _numMiscRegs, 552292SN/A 562292SN/A RegIndex _intZeroReg, 572292SN/A RegIndex _floatZeroReg, 582292SN/A 592292SN/A int map_id, 602292SN/A bool bindRegs) 612292SN/A{ 622292SN/A id = map_id; 632292SN/A 642292SN/A numLogicalIntRegs = _numLogicalIntRegs; 652292SN/A 662292SN/A numLogicalFloatRegs = _numLogicalFloatRegs; 672292SN/A 682292SN/A numPhysicalIntRegs = _numPhysicalIntRegs; 692292SN/A 702292SN/A numPhysicalFloatRegs = _numPhysicalFloatRegs; 712292SN/A 722292SN/A numMiscRegs = _numMiscRegs; 732292SN/A 742292SN/A intZeroReg = _intZeroReg; 752292SN/A floatZeroReg = _floatZeroReg; 762292SN/A 772292SN/A DPRINTF(Rename, "Creating rename map %i. Phys: %i / %i, Float: " 782292SN/A "%i / %i.\n", id, numLogicalIntRegs, numPhysicalIntRegs, 791060SN/A numLogicalFloatRegs, numPhysicalFloatRegs); 801060SN/A 811060SN/A numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs; 821060SN/A 831060SN/A numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs; 841060SN/A 852292SN/A //Create the rename maps 862292SN/A intRenameMap.resize(numLogicalIntRegs); 872292SN/A floatRenameMap.resize(numLogicalRegs); 881060SN/A 892292SN/A if (bindRegs) { 902292SN/A DPRINTF(Rename, "Binding registers into rename map %i",id); 911060SN/A 922292SN/A // Initialize the entries in the integer rename map to point to the 932292SN/A // physical registers of the same index 942292SN/A for (RegIndex index = 0; index < numLogicalIntRegs; ++index) 952292SN/A { 962292SN/A intRenameMap[index].physical_reg = ireg_idx++; 972292SN/A } 982292SN/A 992292SN/A // Initialize the entries in the floating point rename map to point to 1002292SN/A // the physical registers of the same index 1012292SN/A // Although the index refers purely to architected registers, because 1022292SN/A // the floating reg indices come after the integer reg indices, they 1032292SN/A // may exceed the size of a normal RegIndex (short). 1042329SN/A for (PhysRegIndex index = numLogicalIntRegs; 1052329SN/A index < numLogicalRegs; ++index) 1062292SN/A { 1072292SN/A floatRenameMap[index].physical_reg = freg_idx++; 1082292SN/A } 1092292SN/A } else { 1102292SN/A DPRINTF(Rename, "Binding registers into rename map %i",id); 1112292SN/A 1122292SN/A PhysRegIndex temp_ireg = ireg_idx; 1132292SN/A 1142292SN/A for (RegIndex index = 0; index < numLogicalIntRegs; ++index) 1152292SN/A { 1162292SN/A intRenameMap[index].physical_reg = temp_ireg++; 1172292SN/A } 1182292SN/A 1192292SN/A PhysRegIndex temp_freg = freg_idx; 1202292SN/A 1212292SN/A for (PhysRegIndex index = numLogicalIntRegs; 1222292SN/A index < numLogicalRegs; ++index) 1232292SN/A { 1242292SN/A floatRenameMap[index].physical_reg = temp_freg++; 1252292SN/A } 1261060SN/A } 1271061SN/A} 1281061SN/A 1291060SN/Avoid 1301060SN/ASimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr) 1311060SN/A{ 1321060SN/A freeList = fl_ptr; 1331060SN/A} 1341060SN/A 1351060SN/A 1361060SN/ASimpleRenameMap::RenameInfo 1371060SN/ASimpleRenameMap::rename(RegIndex arch_reg) 1381060SN/A{ 1391060SN/A PhysRegIndex renamed_reg; 1401060SN/A PhysRegIndex prev_reg; 1411060SN/A 1421060SN/A if (arch_reg < numLogicalIntRegs) { 1431060SN/A 1441060SN/A // Record the current physical register that is renamed to the 1451060SN/A // requested architected register. 1461060SN/A prev_reg = intRenameMap[arch_reg].physical_reg; 1471060SN/A 1482329SN/A // If it's not referencing the zero register, then rename the 1492329SN/A // register. 1501060SN/A if (arch_reg != intZeroReg) { 1511060SN/A renamed_reg = freeList->getIntReg(); 1521060SN/A 1531060SN/A intRenameMap[arch_reg].physical_reg = renamed_reg; 1541060SN/A 1551061SN/A assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs); 1561061SN/A 1571060SN/A } else { 1581060SN/A // Otherwise return the zero register so nothing bad happens. 1591060SN/A renamed_reg = intZeroReg; 1601060SN/A } 1611060SN/A } else if (arch_reg < numLogicalRegs) { 1621060SN/A // Record the current physical register that is renamed to the 1631060SN/A // requested architected register. 1641060SN/A prev_reg = floatRenameMap[arch_reg].physical_reg; 1651060SN/A 1662329SN/A // If it's not referencing the zero register, then rename the 1672329SN/A // register. 1681060SN/A if (arch_reg != floatZeroReg) { 1691060SN/A renamed_reg = freeList->getFloatReg(); 1701060SN/A 1711060SN/A floatRenameMap[arch_reg].physical_reg = renamed_reg; 1721060SN/A 1731061SN/A assert(renamed_reg < numPhysicalRegs && 1741061SN/A renamed_reg >= numPhysicalIntRegs); 1751060SN/A } else { 1761060SN/A // Otherwise return the zero register so nothing bad happens. 1771060SN/A renamed_reg = floatZeroReg; 1781060SN/A } 1791060SN/A } else { 1801060SN/A // Subtract off the base offset for miscellaneous registers. 1811060SN/A arch_reg = arch_reg - numLogicalRegs; 1821060SN/A 1833867Sbinkertn@umich.edu DPRINTF(Rename, "Renamed misc reg %d\n", arch_reg); 1843867Sbinkertn@umich.edu 1852329SN/A // No renaming happens to the misc. registers. They are 1862329SN/A // simply the registers that come after all the physical 1872329SN/A // registers; thus take the base architected register and add 1882329SN/A // the physical registers to it. 1891060SN/A renamed_reg = arch_reg + numPhysicalRegs; 1901060SN/A 1911060SN/A // Set the previous register to the same register; mainly it must be 1921060SN/A // known that the prev reg was outside the range of normal registers 1931060SN/A // so the free list can avoid adding it. 1941060SN/A prev_reg = renamed_reg; 1951060SN/A 1961061SN/A assert(renamed_reg < numPhysicalRegs + numMiscRegs); 1971060SN/A } 1981060SN/A 1993867Sbinkertn@umich.edu DPRINTF(Rename, "Renamed reg %d to physical reg %d old mapping was %d\n", 2003867Sbinkertn@umich.edu arch_reg, renamed_reg, prev_reg); 2013867Sbinkertn@umich.edu 2021060SN/A return RenameInfo(renamed_reg, prev_reg); 2031060SN/A} 2041060SN/A 2051060SN/APhysRegIndex 2061060SN/ASimpleRenameMap::lookup(RegIndex arch_reg) 2071060SN/A{ 2081060SN/A if (arch_reg < numLogicalIntRegs) { 2091060SN/A return intRenameMap[arch_reg].physical_reg; 2101060SN/A } else if (arch_reg < numLogicalRegs) { 2111060SN/A return floatRenameMap[arch_reg].physical_reg; 2121060SN/A } else { 2131060SN/A // Subtract off the misc registers offset. 2141060SN/A arch_reg = arch_reg - numLogicalRegs; 2151060SN/A 2161060SN/A // Misc. regs don't rename, so simply add the base arch reg to 2171060SN/A // the number of physical registers. 2181060SN/A return numPhysicalRegs + arch_reg; 2191060SN/A } 2201060SN/A} 2211060SN/A 2221060SN/Avoid 2231060SN/ASimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg) 2241060SN/A{ 2252329SN/A // In this implementation the miscellaneous registers do not 2262329SN/A // actually rename, so this function does not allow you to try to 2272329SN/A // change their mappings. 2281060SN/A if (arch_reg < numLogicalIntRegs) { 2291060SN/A DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n", 2301060SN/A (int)arch_reg, renamed_reg); 2311060SN/A 2321060SN/A intRenameMap[arch_reg].physical_reg = renamed_reg; 2332292SN/A } else if (arch_reg < numLogicalIntRegs + numLogicalFloatRegs) { 2341060SN/A DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n", 2351061SN/A (int)arch_reg - numLogicalIntRegs, renamed_reg); 2361060SN/A 2371060SN/A floatRenameMap[arch_reg].physical_reg = renamed_reg; 2381060SN/A } 2391060SN/A} 2401060SN/A 2411060SN/Aint 2421060SN/ASimpleRenameMap::numFreeEntries() 2431060SN/A{ 2441060SN/A int free_int_regs = freeList->numFreeIntRegs(); 2451060SN/A int free_float_regs = freeList->numFreeFloatRegs(); 2461060SN/A 2471060SN/A if (free_int_regs < free_float_regs) { 2481060SN/A return free_int_regs; 2491060SN/A } else { 2501060SN/A return free_float_regs; 2511060SN/A } 2521060SN/A} 253