| /* | |
| * 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__ |