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 + -
显示快捷键?