rename_map.cc revision 2292
111185Serfan.azarkhish@unibo.it/*
211185Serfan.azarkhish@unibo.it * Copyright (c) 2004-2005 The Regents of The University of Michigan
311185Serfan.azarkhish@unibo.it * All rights reserved.
411185Serfan.azarkhish@unibo.it *
511185Serfan.azarkhish@unibo.it * Redistribution and use in source and binary forms, with or without
611185Serfan.azarkhish@unibo.it * modification, are permitted provided that the following conditions are
711185Serfan.azarkhish@unibo.it * met: redistributions of source code must retain the above copyright
811185Serfan.azarkhish@unibo.it * notice, this list of conditions and the following disclaimer;
911185Serfan.azarkhish@unibo.it * redistributions in binary form must reproduce the above copyright
1011185Serfan.azarkhish@unibo.it * notice, this list of conditions and the following disclaimer in the
1111185Serfan.azarkhish@unibo.it * documentation and/or other materials provided with the distribution;
1211185Serfan.azarkhish@unibo.it * neither the name of the copyright holders nor the names of its
1311185Serfan.azarkhish@unibo.it * contributors may be used to endorse or promote products derived from
1411185Serfan.azarkhish@unibo.it * this software without specific prior written permission.
1511185Serfan.azarkhish@unibo.it *
1611185Serfan.azarkhish@unibo.it * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711185Serfan.azarkhish@unibo.it * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811185Serfan.azarkhish@unibo.it * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911185Serfan.azarkhish@unibo.it * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011185Serfan.azarkhish@unibo.it * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111185Serfan.azarkhish@unibo.it * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211185Serfan.azarkhish@unibo.it * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311185Serfan.azarkhish@unibo.it * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411185Serfan.azarkhish@unibo.it * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511185Serfan.azarkhish@unibo.it * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611185Serfan.azarkhish@unibo.it * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711185Serfan.azarkhish@unibo.it */
2811185Serfan.azarkhish@unibo.it
2911185Serfan.azarkhish@unibo.it#include <vector>
3011185Serfan.azarkhish@unibo.it
3111185Serfan.azarkhish@unibo.it#include "cpu/o3/rename_map.hh"
3211185Serfan.azarkhish@unibo.it
3311185Serfan.azarkhish@unibo.itusing namespace std;
3411185Serfan.azarkhish@unibo.it
3511185Serfan.azarkhish@unibo.it// Todo: Consider making functions inline.  Avoid having things that are
3611185Serfan.azarkhish@unibo.it// using the zero register or misc registers from adding on the registers
3711185Serfan.azarkhish@unibo.it// to the free list.  Possibly remove the direct communication between
3811185Serfan.azarkhish@unibo.it// this and the freelist.  Considering making inline bool functions that
3911185Serfan.azarkhish@unibo.it// determine if the register is a logical int, logical fp, physical int,
4011185Serfan.azarkhish@unibo.it// physical fp, etc.
4111185Serfan.azarkhish@unibo.it
4211185Serfan.azarkhish@unibo.itSimpleRenameMap::~SimpleRenameMap()
4311185Serfan.azarkhish@unibo.it{
4411185Serfan.azarkhish@unibo.it    // Delete the rename maps as they were allocated with new.
4511185Serfan.azarkhish@unibo.it    //delete [] intRenameMap;
4611185Serfan.azarkhish@unibo.it    //delete [] floatRenameMap;
4711185Serfan.azarkhish@unibo.it}
4811185Serfan.azarkhish@unibo.it
4911185Serfan.azarkhish@unibo.itvoid
5011185Serfan.azarkhish@unibo.itSimpleRenameMap::init(unsigned _numLogicalIntRegs,
5111185Serfan.azarkhish@unibo.it                      unsigned _numPhysicalIntRegs,
5211185Serfan.azarkhish@unibo.it                      PhysRegIndex &ireg_idx,
5311185Serfan.azarkhish@unibo.it
5411185Serfan.azarkhish@unibo.it                      unsigned _numLogicalFloatRegs,
5511185Serfan.azarkhish@unibo.it                      unsigned _numPhysicalFloatRegs,
5611185Serfan.azarkhish@unibo.it                      PhysRegIndex &freg_idx,
5711185Serfan.azarkhish@unibo.it
5811185Serfan.azarkhish@unibo.it                      unsigned _numMiscRegs,
5911185Serfan.azarkhish@unibo.it
6011185Serfan.azarkhish@unibo.it                      RegIndex _intZeroReg,
6111185Serfan.azarkhish@unibo.it                      RegIndex _floatZeroReg,
6211185Serfan.azarkhish@unibo.it
6311185Serfan.azarkhish@unibo.it                      int map_id,
6411185Serfan.azarkhish@unibo.it                      bool bindRegs)
6511185Serfan.azarkhish@unibo.it{
6611185Serfan.azarkhish@unibo.it    id = map_id;
6711185Serfan.azarkhish@unibo.it
6811185Serfan.azarkhish@unibo.it    numLogicalIntRegs = _numLogicalIntRegs;
6911185Serfan.azarkhish@unibo.it
7011185Serfan.azarkhish@unibo.it    numLogicalFloatRegs = _numLogicalFloatRegs;
7111185Serfan.azarkhish@unibo.it
7211185Serfan.azarkhish@unibo.it    numPhysicalIntRegs = _numPhysicalIntRegs;
7311185Serfan.azarkhish@unibo.it
7411185Serfan.azarkhish@unibo.it    numPhysicalFloatRegs = _numPhysicalFloatRegs;
7511185Serfan.azarkhish@unibo.it
7611185Serfan.azarkhish@unibo.it    numMiscRegs = _numMiscRegs;
7711185Serfan.azarkhish@unibo.it
7811185Serfan.azarkhish@unibo.it    intZeroReg = _intZeroReg;
7911185Serfan.azarkhish@unibo.it    floatZeroReg = _floatZeroReg;
8011185Serfan.azarkhish@unibo.it
8111185Serfan.azarkhish@unibo.it    DPRINTF(Rename, "Creating rename map %i.  Phys: %i / %i, Float: "
8211185Serfan.azarkhish@unibo.it            "%i / %i.\n", id, numLogicalIntRegs, numPhysicalIntRegs,
8311185Serfan.azarkhish@unibo.it            numLogicalFloatRegs, numPhysicalFloatRegs);
8411185Serfan.azarkhish@unibo.it
8511185Serfan.azarkhish@unibo.it    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
8611185Serfan.azarkhish@unibo.it
8711185Serfan.azarkhish@unibo.it    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
8811185Serfan.azarkhish@unibo.it
8911185Serfan.azarkhish@unibo.it    //Create the rename maps
9011185Serfan.azarkhish@unibo.it    intRenameMap.resize(numLogicalIntRegs);
9111185Serfan.azarkhish@unibo.it    floatRenameMap.resize(numLogicalRegs);
9211185Serfan.azarkhish@unibo.it
9311185Serfan.azarkhish@unibo.it    if (bindRegs) {
9411185Serfan.azarkhish@unibo.it        DPRINTF(Rename, "Binding registers into rename map %i",id);
9511185Serfan.azarkhish@unibo.it
9611185Serfan.azarkhish@unibo.it        // Initialize the entries in the integer rename map to point to the
9711185Serfan.azarkhish@unibo.it        // physical registers of the same index
9811185Serfan.azarkhish@unibo.it        for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
9911185Serfan.azarkhish@unibo.it        {
10011185Serfan.azarkhish@unibo.it            intRenameMap[index].physical_reg = ireg_idx++;
10111185Serfan.azarkhish@unibo.it        }
10211185Serfan.azarkhish@unibo.it
10311185Serfan.azarkhish@unibo.it        // Initialize the entries in the floating point rename map to point to
10411185Serfan.azarkhish@unibo.it        // the physical registers of the same index
10511185Serfan.azarkhish@unibo.it        // Although the index refers purely to architected registers, because
10611185Serfan.azarkhish@unibo.it        // the floating reg indices come after the integer reg indices, they
10711185Serfan.azarkhish@unibo.it        // may exceed the size of a normal RegIndex (short).
10811185Serfan.azarkhish@unibo.it        for (PhysRegIndex index = numLogicalIntRegs; index < numLogicalRegs; ++index)
10911185Serfan.azarkhish@unibo.it        {
11011185Serfan.azarkhish@unibo.it            floatRenameMap[index].physical_reg = freg_idx++;
11111185Serfan.azarkhish@unibo.it        }
11211185Serfan.azarkhish@unibo.it    } else {
11311185Serfan.azarkhish@unibo.it        DPRINTF(Rename, "Binding registers into rename map %i",id);
11411185Serfan.azarkhish@unibo.it
11511185Serfan.azarkhish@unibo.it        PhysRegIndex temp_ireg = ireg_idx;
11611185Serfan.azarkhish@unibo.it
11711185Serfan.azarkhish@unibo.it        for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
11811185Serfan.azarkhish@unibo.it        {
11911185Serfan.azarkhish@unibo.it            intRenameMap[index].physical_reg = temp_ireg++;
12011185Serfan.azarkhish@unibo.it        }
12111185Serfan.azarkhish@unibo.it
12211185Serfan.azarkhish@unibo.it        PhysRegIndex temp_freg = freg_idx;
12311185Serfan.azarkhish@unibo.it
12411185Serfan.azarkhish@unibo.it        for (PhysRegIndex index = numLogicalIntRegs;
12511185Serfan.azarkhish@unibo.it             index < numLogicalRegs; ++index)
12611185Serfan.azarkhish@unibo.it        {
12711185Serfan.azarkhish@unibo.it            floatRenameMap[index].physical_reg = temp_freg++;
12811185Serfan.azarkhish@unibo.it        }
12911185Serfan.azarkhish@unibo.it    }
13011185Serfan.azarkhish@unibo.it}
13111185Serfan.azarkhish@unibo.it
13211185Serfan.azarkhish@unibo.itvoid
13311185Serfan.azarkhish@unibo.itSimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
13411185Serfan.azarkhish@unibo.it{
13511185Serfan.azarkhish@unibo.it    //Setup the interface to the freelist.
13611185Serfan.azarkhish@unibo.it    freeList = fl_ptr;
13711185Serfan.azarkhish@unibo.it}
13811185Serfan.azarkhish@unibo.it
13911185Serfan.azarkhish@unibo.it
14011185Serfan.azarkhish@unibo.it// Don't allow this stage to fault; force that check to the rename stage.
14111185Serfan.azarkhish@unibo.it// Simply ask to rename a logical register and get back a new physical
14211185Serfan.azarkhish@unibo.it// register index.
14311185Serfan.azarkhish@unibo.itSimpleRenameMap::RenameInfo
14411185Serfan.azarkhish@unibo.itSimpleRenameMap::rename(RegIndex arch_reg)
14511185Serfan.azarkhish@unibo.it{
14611185Serfan.azarkhish@unibo.it    PhysRegIndex renamed_reg;
14711185Serfan.azarkhish@unibo.it    PhysRegIndex prev_reg;
14811185Serfan.azarkhish@unibo.it
14911185Serfan.azarkhish@unibo.it    if (arch_reg < numLogicalIntRegs) {
15011185Serfan.azarkhish@unibo.it
15111185Serfan.azarkhish@unibo.it        // Record the current physical register that is renamed to the
15211185Serfan.azarkhish@unibo.it        // requested architected register.
15311185Serfan.azarkhish@unibo.it        prev_reg = intRenameMap[arch_reg].physical_reg;
15411185Serfan.azarkhish@unibo.it
15511185Serfan.azarkhish@unibo.it        // If it's not referencing the zero register, then mark the register
15611185Serfan.azarkhish@unibo.it        // as not ready.
15711185Serfan.azarkhish@unibo.it        if (arch_reg != intZeroReg) {
15811185Serfan.azarkhish@unibo.it            // Get a free physical register to rename to.
15911185Serfan.azarkhish@unibo.it            renamed_reg = freeList->getIntReg();
16011185Serfan.azarkhish@unibo.it
16111185Serfan.azarkhish@unibo.it            // Update the integer rename map.
16211185Serfan.azarkhish@unibo.it            intRenameMap[arch_reg].physical_reg = renamed_reg;
16311185Serfan.azarkhish@unibo.it
16411185Serfan.azarkhish@unibo.it            assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);
16511185Serfan.azarkhish@unibo.it
16611185Serfan.azarkhish@unibo.it        } else {
16711185Serfan.azarkhish@unibo.it            // Otherwise return the zero register so nothing bad happens.
16811185Serfan.azarkhish@unibo.it            renamed_reg = intZeroReg;
16911185Serfan.azarkhish@unibo.it        }
17011185Serfan.azarkhish@unibo.it    } else if (arch_reg < numLogicalRegs) {
17111185Serfan.azarkhish@unibo.it        // Subtract off the base offset for floating point registers.
17211185Serfan.azarkhish@unibo.it//        arch_reg = arch_reg - numLogicalIntRegs;
17311185Serfan.azarkhish@unibo.it
17411185Serfan.azarkhish@unibo.it        // Record the current physical register that is renamed to the
17511185Serfan.azarkhish@unibo.it        // requested architected register.
17611185Serfan.azarkhish@unibo.it        prev_reg = floatRenameMap[arch_reg].physical_reg;
17711185Serfan.azarkhish@unibo.it
17811185Serfan.azarkhish@unibo.it        // If it's not referencing the zero register, then mark the register
17911185Serfan.azarkhish@unibo.it        // as not ready.
18011185Serfan.azarkhish@unibo.it        if (arch_reg != floatZeroReg) {
18111185Serfan.azarkhish@unibo.it            // Get a free floating point register to rename to.
18211185Serfan.azarkhish@unibo.it            renamed_reg = freeList->getFloatReg();
18311185Serfan.azarkhish@unibo.it
18411185Serfan.azarkhish@unibo.it            // Update the floating point rename map.
18511185Serfan.azarkhish@unibo.it            floatRenameMap[arch_reg].physical_reg = renamed_reg;
18611185Serfan.azarkhish@unibo.it
18711185Serfan.azarkhish@unibo.it            assert(renamed_reg < numPhysicalRegs &&
18811284Sandreas.hansson@arm.com                   renamed_reg >= numPhysicalIntRegs);
18911185Serfan.azarkhish@unibo.it        } else {
19011185Serfan.azarkhish@unibo.it            // Otherwise return the zero register so nothing bad happens.
19111185Serfan.azarkhish@unibo.it            renamed_reg = floatZeroReg;
19211185Serfan.azarkhish@unibo.it        }
19311185Serfan.azarkhish@unibo.it    } else {
19411185Serfan.azarkhish@unibo.it        // Subtract off the base offset for miscellaneous registers.
19511185Serfan.azarkhish@unibo.it        arch_reg = arch_reg - numLogicalRegs;
19611185Serfan.azarkhish@unibo.it
19711185Serfan.azarkhish@unibo.it        // No renaming happens to the misc. registers.  They are simply the
19811185Serfan.azarkhish@unibo.it        // registers that come after all the  physical registers; thus
19911185Serfan.azarkhish@unibo.it        // take the base architected register and add the physical registers
20011185Serfan.azarkhish@unibo.it        // to it.
20111185Serfan.azarkhish@unibo.it        renamed_reg = arch_reg + numPhysicalRegs;
20211185Serfan.azarkhish@unibo.it
20311185Serfan.azarkhish@unibo.it        // Set the previous register to the same register; mainly it must be
20411185Serfan.azarkhish@unibo.it        // known that the prev reg was outside the range of normal registers
20511185Serfan.azarkhish@unibo.it        // so the free list can avoid adding it.
20611185Serfan.azarkhish@unibo.it        prev_reg = renamed_reg;
20711185Serfan.azarkhish@unibo.it
20811185Serfan.azarkhish@unibo.it        assert(renamed_reg < numPhysicalRegs + numMiscRegs);
20911185Serfan.azarkhish@unibo.it    }
21011185Serfan.azarkhish@unibo.it
21111185Serfan.azarkhish@unibo.it    return RenameInfo(renamed_reg, prev_reg);
21211185Serfan.azarkhish@unibo.it}
21311185Serfan.azarkhish@unibo.it
21411185Serfan.azarkhish@unibo.it//Perhaps give this a pair as a return value, of the physical register
21511185Serfan.azarkhish@unibo.it//and whether or not it's ready.
21611185Serfan.azarkhish@unibo.itPhysRegIndex
21711185Serfan.azarkhish@unibo.itSimpleRenameMap::lookup(RegIndex arch_reg)
21811185Serfan.azarkhish@unibo.it{
21911185Serfan.azarkhish@unibo.it    if (arch_reg < numLogicalIntRegs) {
22011185Serfan.azarkhish@unibo.it        return intRenameMap[arch_reg].physical_reg;
22111185Serfan.azarkhish@unibo.it    } else if (arch_reg < numLogicalRegs) {
22211185Serfan.azarkhish@unibo.it        // Subtract off the base FP offset.
22311185Serfan.azarkhish@unibo.it//        arch_reg = arch_reg - numLogicalIntRegs;
22411185Serfan.azarkhish@unibo.it
22511185Serfan.azarkhish@unibo.it        return floatRenameMap[arch_reg].physical_reg;
22611185Serfan.azarkhish@unibo.it    } else {
22711185Serfan.azarkhish@unibo.it        // Subtract off the misc registers offset.
22811185Serfan.azarkhish@unibo.it        arch_reg = arch_reg - numLogicalRegs;
22911185Serfan.azarkhish@unibo.it
23011185Serfan.azarkhish@unibo.it        // Misc. regs don't rename, so simply add the base arch reg to
23111185Serfan.azarkhish@unibo.it        // the number of physical registers.
23211185Serfan.azarkhish@unibo.it        return numPhysicalRegs + arch_reg;
23311185Serfan.azarkhish@unibo.it    }
23411185Serfan.azarkhish@unibo.it}
23511185Serfan.azarkhish@unibo.it
23611185Serfan.azarkhish@unibo.it// In this implementation the miscellaneous registers do not actually rename,
23711185Serfan.azarkhish@unibo.it// so this function does not allow you to try to change their mappings.
23811185Serfan.azarkhish@unibo.itvoid
23911185Serfan.azarkhish@unibo.itSimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
24011185Serfan.azarkhish@unibo.it{
24111185Serfan.azarkhish@unibo.it    if (arch_reg < numLogicalIntRegs) {
24211185Serfan.azarkhish@unibo.it        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
24311185Serfan.azarkhish@unibo.it                (int)arch_reg, renamed_reg);
24411185Serfan.azarkhish@unibo.it
24511185Serfan.azarkhish@unibo.it        intRenameMap[arch_reg].physical_reg = renamed_reg;
24611185Serfan.azarkhish@unibo.it    } else if (arch_reg < numLogicalIntRegs + numLogicalFloatRegs) {
24711185Serfan.azarkhish@unibo.it
24811185Serfan.azarkhish@unibo.it
24911185Serfan.azarkhish@unibo.it        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
25011185Serfan.azarkhish@unibo.it                (int)arch_reg - numLogicalIntRegs, renamed_reg);
25111185Serfan.azarkhish@unibo.it
25211185Serfan.azarkhish@unibo.it        floatRenameMap[arch_reg].physical_reg = renamed_reg;
25311185Serfan.azarkhish@unibo.it    }
25411185Serfan.azarkhish@unibo.it
25511185Serfan.azarkhish@unibo.it    //assert(arch_reg < (numLogicalIntRegs + numLogicalFloatRegs));
25611185Serfan.azarkhish@unibo.it}
25711185Serfan.azarkhish@unibo.it
25811185Serfan.azarkhish@unibo.itvoid
25911185Serfan.azarkhish@unibo.itSimpleRenameMap::squash(vector<RegIndex> freed_regs,
26011185Serfan.azarkhish@unibo.it                        vector<UnmapInfo> unmaps)
26111185Serfan.azarkhish@unibo.it{
26211185Serfan.azarkhish@unibo.it    panic("Not sure this function should be called.");
26311185Serfan.azarkhish@unibo.it
26411185Serfan.azarkhish@unibo.it    // Not sure the rename map should be able to access the free list
26511185Serfan.azarkhish@unibo.it    // like this.
26611185Serfan.azarkhish@unibo.it    while (!freed_regs.empty()) {
26711185Serfan.azarkhish@unibo.it        RegIndex free_register = freed_regs.back();
26811185Serfan.azarkhish@unibo.it
26911185Serfan.azarkhish@unibo.it        if (free_register < numPhysicalIntRegs) {
27011185Serfan.azarkhish@unibo.it            freeList->addIntReg(free_register);
27111185Serfan.azarkhish@unibo.it        } else {
27211185Serfan.azarkhish@unibo.it            // Subtract off the base FP dependence tag.
27311185Serfan.azarkhish@unibo.it            free_register = free_register - numPhysicalIntRegs;
27411185Serfan.azarkhish@unibo.it            freeList->addFloatReg(free_register);
27511185Serfan.azarkhish@unibo.it        }
27611185Serfan.azarkhish@unibo.it
27711185Serfan.azarkhish@unibo.it        freed_regs.pop_back();
27811185Serfan.azarkhish@unibo.it    }
27911185Serfan.azarkhish@unibo.it
28011185Serfan.azarkhish@unibo.it    // Take unmap info and roll back the rename map.
28111185Serfan.azarkhish@unibo.it}
28211185Serfan.azarkhish@unibo.it
28311185Serfan.azarkhish@unibo.itint
28411185Serfan.azarkhish@unibo.itSimpleRenameMap::numFreeEntries()
28511185Serfan.azarkhish@unibo.it{
28611185Serfan.azarkhish@unibo.it    int free_int_regs = freeList->numFreeIntRegs();
28711185Serfan.azarkhish@unibo.it    int free_float_regs = freeList->numFreeFloatRegs();
28811185Serfan.azarkhish@unibo.it
28911185Serfan.azarkhish@unibo.it    if (free_int_regs < free_float_regs) {
29011185Serfan.azarkhish@unibo.it        return free_int_regs;
29111185Serfan.azarkhish@unibo.it    } else {
29211185Serfan.azarkhish@unibo.it        return free_float_regs;
29311185Serfan.azarkhish@unibo.it    }
29411185Serfan.azarkhish@unibo.it}
29511185Serfan.azarkhish@unibo.it