diff --git a/src/arch/generic/vec_reg.hh b/src/arch/generic/vec_reg.hh index a647cd80eb..3091034a8e 100644 --- a/src/arch/generic/vec_reg.hh +++ b/src/arch/generic/vec_reg.hh @@ -47,8 +47,8 @@ * As the (maximum) length of the physical vector register is a compile-time * constant, it is defined as a template parameter. * - * This file also describes two views of the container that have semantic - * information about the bytes. The first of this views is VecRegT. + * This file also describe one view of the container that has semantic + * information about the bytes, the VecRegT. * A VecRegT is a view of a VecRegContainer (by reference). The VecRegT has * a type (VecElem) to which bytes are casted, and the amount of such * elements that the vector contains (NumElems). The size of a view, @@ -56,18 +56,9 @@ * underlying container. As VecRegT has some degree of type information it * has vector semantics, and defines the index operator ([]) to get * references to particular bytes understood as a VecElem. - * The second view of a container implemented in this file is VecLaneT, which - * is a view of a subset of the container. - * A VecLaneT is a view of a lane of a vector register, where a lane is - * identified by a type (VecElem) and an index (although the view is - * unaware of its index). Operations on the lane are directly applied to - * the corresponding bytes of the underlying VecRegContainer through a - * reference. * * The intended usage is requesting views to the VecRegContainer via the - * member 'as' for VecRegT and the member 'laneView' for VecLaneT. Kindly - * find an example of usage in the following. - * + * member 'as' for VecRegT. * * // We declare 512 bits vectors * using Vec512 = VecRegContainer<64>; @@ -100,41 +91,6 @@ * xc->setWriteRegOperand(this, 0, vdstraw); * } * - * // Usage example, for a micro op that operates over lane number _lidx: - * VecFloatLaneAdd(ExecContext* xd) { - * // Request source vector register to the execution context (const as it - * // is read only). - * const Vec512& vsrc1raw = xc->readVecRegOperand(this, 0); - * // View it as a lane of a vector of floats (we could just specify the - * // first template parametre, the second is derived by the constness of - * // vsrc1raw). - * VecLaneT& src1 = vsrc1raw->laneView(this->_lidx); - * - * // Second source and view - * const Vec512& vsrc2raw = xc->readVecRegOperand(this, 1); - * VecLaneT& src2 = vsrc2raw->laneView(this->_lidx); - * - * // (Writable) destination and view - * // As this is a partial write, we need the exec context to support that - * // through, e.g., 'readVecRegOperandToWrite' returning a writable - * // reference to the register - * Vec512 vdstraw = xc->readVecRegOperandToWrite(this, 3); - * VecLaneT& dst = vdstraw->laneView(this->_lidx); - * - * dst = src1 + src2; - * // There is no need to copy the value back into the exec context, as - * // the assignment to dst modifies the appropriate bytes in vdstraw which - * // is in turn, a reference to the register in the cpu model. - * // For operations that do conditional writeback, we can decouple the - * // write by doing: - * // auto tmp = src1 + src2; - * // if (test) { - * // dst = tmp; // do writeback - * // } else { - * // // do not do writeback - * // } - * } - * */ #ifndef __ARCH_GENERIC_VEC_REG_HH__ @@ -257,10 +213,6 @@ class VecRegT operator Container&() { return container; } }; -/* Forward declaration. */ -template -class VecLaneT; - /** * Vector Register Abstraction * This generic class is the model in a particularization of MVC, to vector @@ -402,14 +354,6 @@ class VecRegContainer return VecRegT(*this); } - template - VecLaneT laneView(); - template - VecLaneT laneView() const; - template - VecLaneT laneView(int laneIdx); - template - VecLaneT laneView(int laneIdx) const; /** @} */ /** * Output operator. @@ -424,217 +368,6 @@ class VecRegContainer } }; -/** We define an auxiliary abstraction for LaneData. The ISA should care - * about the semantics of a, e.g., 32bit element, treating it as a signed or - * unsigned int, or a float depending on the semantics of a particular - * instruction. On the other hand, the cpu model should only care about it - * being a 32-bit value. */ -enum class LaneSize -{ - Empty = 0, - Byte, - TwoByte, - FourByte, - EightByte, -}; - -/** LaneSize is an abstraction of a LS byte value for the execution and thread - * contexts to handle values just depending on its width. That way, the ISA - * can request, for example, the second 4 byte lane of register 5 to the model. - * The model serves that value, agnostic of the semantics of those bits. Then, - * it is up to the ISA to interpret those bits as a float, or as an uint. - * To maximize the utility, this class implements the assignment operator and - * the casting to equal-size types. - * As opposed to a RegLaneT, LaneData is not 'backed' by a VecRegContainer. - * The idea is: - * When data is passed and is susceptible to being copied, use LaneData, as - * copying the primitive type is build on is cheap. - * When data is passed as references (const or not), use RegLaneT, as all - * operations happen 'in place', avoiding any copies (no copies is always - * cheaper than cheap copies), especially when things are inlined, and - * references are not explicitly passed. - */ -template -class LaneData -{ - public: - /** Alias to the native type of the appropriate size. */ - using UnderlyingType = - typename std::conditional::type - >::type - >::type - >::type; - private: - static constexpr auto ByteSz = sizeof(UnderlyingType); - UnderlyingType _val; - using MyClass = LaneData; - - public: - template explicit - LaneData(typename std::enable_if_t t) - : _val(t) {} - - template - typename std::enable_if_t - operator=(const T& that) - { - _val = that; - return *this; - } - template I = 0> - operator T() const { - return *static_cast(&_val); - } -}; - -/** Output operator overload for LaneData. */ -template -inline std::ostream& -operator<<(std::ostream& os, const LaneData& d) -{ - return os << static_cast::UnderlyingType>(d); -} - -/** Vector Lane abstraction - * Another view of a container. This time only a partial part of it is exposed. - * @tparam VecElem Type of each element of the vector. - * @tparam Const Indicate if the underlying container can be modified through - * the view. - */ -/** @{ */ -/* General */ -template -class VecLaneT -{ - public: - /** VecRegContainer friendship to access private VecLaneT constructors. - * Only VecRegContainers can build VecLanes. - */ - /** @{ */ - friend VecLaneT; - - /*template - friend class VecRegContainer;*/ - friend class VecRegContainer<8>; - friend class VecRegContainer<16>; - friend class VecRegContainer<32>; - friend class VecRegContainer<64>; - friend class VecRegContainer<128>; - friend class VecRegContainer<256>; - friend class VecRegContainer; - - /** My type alias. */ - using MyClass = VecLaneT; - - private: - using Cont = typename std::conditional::type; - static_assert(!std::is_const::value || Const, - "Asked for non-const lane of const type!"); - static_assert(std::is_integral::value, - "VecElem type is not integral!"); - /** Reference to data. */ - Cont& container; - - /** Constructor */ - VecLaneT(Cont& cont) : container(cont) { } - - public: - /** Assignment operators. - * Assignment operators are only enabled if the underlying container is - * non-constant. - */ - /** @{ */ - template - typename std::enable_if_t - operator=(const VecElem& that) { - container = that; - return *this; - } - /** - * Generic. - * Generic bitwise assignment. Narrowing and widening assignemnts are - * not allowed, pre-treatment of the rhs is required to conform. - */ - template - typename std::enable_if_t - operator=(const T& that) { - static_assert(sizeof(T) >= sizeof(VecElem), - "Attempt to perform widening bitwise copy."); - static_assert(sizeof(T) <= sizeof(VecElem), - "Attempt to perform narrowing bitwise copy."); - container = static_cast(that); - return *this; - } - /** @} */ - /** Cast to vecElem. */ - operator VecElem() const { return container; } - - /** Constification. */ - template = 0> - operator VecLaneT, true>() - { - return VecLaneT(container); - } -}; - -namespace std { - template - struct add_const> { typedef VecLaneT type; }; -} - -/** View as the Nth lane of type VecElem. */ -template -template -VecLaneT -VecRegContainer::laneView() -{ - return VecLaneT(as()[LaneIdx]); -} - -/** View as the const Nth lane of type VecElem. */ -template -template -VecLaneT -VecRegContainer::laneView() const -{ - return VecLaneT(as()[LaneIdx]); -} - -/** View as the Nth lane of type VecElem. */ -template -template -VecLaneT -VecRegContainer::laneView(int laneIdx) -{ - return VecLaneT(as()[laneIdx]); -} - -/** View as the const Nth lane of type VecElem. */ -template -template -VecLaneT -VecRegContainer::laneView(int laneIdx) const -{ - return VecLaneT(as()[laneIdx]); -} - -using VecLane8 = VecLaneT; -using VecLane16 = VecLaneT; -using VecLane32 = VecLaneT; -using VecLane64 = VecLaneT; - -using ConstVecLane8 = VecLaneT; -using ConstVecLane16 = VecLaneT; -using ConstVecLane32 = VecLaneT; -using ConstVecLane64 = VecLaneT; - /** * Calls required for serialization/deserialization */