rename_map.cc

来自「linux下基于c++的处理器仿真平台。具有处理器流水线」· CC 代码 · 共 350 行

CC
350
字号
/* * Copyright (c) 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator, developed by Nathan Binkert, * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions * from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi,  * and Andrew Schultz. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. */#include <vector>#include "cpu/o3/rename_map.hh"using namespace std;// Todo: Consider making functions inline.  Avoid having things that are// using the zero register or misc registers from adding on the registers// to the free list.  Possibly remove the direct communication between// this and the freelist.  Considering making inline bool functions that// determine if the register is a logical int, logical fp, physical int,// physical fp, etc.SimpleRenameMap::SimpleRenameMap(unsigned _numLogicalIntRegs,                                 unsigned _numPhysicalIntRegs,                                 unsigned _numLogicalFloatRegs,                                 unsigned _numPhysicalFloatRegs,                                 unsigned _numMiscRegs,                                 RegIndex _intZeroReg,                                 RegIndex _floatZeroReg)    : numLogicalIntRegs(_numLogicalIntRegs),      numPhysicalIntRegs(_numPhysicalIntRegs),      numLogicalFloatRegs(_numLogicalFloatRegs),      numPhysicalFloatRegs(_numPhysicalFloatRegs),      numMiscRegs(_numMiscRegs),      intZeroReg(_intZeroReg),      floatZeroReg(_floatZeroReg){    DPRINTF(Rename, "Rename: Creating rename map.  Phys: %i / %i, Float: "            "%i / %i.\n", numLogicalIntRegs, numPhysicalIntRegs,            numLogicalFloatRegs, numPhysicalFloatRegs);    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;    //Create the rename maps, and their scoreboards.    intRenameMap = new RenameEntry[numLogicalIntRegs];    floatRenameMap = new RenameEntry[numLogicalRegs];    // Should combine this into one scoreboard.    intScoreboard.resize(numPhysicalIntRegs);    floatScoreboard.resize(numPhysicalRegs);    miscScoreboard.resize(numPhysicalRegs + numMiscRegs);    // Initialize the entries in the integer rename map to point to the    // physical registers of the same index, and consider each register    // ready until the first rename occurs.    for (RegIndex index = 0; index < numLogicalIntRegs; ++index)    {        intRenameMap[index].physical_reg = index;        intScoreboard[index] = 1;    }    // Initialize the rest of the physical registers (the ones that don't    // directly map to a logical register) as unready.    for (PhysRegIndex index = numLogicalIntRegs;         index < numPhysicalIntRegs;         ++index)    {        intScoreboard[index] = 0;    }    int float_reg_idx = numPhysicalIntRegs;    // Initialize the entries in the floating point rename map to point to     // the physical registers of the same index, and consider each register    // ready until the first rename occurs.    // Although the index refers purely to architected registers, because    // the floating reg indices come after the integer reg indices, they    // may exceed the size of a normal RegIndex (short).    for (PhysRegIndex index = numLogicalIntRegs;          index < numLogicalRegs; ++index)    {        floatRenameMap[index].physical_reg = float_reg_idx++;    }    for (PhysRegIndex index = numPhysicalIntRegs;          index < numPhysicalIntRegs + numLogicalFloatRegs; ++index)    {        floatScoreboard[index] = 1;    }    // Initialize the rest of the physical registers (the ones that don't    // directly map to a logical register) as unready.    for (PhysRegIndex index = numPhysicalIntRegs + numLogicalFloatRegs;         index < numPhysicalRegs;         ++index)    {        floatScoreboard[index] = 0;    }    // Initialize the entries in the misc register scoreboard to be ready.    for (PhysRegIndex index = numPhysicalRegs;          index < numPhysicalRegs + numMiscRegs; ++index)    {        miscScoreboard[index] = 1;    }}SimpleRenameMap::~SimpleRenameMap(){    // Delete the rename maps as they were allocated with new.    delete [] intRenameMap;    delete [] floatRenameMap;}voidSimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr){    //Setup the interface to the freelist.    freeList = fl_ptr;}// Don't allow this stage to fault; force that check to the rename stage.  // Simply ask to rename a logical register and get back a new physical// register index.SimpleRenameMap::RenameInfoSimpleRenameMap::rename(RegIndex arch_reg){    PhysRegIndex renamed_reg;    PhysRegIndex prev_reg;    if (arch_reg < numLogicalIntRegs) {        // Record the current physical register that is renamed to the        // requested architected register.        prev_reg = intRenameMap[arch_reg].physical_reg;        // If it's not referencing the zero register, then mark the register        // as not ready.        if (arch_reg != intZeroReg) {            // Get a free physical register to rename to.            renamed_reg = freeList->getIntReg();            // Update the integer rename map.            intRenameMap[arch_reg].physical_reg = renamed_reg;            assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);            // Mark register as not ready.            intScoreboard[renamed_reg] = false;        } else {            // Otherwise return the zero register so nothing bad happens.            renamed_reg = intZeroReg;        }    } else if (arch_reg < numLogicalRegs) {        // Subtract off the base offset for floating point registers.//        arch_reg = arch_reg - numLogicalIntRegs;        // Record the current physical register that is renamed to the        // requested architected register.        prev_reg = floatRenameMap[arch_reg].physical_reg;        // If it's not referencing the zero register, then mark the register        // as not ready.        if (arch_reg != floatZeroReg) {            // Get a free floating point register to rename to.            renamed_reg = freeList->getFloatReg();            // Update the floating point rename map.            floatRenameMap[arch_reg].physical_reg = renamed_reg;            assert(renamed_reg < numPhysicalRegs &&                    renamed_reg >= numPhysicalIntRegs);            // Mark register as not ready.            floatScoreboard[renamed_reg] = false;        } else {            // Otherwise return the zero register so nothing bad happens.            renamed_reg = floatZeroReg;        }    } else {        // Subtract off the base offset for miscellaneous registers.        arch_reg = arch_reg - numLogicalRegs;        // No renaming happens to the misc. registers.  They are simply the        // registers that come after all the  physical registers; thus        // take the base architected register and add the physical registers        // to it.        renamed_reg = arch_reg + numPhysicalRegs;        // Set the previous register to the same register; mainly it must be        // known that the prev reg was outside the range of normal registers        // so the free list can avoid adding it.        prev_reg = renamed_reg;        assert(renamed_reg < numPhysicalRegs + numMiscRegs);        miscScoreboard[renamed_reg] = false;    }    return RenameInfo(renamed_reg, prev_reg);}//Perhaps give this a pair as a return value, of the physical register//and whether or not it's ready.PhysRegIndexSimpleRenameMap::lookup(RegIndex arch_reg){    if (arch_reg < numLogicalIntRegs) {        return intRenameMap[arch_reg].physical_reg;    } else if (arch_reg < numLogicalRegs) {        // Subtract off the base FP offset.//        arch_reg = arch_reg - numLogicalIntRegs;        return floatRenameMap[arch_reg].physical_reg;    } else {        // Subtract off the misc registers offset.        arch_reg = arch_reg - numLogicalRegs;        // Misc. regs don't rename, so simply add the base arch reg to        // the number of physical registers.        return numPhysicalRegs + arch_reg;    }}boolSimpleRenameMap::isReady(PhysRegIndex phys_reg){    if (phys_reg < numPhysicalIntRegs) {        return intScoreboard[phys_reg];    } else if (phys_reg < numPhysicalRegs) {        // Subtract off the base FP offset.//        phys_reg = phys_reg - numPhysicalIntRegs;        return floatScoreboard[phys_reg];    } else {        // Subtract off the misc registers offset.//        phys_reg = phys_reg - numPhysicalRegs;        return miscScoreboard[phys_reg];    }}// In this implementation the miscellaneous registers do not actually rename,// so this function does not allow you to try to change their mappings.voidSimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg){    if (arch_reg < numLogicalIntRegs) {        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",                (int)arch_reg, renamed_reg);        intRenameMap[arch_reg].physical_reg = renamed_reg;    } else {        assert(arch_reg < (numLogicalIntRegs + numLogicalFloatRegs));        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",                (int)arch_reg - numLogicalIntRegs, renamed_reg);        floatRenameMap[arch_reg].physical_reg = renamed_reg;    }}voidSimpleRenameMap::squash(vector<RegIndex> freed_regs,                        vector<UnmapInfo> unmaps){    panic("Not sure this function should be called.");    // Not sure the rename map should be able to access the free list    // like this.    while (!freed_regs.empty()) {        RegIndex free_register = freed_regs.back();        if (free_register < numPhysicalIntRegs) {            freeList->addIntReg(free_register);        } else {            // Subtract off the base FP dependence tag.            free_register = free_register - numPhysicalIntRegs;            freeList->addFloatReg(free_register);        }        freed_regs.pop_back();    }    // Take unmap info and roll back the rename map.}voidSimpleRenameMap::markAsReady(PhysRegIndex ready_reg){    DPRINTF(Rename, "Rename map: Marking register %i as ready.\n",             (int)ready_reg);        if (ready_reg < numPhysicalIntRegs) {        assert(ready_reg >= 0);        intScoreboard[ready_reg] = 1;    } else if (ready_reg < numPhysicalRegs) {        // Subtract off the base FP offset.//        ready_reg = ready_reg - numPhysicalIntRegs;        floatScoreboard[ready_reg] = 1;    } else {        //Subtract off the misc registers offset.//        ready_reg = ready_reg - numPhysicalRegs;        miscScoreboard[ready_reg] = 1;    }}intSimpleRenameMap::numFreeEntries(){    int free_int_regs = freeList->numFreeIntRegs();    int free_float_regs = freeList->numFreeFloatRegs();    if (free_int_regs < free_float_regs) {        return free_int_regs;    } else {        return free_float_regs;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?