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