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