From e883a6c9708739e33a66333fed4250042008da76 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 31 Jan 2020 16:57:36 -0800 Subject: [PATCH] arch: Convert the static constexpr SIZE in vec_reg to a function. When defining a static constexpr variable in C++11, it is still required to have a separate definition someplace, something that can be particularly problematic in template classes. C++17 fixes this problem by adding inline variables which don't, but in the mean time having a static constexpr value with no backing store will, if the compiler decides to not fold away the storage location, cause linking errors. This happened to me when trying to build the debug build of ARM just now. By turning these expressions into static inline functions, then they no longer need definitions elsewhere, still fold away to nothing, and are compliant with C++11 which is currently the standard gem5 expects to be using. Change-Id: I647d7cf4a1e8de98251ee9ef116f007e08eac1f3 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24964 Tested-by: kokoro Reviewed-by: Chun-Chen TK Hsu Maintainer: Giacomo Travaglini --- src/arch/arm/fastmodel/iris/thread_context.cc | 2 +- src/arch/generic/vec_reg.hh | 30 +++++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/arch/arm/fastmodel/iris/thread_context.cc b/src/arch/arm/fastmodel/iris/thread_context.cc index 98fc09eb3..85171fcf8 100644 --- a/src/arch/arm/fastmodel/iris/thread_context.cc +++ b/src/arch/arm/fastmodel/iris/thread_context.cc @@ -589,7 +589,7 @@ ThreadContext::readVecReg(const RegId ®_id) const iris::ResourceReadResult result; call().resource_read(_instId, result, vecRegIds.at(idx)); size_t data_size = result.data.size() * (sizeof(*result.data.data())); - size_t size = std::min(data_size, reg.SIZE); + size_t size = std::min(data_size, reg.size()); memcpy(reg.raw_ptr(), (void *)result.data.data(), size); return reg; diff --git a/src/arch/generic/vec_reg.hh b/src/arch/generic/vec_reg.hh index 8b9bea108..4156ac5ef 100644 --- a/src/arch/generic/vec_reg.hh +++ b/src/arch/generic/vec_reg.hh @@ -170,12 +170,16 @@ template class VecRegT { /** Size of the register in bytes. */ - static constexpr size_t SIZE = sizeof(VecElem) * NumElems; + static constexpr inline size_t + size() + { + return sizeof(VecElem) * NumElems; + } public: /** Container type alias. */ using Container = typename std::conditional, - VecRegContainer>::type; + const VecRegContainer, + VecRegContainer>::type; private: /** My type alias. */ using MyClass = VecRegT; @@ -238,7 +242,7 @@ class VecRegT { /* 0-sized is not allowed */ os << "[" << std::hex << (uint32_t)vr[0]; - for (uint32_t e = 1; e < vr.SIZE; e++) + for (uint32_t e = 1; e < vr.size(); e++) os << " " << std::hex << (uint32_t)vr[e]; os << ']'; return os; @@ -264,16 +268,16 @@ class VecLaneT; * portion through the method 'as * @tparam Sz Size of the container in bytes. */ -template +template class VecRegContainer { - static_assert(Sz > 0, + static_assert(SIZE > 0, "Cannot create Vector Register Container of zero size"); - static_assert(Sz <= MaxVecRegLenInBytes, + static_assert(SIZE <= MaxVecRegLenInBytes, "Vector Register size limit exceeded"); public: - static constexpr size_t SIZE = Sz; - using Container = std::array; + static constexpr inline size_t size() { return SIZE; }; + using Container = std::array; private: Container container; using MyClass = VecRegContainer; @@ -377,7 +381,7 @@ class VecRegContainer * @tparam NumElem Amount of elements in the view. */ /** @{ */ - template + template VecRegT as() const { static_assert(SIZE % sizeof(VecElem) == 0, @@ -387,7 +391,7 @@ class VecRegContainer return VecRegT(*this); } - template + template VecRegT as() { static_assert(SIZE % sizeof(VecElem) == 0, @@ -638,10 +642,10 @@ template inline bool to_number(const std::string& value, VecRegContainer& v) { - fatal_if(value.size() > 2 * VecRegContainer::SIZE, + fatal_if(value.size() > 2 * VecRegContainer::size(), "Vector register value overflow at unserialize"); - for (int i = 0; i < VecRegContainer::SIZE; i++) { + for (int i = 0; i < VecRegContainer::size(); i++) { uint8_t b = 0; if (2 * i < value.size()) b = stoul(value.substr(i * 2, 2), nullptr, 16); -- 2.30.2