diff options
Diffstat (limited to 'src/cpu/o3/regfile.cc')
-rw-r--r-- | src/cpu/o3/regfile.cc | 120 |
1 files changed, 115 insertions, 5 deletions
diff --git a/src/cpu/o3/regfile.cc b/src/cpu/o3/regfile.cc index ea4370f48..2f41e2ac2 100644 --- a/src/cpu/o3/regfile.cc +++ b/src/cpu/o3/regfile.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2016 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved. @@ -34,19 +46,30 @@ #include "cpu/o3/regfile.hh" #include "cpu/o3/free_list.hh" +#include "arch/generic/types.hh" +#include "cpu/o3/free_list.hh" PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, unsigned _numPhysicalFloatRegs, - unsigned _numPhysicalCCRegs) + unsigned _numPhysicalVecRegs, + unsigned _numPhysicalCCRegs, + VecMode vmode) : intRegFile(_numPhysicalIntRegs), floatRegFile(_numPhysicalFloatRegs), + vectorRegFile(_numPhysicalVecRegs), ccRegFile(_numPhysicalCCRegs), numPhysicalIntRegs(_numPhysicalIntRegs), numPhysicalFloatRegs(_numPhysicalFloatRegs), + numPhysicalVecRegs(_numPhysicalVecRegs), + numPhysicalVecElemRegs(_numPhysicalVecRegs * + NumVecElemPerVecReg), numPhysicalCCRegs(_numPhysicalCCRegs), totalNumRegs(_numPhysicalIntRegs + _numPhysicalFloatRegs - + _numPhysicalCCRegs) + + _numPhysicalVecRegs + + _numPhysicalVecRegs * NumVecElemPerVecReg + + _numPhysicalCCRegs), + vecMode(vmode) { PhysRegIndex phys_reg; PhysRegIndex flat_reg_idx = 0; @@ -68,6 +91,23 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, floatRegIds.emplace_back(FloatRegClass, phys_reg, flat_reg_idx++); } + // The next batch of the registers are the vector physical + // registers; put them onto the vector free list. + for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) { + vectorRegFile[phys_reg].zero(); + vecRegIds.emplace_back(VecRegClass, phys_reg, flat_reg_idx++); + } + // The next batch of the registers are the vector element physical + // registers; they refer to the same containers as the vector + // registers, just a different (and incompatible) way to access + // them; put them onto the vector free list. + for (phys_reg = 0; phys_reg < numPhysicalVecRegs; phys_reg++) { + for (ElemIndex eIdx = 0; eIdx < NumVecElemPerVecReg; eIdx++) { + vecElemIds.emplace_back(VecElemClass, phys_reg, + eIdx, flat_reg_idx++); + } + } + // The rest of the registers are the condition-code physical // registers; put them onto the condition-code free list. for (phys_reg = 0; phys_reg < numPhysicalCCRegs; phys_reg++) { @@ -90,20 +130,90 @@ PhysRegFile::initFreeList(UnifiedFreeList *freeList) // The initial batch of registers are the integer ones for (reg_idx = 0; reg_idx < numPhysicalIntRegs; reg_idx++) { assert(intRegIds[reg_idx].index() == reg_idx); - freeList->addIntReg(&intRegIds[reg_idx]); } + freeList->addRegs(intRegIds.begin(), intRegIds.end()); // The next batch of the registers are the floating-point physical // registers; put them onto the floating-point free list. for (reg_idx = 0; reg_idx < numPhysicalFloatRegs; reg_idx++) { assert(floatRegIds[reg_idx].index() == reg_idx); - freeList->addFloatReg(&floatRegIds[reg_idx]); } + freeList->addRegs(floatRegIds.begin(), floatRegIds.end()); + + /* The next batch of the registers are the vector physical + * registers; put them onto the vector free list. */ + for (reg_idx = 0; reg_idx < numPhysicalVecRegs; reg_idx++) { + assert(vecRegIds[reg_idx].index() == reg_idx); + for (ElemIndex elemIdx = 0; elemIdx < NumVecElemPerVecReg; elemIdx++) { + assert(vecElemIds[reg_idx * NumVecElemPerVecReg + + elemIdx].index() == reg_idx); + assert(vecElemIds[reg_idx * NumVecElemPerVecReg + + elemIdx].elemIndex() == elemIdx); + } + } + + /* depending on the mode we add the vector registers as whole units or + * as different elements. */ + if (vecMode == Enums::Full) + freeList->addRegs(vecRegIds.begin(), vecRegIds.end()); + else + freeList->addRegs(vecElemIds.begin(), vecElemIds.end()); // The rest of the registers are the condition-code physical // registers; put them onto the condition-code free list. for (reg_idx = 0; reg_idx < numPhysicalCCRegs; reg_idx++) { assert(ccRegIds[reg_idx].index() == reg_idx); - freeList->addCCReg(&ccRegIds[reg_idx]); } + freeList->addRegs(ccRegIds.begin(), ccRegIds.end()); } + +auto +PhysRegFile::getRegElemIds(PhysRegIdPtr reg) -> IdRange +{ + panic_if(!reg->isVectorPhysReg(), + "Trying to get elems of a %s register", reg->className()); + auto idx = reg->index(); + return std::make_pair( + vecElemIds.begin() + idx * NumVecElemPerVecReg, + vecElemIds.begin() + (idx+1) * NumVecElemPerVecReg); +} + +auto +PhysRegFile::getRegIds(RegClass cls) -> IdRange +{ + switch (cls) + { + case IntRegClass: + return std::make_pair(intRegIds.begin(), intRegIds.end()); + case FloatRegClass: + return std::make_pair(floatRegIds.begin(), floatRegIds.end()); + case VecRegClass: + return std::make_pair(vecRegIds.begin(), vecRegIds.end()); + case VecElemClass: + return std::make_pair(vecElemIds.begin(), vecElemIds.end()); + case CCRegClass: + return std::make_pair(ccRegIds.begin(), ccRegIds.end()); + case MiscRegClass: + return std::make_pair(miscRegIds.begin(), miscRegIds.end()); + } + /* There is no way to make an empty iterator */ + return std::make_pair(PhysIds::const_iterator(), + PhysIds::const_iterator()); +} + +PhysRegIdPtr +PhysRegFile::getTrueId(PhysRegIdPtr reg) +{ + switch (reg->classValue()) { + case VecRegClass: + return &vecRegIds[reg->index()]; + case VecElemClass: + return &vecElemIds[reg->index() * NumVecElemPerVecReg + + reg->elemIndex()]; + default: + panic_if(!reg->isVectorPhysElem(), + "Trying to get the register of a %s register", reg->className()); + } + return nullptr; +} + |