13c005a8af
--HG-- rename : cpu/base_cpu.cc => cpu/base.cc rename : cpu/base_cpu.hh => cpu/base.hh rename : cpu/beta_cpu/2bit_local_pred.cc => cpu/o3/2bit_local_pred.cc rename : cpu/beta_cpu/2bit_local_pred.hh => cpu/o3/2bit_local_pred.hh rename : cpu/beta_cpu/alpha_full_cpu.cc => cpu/o3/alpha_cpu.cc rename : cpu/beta_cpu/alpha_full_cpu.hh => cpu/o3/alpha_cpu.hh rename : cpu/beta_cpu/alpha_full_cpu_builder.cc => cpu/o3/alpha_cpu_builder.cc rename : cpu/beta_cpu/alpha_full_cpu_impl.hh => cpu/o3/alpha_cpu_impl.hh rename : cpu/beta_cpu/alpha_dyn_inst.cc => cpu/o3/alpha_dyn_inst.cc rename : cpu/beta_cpu/alpha_dyn_inst.hh => cpu/o3/alpha_dyn_inst.hh rename : cpu/beta_cpu/alpha_dyn_inst_impl.hh => cpu/o3/alpha_dyn_inst_impl.hh rename : cpu/beta_cpu/alpha_impl.hh => cpu/o3/alpha_impl.hh rename : cpu/beta_cpu/alpha_params.hh => cpu/o3/alpha_params.hh rename : cpu/beta_cpu/bpred_unit.cc => cpu/o3/bpred_unit.cc rename : cpu/beta_cpu/bpred_unit.hh => cpu/o3/bpred_unit.hh rename : cpu/beta_cpu/bpred_unit_impl.hh => cpu/o3/bpred_unit_impl.hh rename : cpu/beta_cpu/btb.cc => cpu/o3/btb.cc rename : cpu/beta_cpu/btb.hh => cpu/o3/btb.hh rename : cpu/beta_cpu/comm.hh => cpu/o3/comm.hh rename : cpu/beta_cpu/commit.cc => cpu/o3/commit.cc rename : cpu/beta_cpu/commit.hh => cpu/o3/commit.hh rename : cpu/beta_cpu/commit_impl.hh => cpu/o3/commit_impl.hh rename : cpu/beta_cpu/full_cpu.cc => cpu/o3/cpu.cc rename : cpu/beta_cpu/full_cpu.hh => cpu/o3/cpu.hh rename : cpu/beta_cpu/cpu_policy.hh => cpu/o3/cpu_policy.hh rename : cpu/beta_cpu/decode.cc => cpu/o3/decode.cc rename : cpu/beta_cpu/decode.hh => cpu/o3/decode.hh rename : cpu/beta_cpu/decode_impl.hh => cpu/o3/decode_impl.hh rename : cpu/beta_cpu/fetch.cc => cpu/o3/fetch.cc rename : cpu/beta_cpu/fetch.hh => cpu/o3/fetch.hh rename : cpu/beta_cpu/fetch_impl.hh => cpu/o3/fetch_impl.hh rename : cpu/beta_cpu/free_list.cc => cpu/o3/free_list.cc rename : cpu/beta_cpu/free_list.hh => cpu/o3/free_list.hh rename : cpu/beta_cpu/iew.cc => cpu/o3/iew.cc rename : cpu/beta_cpu/iew.hh => cpu/o3/iew.hh rename : cpu/beta_cpu/iew_impl.hh => cpu/o3/iew_impl.hh rename : cpu/beta_cpu/inst_queue.cc => cpu/o3/inst_queue.cc rename : cpu/beta_cpu/inst_queue.hh => cpu/o3/inst_queue.hh rename : cpu/beta_cpu/inst_queue_impl.hh => cpu/o3/inst_queue_impl.hh rename : cpu/beta_cpu/mem_dep_unit.cc => cpu/o3/mem_dep_unit.cc rename : cpu/beta_cpu/mem_dep_unit.hh => cpu/o3/mem_dep_unit.hh rename : cpu/beta_cpu/mem_dep_unit_impl.hh => cpu/o3/mem_dep_unit_impl.hh rename : cpu/beta_cpu/ras.cc => cpu/o3/ras.cc rename : cpu/beta_cpu/ras.hh => cpu/o3/ras.hh rename : cpu/beta_cpu/regfile.hh => cpu/o3/regfile.hh rename : cpu/beta_cpu/rename.cc => cpu/o3/rename.cc rename : cpu/beta_cpu/rename.hh => cpu/o3/rename.hh rename : cpu/beta_cpu/rename_impl.hh => cpu/o3/rename_impl.hh rename : cpu/beta_cpu/rename_map.cc => cpu/o3/rename_map.cc rename : cpu/beta_cpu/rename_map.hh => cpu/o3/rename_map.hh rename : cpu/beta_cpu/rob.cc => cpu/o3/rob.cc rename : cpu/beta_cpu/rob.hh => cpu/o3/rob.hh rename : cpu/beta_cpu/rob_impl.hh => cpu/o3/rob_impl.hh rename : cpu/beta_cpu/sat_counter.cc => cpu/o3/sat_counter.cc rename : cpu/beta_cpu/sat_counter.hh => cpu/o3/sat_counter.hh rename : cpu/beta_cpu/store_set.cc => cpu/o3/store_set.cc rename : cpu/beta_cpu/store_set.hh => cpu/o3/store_set.hh rename : cpu/beta_cpu/tournament_pred.cc => cpu/o3/tournament_pred.cc rename : cpu/beta_cpu/tournament_pred.hh => cpu/o3/tournament_pred.hh rename : cpu/ooo_cpu/ooo_cpu.cc => cpu/ozone/cpu.cc rename : cpu/ooo_cpu/ooo_cpu.hh => cpu/ozone/cpu.hh rename : cpu/ooo_cpu/ooo_impl.hh => cpu/ozone/cpu_impl.hh rename : cpu/ooo_cpu/ea_list.cc => cpu/ozone/ea_list.cc rename : cpu/ooo_cpu/ea_list.hh => cpu/ozone/ea_list.hh rename : cpu/simple_cpu/simple_cpu.cc => cpu/simple/cpu.cc rename : cpu/simple_cpu/simple_cpu.hh => cpu/simple/cpu.hh rename : cpu/full_cpu/smt.hh => cpu/smt.hh rename : cpu/full_cpu/op_class.hh => encumbered/cpu/full/op_class.hh extra : convert_revision : c4a891d8d6d3e0e9e5ea56be47d851da44d8c032
346 lines
12 KiB
C++
346 lines
12 KiB
C++
/*
|
|
* Copyright (c) 2004-2005 The Regents of The University of Michigan
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met: redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer;
|
|
* redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution;
|
|
* neither the name of the copyright holders nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#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;
|
|
}
|
|
|
|
void
|
|
SimpleRenameMap::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::RenameInfo
|
|
SimpleRenameMap::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.
|
|
PhysRegIndex
|
|
SimpleRenameMap::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;
|
|
}
|
|
}
|
|
|
|
bool
|
|
SimpleRenameMap::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.
|
|
void
|
|
SimpleRenameMap::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;
|
|
}
|
|
}
|
|
|
|
void
|
|
SimpleRenameMap::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.
|
|
}
|
|
|
|
void
|
|
SimpleRenameMap::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;
|
|
}
|
|
}
|
|
|
|
int
|
|
SimpleRenameMap::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;
|
|
}
|
|
}
|