blob: 8b87725caa2f33b58d916b6dd0aad40d8ff2665a [file] [log] [blame]
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* 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.
*
* Authors: Kevin Lim
* Gabe Black
*/
#ifndef __CPU_O3_REGFILE_HH__
#define __CPU_O3_REGFILE_HH__
#include <vector>
#include "arch/isa_traits.hh"
#include "arch/kernel_stats.hh"
#include "arch/types.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/o3/comm.hh"
#include "debug/IEW.hh"
class UnifiedFreeList;
/**
* Simple physical register file class.
*/
class PhysRegFile
{
private:
typedef TheISA::IntReg IntReg;
typedef TheISA::FloatReg FloatReg;
typedef TheISA::FloatRegBits FloatRegBits;
typedef TheISA::CCReg CCReg;
typedef union {
FloatReg d;
FloatRegBits q;
} PhysFloatReg;
/** Integer register file. */
std::vector<IntReg> intRegFile;
/** Floating point register file. */
std::vector<PhysFloatReg> floatRegFile;
/** Condition-code register file. */
std::vector<CCReg> ccRegFile;
/**
* The first floating-point physical register index. The physical
* register file has a single continuous index space, with the
* initial indices mapping to the integer registers, followed
* immediately by the floating-point registers. Thus the first
* floating-point index is equal to the number of integer
* registers.
*
* Note that this internal organizational detail on how physical
* register file indices are ordered should *NOT* be exposed
* outside of this class. Other classes can use the is*PhysReg()
* methods to map from a physical register index to a class
* without knowing the internal structure of the index map.
*/
unsigned baseFloatRegIndex;
/**
* The first condition-code physical register index. The
* condition-code registers follow the floating-point registers.
*/
unsigned baseCCRegIndex;
/** Total number of physical registers. */
unsigned totalNumRegs;
public:
/**
* Constructs a physical register file with the specified amount of
* integer and floating point registers.
*/
PhysRegFile(unsigned _numPhysicalIntRegs,
unsigned _numPhysicalFloatRegs,
unsigned _numPhysicalCCRegs);
/**
* Destructor to free resources
*/
~PhysRegFile() {}
/** Initialize the free list */
void initFreeList(UnifiedFreeList *freeList);
/** @return the number of integer physical registers. */
unsigned numIntPhysRegs() const { return baseFloatRegIndex; }
/** @return the number of floating-point physical registers. */
unsigned numFloatPhysRegs() const
{ return baseCCRegIndex - baseFloatRegIndex; }
/** @return the number of condition-code physical registers. */
unsigned numCCPhysRegs() const
{ return totalNumRegs - baseCCRegIndex; }
/** @return the total number of physical registers. */
unsigned totalNumPhysRegs() const { return totalNumRegs; }
/**
* @return true if the specified physical register index
* corresponds to an integer physical register.
*/
bool isIntPhysReg(PhysRegIndex reg_idx) const
{
return 0 <= reg_idx && reg_idx < baseFloatRegIndex;
}
/**
* @return true if the specified physical register index
* corresponds to a floating-point physical register.
*/
bool isFloatPhysReg(PhysRegIndex reg_idx) const
{
return (baseFloatRegIndex <= reg_idx && reg_idx < baseCCRegIndex);
}
/**
* Return true if the specified physical register index
* corresponds to a condition-code physical register.
*/
bool isCCPhysReg(PhysRegIndex reg_idx)
{
return (baseCCRegIndex <= reg_idx && reg_idx < totalNumRegs);
}
/** Reads an integer register. */
uint64_t readIntReg(PhysRegIndex reg_idx) const
{
assert(isIntPhysReg(reg_idx));
DPRINTF(IEW, "RegFile: Access to int register %i, has data "
"%#x\n", int(reg_idx), intRegFile[reg_idx]);
return intRegFile[reg_idx];
}
/** Reads a floating point register (double precision). */
FloatReg readFloatReg(PhysRegIndex reg_idx) const
{
assert(isFloatPhysReg(reg_idx));
// Remove the base Float reg dependency.
PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
DPRINTF(IEW, "RegFile: Access to float register %i, has "
"data %#x\n", int(reg_idx), floatRegFile[reg_offset].q);
return floatRegFile[reg_offset].d;
}
FloatRegBits readFloatRegBits(PhysRegIndex reg_idx) const
{
assert(isFloatPhysReg(reg_idx));
// Remove the base Float reg dependency.
PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
FloatRegBits floatRegBits = floatRegFile[reg_offset].q;
DPRINTF(IEW, "RegFile: Access to float register %i as int, "
"has data %#x\n", int(reg_idx), (uint64_t)floatRegBits);
return floatRegBits;
}
/** Reads a condition-code register. */
CCReg readCCReg(PhysRegIndex reg_idx)
{
assert(isCCPhysReg(reg_idx));
// Remove the base CC reg dependency.
PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
DPRINTF(IEW, "RegFile: Access to cc register %i, has "
"data %#x\n", int(reg_idx), ccRegFile[reg_offset]);
return ccRegFile[reg_offset];
}
/** Sets an integer register to the given value. */
void setIntReg(PhysRegIndex reg_idx, uint64_t val)
{
assert(isIntPhysReg(reg_idx));
DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n",
int(reg_idx), val);
if (reg_idx != TheISA::ZeroReg)
intRegFile[reg_idx] = val;
}
/** Sets a double precision floating point register to the given value. */
void setFloatReg(PhysRegIndex reg_idx, FloatReg val)
{
assert(isFloatPhysReg(reg_idx));
// Remove the base Float reg dependency.
PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
int(reg_idx), (uint64_t)val);
#if THE_ISA == ALPHA_ISA
if (reg_offset != TheISA::ZeroReg)
#endif
floatRegFile[reg_offset].d = val;
}
void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val)
{
assert(isFloatPhysReg(reg_idx));
// Remove the base Float reg dependency.
PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
int(reg_idx), (uint64_t)val);
floatRegFile[reg_offset].q = val;
}
/** Sets a condition-code register to the given value. */
void setCCReg(PhysRegIndex reg_idx, CCReg val)
{
assert(isCCPhysReg(reg_idx));
// Remove the base CC reg dependency.
PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n",
int(reg_idx), (uint64_t)val);
ccRegFile[reg_offset] = val;
}
};
#endif //__CPU_O3_REGFILE_HH__