268 lines
8.5 KiB
C++
268 lines
8.5 KiB
C++
/*
|
|
* 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__
|