rename_map.cc revision 2665
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
371060SN/A// Todo: Consider making functions inline.  Avoid having things that are
381060SN/A// using the zero register or misc registers from adding on the registers
391061SN/A// to the free list.  Possibly remove the direct communication between
401061SN/A// this and the freelist.  Considering making inline bool functions that
411061SN/A// determine if the register is a logical int, logical fp, physical int,
421061SN/A// physical fp, etc.
431060SN/A
441060SN/ASimpleRenameMap::SimpleRenameMap(unsigned _numLogicalIntRegs,
451060SN/A                                 unsigned _numPhysicalIntRegs,
461060SN/A                                 unsigned _numLogicalFloatRegs,
471060SN/A                                 unsigned _numPhysicalFloatRegs,
481060SN/A                                 unsigned _numMiscRegs,
491060SN/A                                 RegIndex _intZeroReg,
501060SN/A                                 RegIndex _floatZeroReg)
511060SN/A    : numLogicalIntRegs(_numLogicalIntRegs),
521060SN/A      numPhysicalIntRegs(_numPhysicalIntRegs),
531060SN/A      numLogicalFloatRegs(_numLogicalFloatRegs),
541060SN/A      numPhysicalFloatRegs(_numPhysicalFloatRegs),
551060SN/A      numMiscRegs(_numMiscRegs),
561060SN/A      intZeroReg(_intZeroReg),
571060SN/A      floatZeroReg(_floatZeroReg)
581060SN/A{
591060SN/A    DPRINTF(Rename, "Rename: Creating rename map.  Phys: %i / %i, Float: "
601060SN/A            "%i / %i.\n", numLogicalIntRegs, numPhysicalIntRegs,
611060SN/A            numLogicalFloatRegs, numPhysicalFloatRegs);
621060SN/A
631060SN/A    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
641060SN/A
651060SN/A    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
661060SN/A
671060SN/A    //Create the rename maps, and their scoreboards.
681060SN/A    intRenameMap = new RenameEntry[numLogicalIntRegs];
691061SN/A    floatRenameMap = new RenameEntry[numLogicalRegs];
701060SN/A
711061SN/A    // Should combine this into one scoreboard.
721060SN/A    intScoreboard.resize(numPhysicalIntRegs);
731061SN/A    floatScoreboard.resize(numPhysicalRegs);
741061SN/A    miscScoreboard.resize(numPhysicalRegs + numMiscRegs);
751060SN/A
761060SN/A    // Initialize the entries in the integer rename map to point to the
771060SN/A    // physical registers of the same index, and consider each register
781060SN/A    // ready until the first rename occurs.
791060SN/A    for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
801060SN/A    {
811060SN/A        intRenameMap[index].physical_reg = index;
821060SN/A        intScoreboard[index] = 1;
831060SN/A    }
841060SN/A
851060SN/A    // Initialize the rest of the physical registers (the ones that don't
861060SN/A    // directly map to a logical register) as unready.
871060SN/A    for (PhysRegIndex index = numLogicalIntRegs;
881060SN/A         index < numPhysicalIntRegs;
891060SN/A         ++index)
901060SN/A    {
911060SN/A        intScoreboard[index] = 0;
921060SN/A    }
931060SN/A
941061SN/A    int float_reg_idx = numPhysicalIntRegs;
951061SN/A
961060SN/A    // Initialize the entries in the floating point rename map to point to
971060SN/A    // the physical registers of the same index, and consider each register
981060SN/A    // ready until the first rename occurs.
991061SN/A    // Although the index refers purely to architected registers, because
1001061SN/A    // the floating reg indices come after the integer reg indices, they
1011061SN/A    // may exceed the size of a normal RegIndex (short).
1021061SN/A    for (PhysRegIndex index = numLogicalIntRegs;
1031061SN/A         index < numLogicalRegs; ++index)
1041060SN/A    {
1051061SN/A        floatRenameMap[index].physical_reg = float_reg_idx++;
1061061SN/A    }
1071061SN/A
1081062SN/A    for (PhysRegIndex index = numPhysicalIntRegs;
1091061SN/A         index < numPhysicalIntRegs + numLogicalFloatRegs; ++index)
1101061SN/A    {
1111060SN/A        floatScoreboard[index] = 1;
1121060SN/A    }
1131060SN/A
1141060SN/A    // Initialize the rest of the physical registers (the ones that don't
1151060SN/A    // directly map to a logical register) as unready.
1161061SN/A    for (PhysRegIndex index = numPhysicalIntRegs + numLogicalFloatRegs;
1171061SN/A         index < numPhysicalRegs;
1181060SN/A         ++index)
1191060SN/A    {
1201060SN/A        floatScoreboard[index] = 0;
1211060SN/A    }
1221060SN/A
1231060SN/A    // Initialize the entries in the misc register scoreboard to be ready.
1241062SN/A    for (PhysRegIndex index = numPhysicalRegs;
1251061SN/A         index < numPhysicalRegs + numMiscRegs; ++index)
1261060SN/A    {
1271060SN/A        miscScoreboard[index] = 1;
1281060SN/A    }
1291060SN/A}
1301060SN/A
1311061SN/ASimpleRenameMap::~SimpleRenameMap()
1321061SN/A{
1331061SN/A    // Delete the rename maps as they were allocated with new.
1341061SN/A    delete [] intRenameMap;
1351061SN/A    delete [] floatRenameMap;
1361061SN/A}
1371061SN/A
1381060SN/Avoid
1391060SN/ASimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
1401060SN/A{
1411060SN/A    //Setup the interface to the freelist.
1421060SN/A    freeList = fl_ptr;
1431060SN/A}
1441060SN/A
1451060SN/A
1461060SN/A// Don't allow this stage to fault; force that check to the rename stage.
1471060SN/A// Simply ask to rename a logical register and get back a new physical
1481060SN/A// register index.
1491060SN/ASimpleRenameMap::RenameInfo
1501060SN/ASimpleRenameMap::rename(RegIndex arch_reg)
1511060SN/A{
1521060SN/A    PhysRegIndex renamed_reg;
1531060SN/A    PhysRegIndex prev_reg;
1541060SN/A
1551060SN/A    if (arch_reg < numLogicalIntRegs) {
1561060SN/A
1571060SN/A        // Record the current physical register that is renamed to the
1581060SN/A        // requested architected register.
1591060SN/A        prev_reg = intRenameMap[arch_reg].physical_reg;
1601060SN/A
1611060SN/A        // If it's not referencing the zero register, then mark the register
1621060SN/A        // as not ready.
1631060SN/A        if (arch_reg != intZeroReg) {
1641060SN/A            // Get a free physical register to rename to.
1651060SN/A            renamed_reg = freeList->getIntReg();
1661060SN/A
1671060SN/A            // Update the integer rename map.
1681060SN/A            intRenameMap[arch_reg].physical_reg = renamed_reg;
1691060SN/A
1701061SN/A            assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);
1711061SN/A
1721060SN/A            // Mark register as not ready.
1731060SN/A            intScoreboard[renamed_reg] = false;
1741060SN/A        } else {
1751060SN/A            // Otherwise return the zero register so nothing bad happens.
1761060SN/A            renamed_reg = intZeroReg;
1771060SN/A        }
1781060SN/A    } else if (arch_reg < numLogicalRegs) {
1791060SN/A        // Subtract off the base offset for floating point registers.
1801061SN/A//        arch_reg = arch_reg - numLogicalIntRegs;
1811060SN/A
1821060SN/A        // Record the current physical register that is renamed to the
1831060SN/A        // requested architected register.
1841060SN/A        prev_reg = floatRenameMap[arch_reg].physical_reg;
1851060SN/A
1861060SN/A        // If it's not referencing the zero register, then mark the register
1871060SN/A        // as not ready.
1881060SN/A        if (arch_reg != floatZeroReg) {
1891060SN/A            // Get a free floating point register to rename to.
1901060SN/A            renamed_reg = freeList->getFloatReg();
1911060SN/A
1921060SN/A            // Update the floating point rename map.
1931060SN/A            floatRenameMap[arch_reg].physical_reg = renamed_reg;
1941060SN/A
1951061SN/A            assert(renamed_reg < numPhysicalRegs &&
1961061SN/A                   renamed_reg >= numPhysicalIntRegs);
1971061SN/A
1981060SN/A            // Mark register as not ready.
1991060SN/A            floatScoreboard[renamed_reg] = false;
2001060SN/A        } else {
2011060SN/A            // Otherwise return the zero register so nothing bad happens.
2021060SN/A            renamed_reg = floatZeroReg;
2031060SN/A        }
2041060SN/A    } else {
2051060SN/A        // Subtract off the base offset for miscellaneous registers.
2061060SN/A        arch_reg = arch_reg - numLogicalRegs;
2071060SN/A
2081060SN/A        // No renaming happens to the misc. registers.  They are simply the
2091060SN/A        // registers that come after all the  physical registers; thus
2101060SN/A        // take the base architected register and add the physical registers
2111060SN/A        // to it.
2121060SN/A        renamed_reg = arch_reg + numPhysicalRegs;
2131060SN/A
2141060SN/A        // Set the previous register to the same register; mainly it must be
2151060SN/A        // known that the prev reg was outside the range of normal registers
2161060SN/A        // so the free list can avoid adding it.
2171060SN/A        prev_reg = renamed_reg;
2181060SN/A
2191061SN/A        assert(renamed_reg < numPhysicalRegs + numMiscRegs);
2201061SN/A
2211060SN/A        miscScoreboard[renamed_reg] = false;
2221060SN/A    }
2231060SN/A
2241060SN/A    return RenameInfo(renamed_reg, prev_reg);
2251060SN/A}
2261060SN/A
2271060SN/A//Perhaps give this a pair as a return value, of the physical register
2281060SN/A//and whether or not it's ready.
2291060SN/APhysRegIndex
2301060SN/ASimpleRenameMap::lookup(RegIndex arch_reg)
2311060SN/A{
2321060SN/A    if (arch_reg < numLogicalIntRegs) {
2331060SN/A        return intRenameMap[arch_reg].physical_reg;
2341060SN/A    } else if (arch_reg < numLogicalRegs) {
2351060SN/A        // Subtract off the base FP offset.
2361061SN/A//        arch_reg = arch_reg - numLogicalIntRegs;
2371060SN/A
2381060SN/A        return floatRenameMap[arch_reg].physical_reg;
2391060SN/A    } else {
2401060SN/A        // Subtract off the misc registers offset.
2411060SN/A        arch_reg = arch_reg - numLogicalRegs;
2421060SN/A
2431060SN/A        // Misc. regs don't rename, so simply add the base arch reg to
2441060SN/A        // the number of physical registers.
2451060SN/A        return numPhysicalRegs + arch_reg;
2461060SN/A    }
2471060SN/A}
2481060SN/A
2491060SN/Abool
2501060SN/ASimpleRenameMap::isReady(PhysRegIndex phys_reg)
2511060SN/A{
2521060SN/A    if (phys_reg < numPhysicalIntRegs) {
2531060SN/A        return intScoreboard[phys_reg];
2541060SN/A    } else if (phys_reg < numPhysicalRegs) {
2551060SN/A
2561060SN/A        // Subtract off the base FP offset.
2571061SN/A//        phys_reg = phys_reg - numPhysicalIntRegs;
2581060SN/A
2591060SN/A        return floatScoreboard[phys_reg];
2601060SN/A    } else {
2611060SN/A        // Subtract off the misc registers offset.
2621061SN/A//        phys_reg = phys_reg - numPhysicalRegs;
2631060SN/A
2641060SN/A        return miscScoreboard[phys_reg];
2651060SN/A    }
2661060SN/A}
2671060SN/A
2681060SN/A// In this implementation the miscellaneous registers do not actually rename,
2691060SN/A// so this function does not allow you to try to change their mappings.
2701060SN/Avoid
2711060SN/ASimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
2721060SN/A{
2731060SN/A    if (arch_reg < numLogicalIntRegs) {
2741060SN/A        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
2751060SN/A                (int)arch_reg, renamed_reg);
2761060SN/A
2771060SN/A        intRenameMap[arch_reg].physical_reg = renamed_reg;
2781060SN/A    } else {
2791061SN/A        assert(arch_reg < (numLogicalIntRegs + numLogicalFloatRegs));
2801060SN/A
2811060SN/A        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
2821061SN/A                (int)arch_reg - numLogicalIntRegs, renamed_reg);
2831060SN/A
2841060SN/A        floatRenameMap[arch_reg].physical_reg = renamed_reg;
2851060SN/A    }
2861060SN/A}
2871060SN/A
2881060SN/Avoid
2891060SN/ASimpleRenameMap::squash(vector<RegIndex> freed_regs,
2901060SN/A                        vector<UnmapInfo> unmaps)
2911060SN/A{
2921061SN/A    panic("Not sure this function should be called.");
2931061SN/A
2941060SN/A    // Not sure the rename map should be able to access the free list
2951060SN/A    // like this.
2961060SN/A    while (!freed_regs.empty()) {
2971060SN/A        RegIndex free_register = freed_regs.back();
2981060SN/A
2991060SN/A        if (free_register < numPhysicalIntRegs) {
3001060SN/A            freeList->addIntReg(free_register);
3011060SN/A        } else {
3021060SN/A            // Subtract off the base FP dependence tag.
3031060SN/A            free_register = free_register - numPhysicalIntRegs;
3041060SN/A            freeList->addFloatReg(free_register);
3051060SN/A        }
3061060SN/A
3071060SN/A        freed_regs.pop_back();
3081060SN/A    }
3091060SN/A
3101060SN/A    // Take unmap info and roll back the rename map.
3111060SN/A}
3121060SN/A
3131060SN/Avoid
3141060SN/ASimpleRenameMap::markAsReady(PhysRegIndex ready_reg)
3151060SN/A{
3161060SN/A    DPRINTF(Rename, "Rename map: Marking register %i as ready.\n",
3171060SN/A            (int)ready_reg);
3181060SN/A
3191060SN/A    if (ready_reg < numPhysicalIntRegs) {
3201061SN/A        assert(ready_reg >= 0);
3211061SN/A
3221060SN/A        intScoreboard[ready_reg] = 1;
3231060SN/A    } else if (ready_reg < numPhysicalRegs) {
3241060SN/A
3251060SN/A        // Subtract off the base FP offset.
3261061SN/A//        ready_reg = ready_reg - numPhysicalIntRegs;
3271060SN/A
3281060SN/A        floatScoreboard[ready_reg] = 1;
3291060SN/A    } else {
3301060SN/A        //Subtract off the misc registers offset.
3311061SN/A//        ready_reg = ready_reg - numPhysicalRegs;
3321060SN/A
3331060SN/A        miscScoreboard[ready_reg] = 1;
3341060SN/A    }
3351060SN/A}
3361060SN/A
3371060SN/Aint
3381060SN/ASimpleRenameMap::numFreeEntries()
3391060SN/A{
3401060SN/A    int free_int_regs = freeList->numFreeIntRegs();
3411060SN/A    int free_float_regs = freeList->numFreeFloatRegs();
3421060SN/A
3431060SN/A    if (free_int_regs < free_float_regs) {
3441060SN/A        return free_int_regs;
3451060SN/A    } else {
3461060SN/A        return free_float_regs;
3471060SN/A    }
3481060SN/A}
349