rename_map.cc revision 2292
12929Sktlim@umich.edu/*
22929Sktlim@umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
32932Sktlim@umich.edu * All rights reserved.
42929Sktlim@umich.edu *
52929Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without
62929Sktlim@umich.edu * modification, are permitted provided that the following conditions are
72929Sktlim@umich.edu * met: redistributions of source code must retain the above copyright
82929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer;
92929Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright
102929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the
112929Sktlim@umich.edu * documentation and/or other materials provided with the distribution;
122929Sktlim@umich.edu * neither the name of the copyright holders nor the names of its
132929Sktlim@umich.edu * contributors may be used to endorse or promote products derived from
142929Sktlim@umich.edu * this software without specific prior written permission.
152929Sktlim@umich.edu *
162929Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172929Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182929Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192929Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202929Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212929Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222929Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232929Sktlim@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242929Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252929Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262929Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272929Sktlim@umich.edu */
282932Sktlim@umich.edu
292932Sktlim@umich.edu#include <vector>
302932Sktlim@umich.edu
312929Sktlim@umich.edu#include "cpu/o3/rename_map.hh"
326007Ssteve.reinhardt@amd.com
337735SAli.Saidi@ARM.comusing namespace std;
342929Sktlim@umich.edu
352929Sktlim@umich.edu// Todo: Consider making functions inline.  Avoid having things that are
362929Sktlim@umich.edu// using the zero register or misc registers from adding on the registers
372929Sktlim@umich.edu// to the free list.  Possibly remove the direct communication between
382929Sktlim@umich.edu// this and the freelist.  Considering making inline bool functions that
392929Sktlim@umich.edu// determine if the register is a logical int, logical fp, physical int,
402929Sktlim@umich.edu// physical fp, etc.
412929Sktlim@umich.edu
422929Sktlim@umich.eduSimpleRenameMap::~SimpleRenameMap()
432929Sktlim@umich.edu{
442929Sktlim@umich.edu    // Delete the rename maps as they were allocated with new.
452929Sktlim@umich.edu    //delete [] intRenameMap;
462929Sktlim@umich.edu    //delete [] floatRenameMap;
476007Ssteve.reinhardt@amd.com}
486007Ssteve.reinhardt@amd.com
496007Ssteve.reinhardt@amd.comvoid
506007Ssteve.reinhardt@amd.comSimpleRenameMap::init(unsigned _numLogicalIntRegs,
516007Ssteve.reinhardt@amd.com                      unsigned _numPhysicalIntRegs,
526007Ssteve.reinhardt@amd.com                      PhysRegIndex &ireg_idx,
536007Ssteve.reinhardt@amd.com
546007Ssteve.reinhardt@amd.com                      unsigned _numLogicalFloatRegs,
556007Ssteve.reinhardt@amd.com                      unsigned _numPhysicalFloatRegs,
566007Ssteve.reinhardt@amd.com                      PhysRegIndex &freg_idx,
576007Ssteve.reinhardt@amd.com
586007Ssteve.reinhardt@amd.com                      unsigned _numMiscRegs,
596007Ssteve.reinhardt@amd.com
606007Ssteve.reinhardt@amd.com                      RegIndex _intZeroReg,
616007Ssteve.reinhardt@amd.com                      RegIndex _floatZeroReg,
626007Ssteve.reinhardt@amd.com
636007Ssteve.reinhardt@amd.com                      int map_id,
646007Ssteve.reinhardt@amd.com                      bool bindRegs)
656007Ssteve.reinhardt@amd.com{
666007Ssteve.reinhardt@amd.com    id = map_id;
676007Ssteve.reinhardt@amd.com
686007Ssteve.reinhardt@amd.com    numLogicalIntRegs = _numLogicalIntRegs;
696007Ssteve.reinhardt@amd.com
706007Ssteve.reinhardt@amd.com    numLogicalFloatRegs = _numLogicalFloatRegs;
716007Ssteve.reinhardt@amd.com
726007Ssteve.reinhardt@amd.com    numPhysicalIntRegs = _numPhysicalIntRegs;
736007Ssteve.reinhardt@amd.com
746007Ssteve.reinhardt@amd.com    numPhysicalFloatRegs = _numPhysicalFloatRegs;
756007Ssteve.reinhardt@amd.com
762929Sktlim@umich.edu    numMiscRegs = _numMiscRegs;
772929Sktlim@umich.edu
782929Sktlim@umich.edu    intZeroReg = _intZeroReg;
796007Ssteve.reinhardt@amd.com    floatZeroReg = _floatZeroReg;
806007Ssteve.reinhardt@amd.com
816007Ssteve.reinhardt@amd.com    DPRINTF(Rename, "Creating rename map %i.  Phys: %i / %i, Float: "
826007Ssteve.reinhardt@amd.com            "%i / %i.\n", id, numLogicalIntRegs, numPhysicalIntRegs,
836007Ssteve.reinhardt@amd.com            numLogicalFloatRegs, numPhysicalFloatRegs);
846007Ssteve.reinhardt@amd.com
852929Sktlim@umich.edu    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
862929Sktlim@umich.edu
872929Sktlim@umich.edu    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
882929Sktlim@umich.edu
892929Sktlim@umich.edu    //Create the rename maps
906011Ssteve.reinhardt@amd.com    intRenameMap.resize(numLogicalIntRegs);
916007Ssteve.reinhardt@amd.com    floatRenameMap.resize(numLogicalRegs);
926007Ssteve.reinhardt@amd.com
936007Ssteve.reinhardt@amd.com    if (bindRegs) {
946007Ssteve.reinhardt@amd.com        DPRINTF(Rename, "Binding registers into rename map %i",id);
956007Ssteve.reinhardt@amd.com
966007Ssteve.reinhardt@amd.com        // Initialize the entries in the integer rename map to point to the
976007Ssteve.reinhardt@amd.com        // physical registers of the same index
986007Ssteve.reinhardt@amd.com        for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
996007Ssteve.reinhardt@amd.com        {
1006007Ssteve.reinhardt@amd.com            intRenameMap[index].physical_reg = ireg_idx++;
1016007Ssteve.reinhardt@amd.com        }
1026007Ssteve.reinhardt@amd.com
1036007Ssteve.reinhardt@amd.com        // Initialize the entries in the floating point rename map to point to
1046007Ssteve.reinhardt@amd.com        // the physical registers of the same index
1057735SAli.Saidi@ARM.com        // Although the index refers purely to architected registers, because
1066011Ssteve.reinhardt@amd.com        // the floating reg indices come after the integer reg indices, they
1076007Ssteve.reinhardt@amd.com        // may exceed the size of a normal RegIndex (short).
1086007Ssteve.reinhardt@amd.com        for (PhysRegIndex index = numLogicalIntRegs; index < numLogicalRegs; ++index)
1096007Ssteve.reinhardt@amd.com        {
1106007Ssteve.reinhardt@amd.com            floatRenameMap[index].physical_reg = freg_idx++;
1117735SAli.Saidi@ARM.com        }
1127735SAli.Saidi@ARM.com    } else {
1137735SAli.Saidi@ARM.com        DPRINTF(Rename, "Binding registers into rename map %i",id);
1147735SAli.Saidi@ARM.com
1157735SAli.Saidi@ARM.com        PhysRegIndex temp_ireg = ireg_idx;
1167735SAli.Saidi@ARM.com
1177735SAli.Saidi@ARM.com        for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
1187735SAli.Saidi@ARM.com        {
1197735SAli.Saidi@ARM.com            intRenameMap[index].physical_reg = temp_ireg++;
1207735SAli.Saidi@ARM.com        }
1217735SAli.Saidi@ARM.com
1227735SAli.Saidi@ARM.com        PhysRegIndex temp_freg = freg_idx;
1237735SAli.Saidi@ARM.com
1247735SAli.Saidi@ARM.com        for (PhysRegIndex index = numLogicalIntRegs;
1256007Ssteve.reinhardt@amd.com             index < numLogicalRegs; ++index)
1268599Ssteve.reinhardt@amd.com        {
1278599Ssteve.reinhardt@amd.com            floatRenameMap[index].physical_reg = temp_freg++;
1288599Ssteve.reinhardt@amd.com        }
1296007Ssteve.reinhardt@amd.com    }
1306011Ssteve.reinhardt@amd.com}
1316007Ssteve.reinhardt@amd.com
1326007Ssteve.reinhardt@amd.comvoid
1336007Ssteve.reinhardt@amd.comSimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
1346007Ssteve.reinhardt@amd.com{
1356007Ssteve.reinhardt@amd.com    //Setup the interface to the freelist.
1366007Ssteve.reinhardt@amd.com    freeList = fl_ptr;
1376011Ssteve.reinhardt@amd.com}
1386007Ssteve.reinhardt@amd.com
1396007Ssteve.reinhardt@amd.com
1406007Ssteve.reinhardt@amd.com// Don't allow this stage to fault; force that check to the rename stage.
1416007Ssteve.reinhardt@amd.com// Simply ask to rename a logical register and get back a new physical
1426007Ssteve.reinhardt@amd.com// register index.
1436008Ssteve.reinhardt@amd.comSimpleRenameMap::RenameInfo
1446007Ssteve.reinhardt@amd.comSimpleRenameMap::rename(RegIndex arch_reg)
1456008Ssteve.reinhardt@amd.com{
1466008Ssteve.reinhardt@amd.com    PhysRegIndex renamed_reg;
1476008Ssteve.reinhardt@amd.com    PhysRegIndex prev_reg;
1486008Ssteve.reinhardt@amd.com
1496008Ssteve.reinhardt@amd.com    if (arch_reg < numLogicalIntRegs) {
1506008Ssteve.reinhardt@amd.com
1516008Ssteve.reinhardt@amd.com        // Record the current physical register that is renamed to the
1526007Ssteve.reinhardt@amd.com        // requested architected register.
1536007Ssteve.reinhardt@amd.com        prev_reg = intRenameMap[arch_reg].physical_reg;
1546007Ssteve.reinhardt@amd.com
1556007Ssteve.reinhardt@amd.com        // If it's not referencing the zero register, then mark the register
1566007Ssteve.reinhardt@amd.com        // as not ready.
1572929Sktlim@umich.edu        if (arch_reg != intZeroReg) {
1582929Sktlim@umich.edu            // Get a free physical register to rename to.
1592929Sktlim@umich.edu            renamed_reg = freeList->getIntReg();
1602929Sktlim@umich.edu
1616007Ssteve.reinhardt@amd.com            // Update the integer rename map.
1626007Ssteve.reinhardt@amd.com            intRenameMap[arch_reg].physical_reg = renamed_reg;
1632929Sktlim@umich.edu
1642929Sktlim@umich.edu            assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);
1652929Sktlim@umich.edu
1662929Sktlim@umich.edu        } else {
1676007Ssteve.reinhardt@amd.com            // Otherwise return the zero register so nothing bad happens.
1686007Ssteve.reinhardt@amd.com            renamed_reg = intZeroReg;
1692929Sktlim@umich.edu        }
1702929Sktlim@umich.edu    } else if (arch_reg < numLogicalRegs) {
1716007Ssteve.reinhardt@amd.com        // Subtract off the base offset for floating point registers.
1722929Sktlim@umich.edu//        arch_reg = arch_reg - numLogicalIntRegs;
1732929Sktlim@umich.edu
1742929Sktlim@umich.edu        // Record the current physical register that is renamed to the
1752929Sktlim@umich.edu        // requested architected register.
1762929Sktlim@umich.edu        prev_reg = floatRenameMap[arch_reg].physical_reg;
1772929Sktlim@umich.edu
1782929Sktlim@umich.edu        // If it's not referencing the zero register, then mark the register
1794937Sstever@gmail.com        // as not ready.
1804937Sstever@gmail.com        if (arch_reg != floatZeroReg) {
1814937Sstever@gmail.com            // Get a free floating point register to rename to.
1824937Sstever@gmail.com            renamed_reg = freeList->getFloatReg();
1838120Sgblack@eecs.umich.edu
1844937Sstever@gmail.com            // Update the floating point rename map.
1854937Sstever@gmail.com            floatRenameMap[arch_reg].physical_reg = renamed_reg;
1864937Sstever@gmail.com
1874937Sstever@gmail.com            assert(renamed_reg < numPhysicalRegs &&
1885773Snate@binkert.org                   renamed_reg >= numPhysicalIntRegs);
1894937Sstever@gmail.com        } else {
1904937Sstever@gmail.com            // Otherwise return the zero register so nothing bad happens.
1914937Sstever@gmail.com            renamed_reg = floatZeroReg;
1922929Sktlim@umich.edu        }
1932929Sktlim@umich.edu    } else {
1942929Sktlim@umich.edu        // Subtract off the base offset for miscellaneous registers.
1955773Snate@binkert.org        arch_reg = arch_reg - numLogicalRegs;
1962929Sktlim@umich.edu
1972929Sktlim@umich.edu        // No renaming happens to the misc. registers.  They are simply the
1982929Sktlim@umich.edu        // registers that come after all the  physical registers; thus
1992929Sktlim@umich.edu        // take the base architected register and add the physical registers
2002929Sktlim@umich.edu        // to it.
2012929Sktlim@umich.edu        renamed_reg = arch_reg + numPhysicalRegs;
2024937Sstever@gmail.com
2034937Sstever@gmail.com        // Set the previous register to the same register; mainly it must be
2044937Sstever@gmail.com        // known that the prev reg was outside the range of normal registers
2054937Sstever@gmail.com        // so the free list can avoid adding it.
2064937Sstever@gmail.com        prev_reg = renamed_reg;
2074937Sstever@gmail.com
2084937Sstever@gmail.com        assert(renamed_reg < numPhysicalRegs + numMiscRegs);
2094937Sstever@gmail.com    }
2104937Sstever@gmail.com
2114937Sstever@gmail.com    return RenameInfo(renamed_reg, prev_reg);
2124937Sstever@gmail.com}
2134937Sstever@gmail.com
2144937Sstever@gmail.com//Perhaps give this a pair as a return value, of the physical register
2154937Sstever@gmail.com//and whether or not it's ready.
2164937Sstever@gmail.comPhysRegIndex
2172929Sktlim@umich.eduSimpleRenameMap::lookup(RegIndex arch_reg)
2182929Sktlim@umich.edu{
2192929Sktlim@umich.edu    if (arch_reg < numLogicalIntRegs) {
2202929Sktlim@umich.edu        return intRenameMap[arch_reg].physical_reg;
2212929Sktlim@umich.edu    } else if (arch_reg < numLogicalRegs) {
2222929Sktlim@umich.edu        // Subtract off the base FP offset.
2232929Sktlim@umich.edu//        arch_reg = arch_reg - numLogicalIntRegs;
2246011Ssteve.reinhardt@amd.com
2252929Sktlim@umich.edu        return floatRenameMap[arch_reg].physical_reg;
2262929Sktlim@umich.edu    } else {
2272929Sktlim@umich.edu        // Subtract off the misc registers offset.
2282929Sktlim@umich.edu        arch_reg = arch_reg - numLogicalRegs;
2292929Sktlim@umich.edu
2302929Sktlim@umich.edu        // Misc. regs don't rename, so simply add the base arch reg to
2312929Sktlim@umich.edu        // the number of physical registers.
2322929Sktlim@umich.edu        return numPhysicalRegs + arch_reg;
2332997Sstever@eecs.umich.edu    }
2342997Sstever@eecs.umich.edu}
2352929Sktlim@umich.edu
2362997Sstever@eecs.umich.edu// In this implementation the miscellaneous registers do not actually rename,
2372997Sstever@eecs.umich.edu// so this function does not allow you to try to change their mappings.
2382929Sktlim@umich.eduvoid
2392997Sstever@eecs.umich.eduSimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
2402997Sstever@eecs.umich.edu{
2412997Sstever@eecs.umich.edu    if (arch_reg < numLogicalIntRegs) {
2422929Sktlim@umich.edu        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
2432997Sstever@eecs.umich.edu                (int)arch_reg, renamed_reg);
2442997Sstever@eecs.umich.edu
2452997Sstever@eecs.umich.edu        intRenameMap[arch_reg].physical_reg = renamed_reg;
2462997Sstever@eecs.umich.edu    } else if (arch_reg < numLogicalIntRegs + numLogicalFloatRegs) {
2475773Snate@binkert.org
2485773Snate@binkert.org
2492997Sstever@eecs.umich.edu        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
2502997Sstever@eecs.umich.edu                (int)arch_reg - numLogicalIntRegs, renamed_reg);
2516007Ssteve.reinhardt@amd.com
2526007Ssteve.reinhardt@amd.com        floatRenameMap[arch_reg].physical_reg = renamed_reg;
2532997Sstever@eecs.umich.edu    }
2542929Sktlim@umich.edu
2552997Sstever@eecs.umich.edu    //assert(arch_reg < (numLogicalIntRegs + numLogicalFloatRegs));
2568120Sgblack@eecs.umich.edu}
2572997Sstever@eecs.umich.edu
2582997Sstever@eecs.umich.eduvoid
2592997Sstever@eecs.umich.eduSimpleRenameMap::squash(vector<RegIndex> freed_regs,
2602997Sstever@eecs.umich.edu                        vector<UnmapInfo> unmaps)
2612997Sstever@eecs.umich.edu{
2622929Sktlim@umich.edu    panic("Not sure this function should be called.");
2632997Sstever@eecs.umich.edu
2642929Sktlim@umich.edu    // Not sure the rename map should be able to access the free list
2652929Sktlim@umich.edu    // like this.
2663005Sstever@eecs.umich.edu    while (!freed_regs.empty()) {
2673005Sstever@eecs.umich.edu        RegIndex free_register = freed_regs.back();
2683005Sstever@eecs.umich.edu
2693005Sstever@eecs.umich.edu        if (free_register < numPhysicalIntRegs) {
2706025Snate@binkert.org            freeList->addIntReg(free_register);
2716025Snate@binkert.org        } else {
2726025Snate@binkert.org            // Subtract off the base FP dependence tag.
2736025Snate@binkert.org            free_register = free_register - numPhysicalIntRegs;
2746025Snate@binkert.org            freeList->addFloatReg(free_register);
2758397Sksewell@umich.edu        }
2768397Sksewell@umich.edu
2774130Ssaidi@eecs.umich.edu        freed_regs.pop_back();
2784130Ssaidi@eecs.umich.edu    }
2794130Ssaidi@eecs.umich.edu
2807735SAli.Saidi@ARM.com    // Take unmap info and roll back the rename map.
2817735SAli.Saidi@ARM.com}
2828528SAli.Saidi@ARM.com
2838150SAli.Saidi@ARM.comint
2848528SAli.Saidi@ARM.comSimpleRenameMap::numFreeEntries()
2858528SAli.Saidi@ARM.com{
2868528SAli.Saidi@ARM.com    int free_int_regs = freeList->numFreeIntRegs();
2877926Sgblack@eecs.umich.edu    int free_float_regs = freeList->numFreeFloatRegs();
2887926Sgblack@eecs.umich.edu
2898498Sgblack@eecs.umich.edu    if (free_int_regs < free_float_regs) {
2908498Sgblack@eecs.umich.edu        return free_int_regs;
2913691Shsul@eecs.umich.edu    } else {
2923005Sstever@eecs.umich.edu        return free_float_regs;
2935721Shsul@eecs.umich.edu    }
2946194Sksewell@umich.edu}
2956928SBrad.Beckmann@amd.com