gem5  v20.1.0.0
vec_reg.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2018 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
140 #ifndef __ARCH_GENERIC_VEC_REG_HH__
141 #define __ARCH_GENERIC_VEC_REG_HH__
142 
143 #include <array>
144 #include <cassert>
145 #include <iostream>
146 #include <string>
147 #include <type_traits>
148 #include <vector>
149 
150 #include "base/cprintf.hh"
151 #include "base/logging.hh"
152 
153 constexpr unsigned MaxVecRegLenInBytes = 4096;
154 
155 template <size_t Sz>
157 
169 template <typename VecElem, size_t NumElems, bool Const>
170 class VecRegT
171 {
173  static constexpr inline size_t
175  {
176  return sizeof(VecElem) * NumElems;
177  }
178  public:
180  using Container = typename std::conditional<Const,
181  const VecRegContainer<size()>,
183  private:
188 
189  public:
191  VecRegT(Container& cnt) : container(cnt) {};
192 
194  template<bool Condition = !Const>
196  zero() { container.zero(); }
197 
198  template<bool Condition = !Const>
200  operator=(const MyClass& that)
201  {
202  container = that.container;
203  return *this;
204  }
205 
207  const VecElem& operator[](size_t idx) const
208  {
209  return container.template raw_ptr<VecElem>()[idx];
210  }
211 
213  template<bool Condition = !Const>
215  operator[](size_t idx)
216  {
217  return container.template raw_ptr<VecElem>()[idx];
218  }
219 
223  template<typename VE2, size_t NE2, bool C2>
224  bool
226  {
227  return container == that.container;
228  }
232  template<typename VE2, size_t NE2, bool C2>
233  bool
235  {
236  return !operator==(that);
237  }
238 
240  friend std::ostream&
241  operator<<(std::ostream& os, const MyClass& vr)
242  {
243  /* 0-sized is not allowed */
244  os << "[" << std::hex << (uint32_t)vr[0];
245  for (uint32_t e = 1; e < vr.size(); e++)
246  os << " " << std::hex << (uint32_t)vr[e];
247  os << ']';
248  return os;
249  }
250 
251  const std::string print() const { return csprintf("%s", *this); }
257  operator Container&() { return container; }
258 };
259 
260 /* Forward declaration. */
261 template <typename VecElem, bool Const>
262 class VecLaneT;
263 
271 template <size_t SIZE>
272 class VecRegContainer
273 {
274  static_assert(SIZE > 0,
275  "Cannot create Vector Register Container of zero size");
276  static_assert(SIZE <= MaxVecRegLenInBytes,
277  "Vector Register size limit exceeded");
278  public:
279  static constexpr inline size_t size() { return SIZE; };
280  using Container = std::array<uint8_t, SIZE>;
281  private:
282  // 16-byte aligned to support 128bit element view
283  alignas(16) Container container;
285 
286  public:
288  VecRegContainer(const VecRegContainer &) = default;
289  /* This is required for de-serialisation. */
291  {
292  assert(that.size() >= SIZE);
293  std::memcpy(container.data(), &that[0], SIZE);
294  }
295 
297  void zero() { memset(container.data(), 0, SIZE); }
298 
302  MyClass& operator=(const MyClass& that)
303  {
304  if (&that == this)
305  return *this;
306  memcpy(container.data(), that.container.data(), SIZE);
307  return *this;
308  }
309 
312  {
313  std::memcpy(container.data(), that.data(), SIZE);
314  return *this;
315  }
316 
321  {
322  assert(that.size() >= SIZE);
323  std::memcpy(container.data(), that.data(), SIZE);
324  return *this;
325  }
331  void copyTo(Container& dst) const
332  {
333  std::memcpy(dst.data(), container.data(), SIZE);
334  }
335 
339  void copyTo(std::vector<uint8_t>& dst) const
340  {
341  dst.resize(SIZE);
342  std::memcpy(dst.data(), container.data(), SIZE);
343  }
349  template<size_t S2>
350  inline bool
351  operator==(const VecRegContainer<S2>& that) const
352  {
353  return SIZE == S2 &&
354  !memcmp(container.data(), that.container.data(), SIZE);
355  }
359  template<size_t S2>
360  bool
361  operator!=(const VecRegContainer<S2>& that) const
362  {
363  return !operator==(that);
364  }
365 
366  const std::string print() const { return csprintf("%s", *this); }
368  template <typename Ret>
369  const Ret* raw_ptr() const { return (const Ret*)container.data(); }
370 
371  template <typename Ret>
372  Ret* raw_ptr() { return (Ret*)container.data(); }
373 
385  template <typename VecElem, size_t NumElems=(SIZE / sizeof(VecElem))>
387  {
388  static_assert(SIZE % sizeof(VecElem) == 0,
389  "VecElem does not evenly divide the register size");
390  static_assert(sizeof(VecElem) * NumElems <= SIZE,
391  "Viewing VecReg as something bigger than it is");
392  return VecRegT<VecElem, NumElems, true>(*this);
393  }
394 
395  template <typename VecElem, size_t NumElems=(SIZE / sizeof(VecElem))>
397  {
398  static_assert(SIZE % sizeof(VecElem) == 0,
399  "VecElem does not evenly divide the register size");
400  static_assert(sizeof(VecElem) * NumElems <= SIZE,
401  "Viewing VecReg as something bigger than it is");
402  return VecRegT<VecElem, NumElems, false>(*this);
403  }
404 
405  template <typename VecElem, int LaneIdx>
407  template <typename VecElem, int LaneIdx>
409  template <typename VecElem>
410  VecLaneT<VecElem, false> laneView(int laneIdx);
411  template <typename VecElem>
412  VecLaneT<VecElem, true> laneView(int laneIdx) const;
418  friend std::ostream& operator<<(std::ostream& os, const MyClass& v)
419  {
420  for (auto& b: v.container) {
421  os << csprintf("%02x", b);
422  }
423  return os;
424  }
425 };
426 
432 enum class LaneSize
433 {
434  Empty = 0,
435  Byte,
436  TwoByte,
437  FourByte,
438  EightByte,
439 };
440 
457 template <LaneSize LS>
458 class LaneData
459 {
460  public:
462  using UnderlyingType =
463  typename std::conditional<LS == LaneSize::EightByte, uint64_t,
464  typename std::conditional<LS == LaneSize::FourByte, uint32_t,
465  typename std::conditional<LS == LaneSize::TwoByte, uint16_t,
466  typename std::conditional<LS == LaneSize::Byte, uint8_t,
467  void>::type
468  >::type
469  >::type
471  private:
472  static constexpr auto ByteSz = sizeof(UnderlyingType);
475 
476  public:
477  template <typename T> explicit
478  LaneData(typename std::enable_if<sizeof(T) == ByteSz, const T&>::type t)
479  : _val(t) {}
480 
481  template <typename T>
482  typename std::enable_if<sizeof(T) == ByteSz, MyClass&>::type
483  operator=(const T& that)
484  {
485  _val = that;
486  return *this;
487  }
488  template<typename T,
489  typename std::enable_if<sizeof(T) == ByteSz, int>::type I = 0>
490  operator T() const {
491  return *static_cast<const T*>(&_val);
492  }
493 };
494 
496 template <LaneSize LS>
497 inline std::ostream&
498 operator<<(std::ostream& os, const LaneData<LS>& d)
499 {
500  return os << static_cast<typename LaneData<LS>::UnderlyingType>(d);
501 }
502 
510 /* General */
511 template <typename VecElem, bool Const>
512 class VecLaneT
513 {
514  public:
520 
521  /*template <size_t Sz>
522  friend class VecRegContainer;*/
523  friend class VecRegContainer<8>;
524  friend class VecRegContainer<16>;
525  friend class VecRegContainer<32>;
526  friend class VecRegContainer<64>;
527  friend class VecRegContainer<128>;
528  friend class VecRegContainer<256>;
530 
533 
534  private:
535  using Cont = typename std::conditional<Const,
536  const VecElem,
538  static_assert(!std::is_const<VecElem>::value || Const,
539  "Asked for non-const lane of const type!");
540  static_assert(std::is_integral<VecElem>::value,
541  "VecElem type is not integral!");
543  Cont& container;
544 
546  VecLaneT(Cont& cont) : container(cont) { }
547 
548  public:
554  template <bool Assignable = !Const>
556  operator=(const VecElem& that) {
557  container = that;
558  return *this;
559  }
565  template <bool Assignable = !Const, typename T>
567  operator=(const T& that) {
568  static_assert(sizeof(T) >= sizeof(VecElem),
569  "Attempt to perform widening bitwise copy.");
570  static_assert(sizeof(T) <= sizeof(VecElem),
571  "Attempt to perform narrowing bitwise copy.");
572  container = static_cast<VecElem>(that);
573  return *this;
574  }
577  operator VecElem() const { return container; }
578 
582  {
584  }
585 };
586 
587 namespace std {
588  template<typename T, bool Const>
589  struct add_const<VecLaneT<T, Const>> { typedef VecLaneT<T, true> type; };
590 }
591 
593 template <size_t Sz>
594 template <typename VecElem, int LaneIdx>
597 {
598  return VecLaneT<VecElem, false>(as<VecElem>()[LaneIdx]);
599 }
600 
602 template <size_t Sz>
603 template <typename VecElem, int LaneIdx>
606 {
607  return VecLaneT<VecElem, true>(as<VecElem>()[LaneIdx]);
608 }
609 
611 template <size_t Sz>
612 template <typename VecElem>
615 {
616  return VecLaneT<VecElem, false>(as<VecElem>()[laneIdx]);
617 }
618 
620 template <size_t Sz>
621 template <typename VecElem>
624 {
625  return VecLaneT<VecElem, true>(as<VecElem>()[laneIdx]);
626 }
627 
632 
637 
642 template <size_t Sz>
643 inline bool
644 to_number(const std::string& value, VecRegContainer<Sz>& v)
645 {
646  fatal_if(value.size() > 2 * VecRegContainer<Sz>::size(),
647  "Vector register value overflow at unserialize");
648 
649  for (int i = 0; i < VecRegContainer<Sz>::size(); i++) {
650  uint8_t b = 0;
651  if (2 * i < value.size())
652  b = stoul(value.substr(i * 2, 2), nullptr, 16);
653  v.template raw_ptr<uint8_t>()[i] = b;
654  }
655  return true;
656 }
664 using DummyVecElem = uint32_t;
665 constexpr unsigned DummyNumVecElemPerVecReg = 2;
670  sizeof(DummyVecElem);
673 #endif /* __ARCH_GENERIC_VEC_REG_HH__ */
DummyVecRegSizeBytes
constexpr size_t DummyVecRegSizeBytes
Definition: vec_reg.hh:669
VecRegT::size
static constexpr size_t size()
Size of the register in bytes.
Definition: vec_reg.hh:174
X86ISA::os
Bitfield< 17 > os
Definition: misc.hh:803
VecLaneT::VecLaneT
VecLaneT(Cont &cont)
Constructor.
Definition: vec_reg.hh:546
LaneSize
LaneSize
We define an auxiliary abstraction for LaneData.
Definition: vec_reg.hh:432
LaneSize::TwoByte
@ TwoByte
VecRegT::operator!=
bool operator!=(const VecRegT< VE2, NE2, C2 > &that) const
Inequality operator.
Definition: vec_reg.hh:234
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
VecRegContainer::operator=
MyClass & operator=(const std::vector< uint8_t > &that)
From vector<uint8_t>.
Definition: vec_reg.hh:320
VecRegContainer::raw_ptr
const Ret * raw_ptr() const
Get pointer to bytes.
Definition: vec_reg.hh:369
type
uint8_t type
Definition: inet.hh:421
VecRegContainer::VecRegContainer
VecRegContainer()
Definition: vec_reg.hh:287
std::add_const< VecLaneT< T, Const > >::type
VecLaneT< T, true > type
Definition: vec_reg.hh:589
std::vector< uint8_t >
VecRegContainer::operator=
MyClass & operator=(const Container &that)
From appropriately sized uint8_t[].
Definition: vec_reg.hh:311
VecRegContainer::as
VecRegT< VecElem, NumElems, false > as()
Definition: vec_reg.hh:396
LaneData::_val
UnderlyingType _val
Definition: vec_reg.hh:473
MaxVecRegLenInBytes
constexpr unsigned MaxVecRegLenInBytes
Definition: vec_reg.hh:153
VecLaneT::operator=
std::enable_if< Assignable, MyClass & >::type operator=(const VecElem &that)
Assignment operators.
Definition: vec_reg.hh:556
VecLaneT::Cont
typename std::conditional< Const, const VecElem, VecElem >::type Cont
Definition: vec_reg.hh:537
VecRegT::Container
typename std::conditional< Const, const VecRegContainer< size()>, VecRegContainer< size()> >::type Container
Container type alias.
Definition: vec_reg.hh:182
VecRegContainer::raw_ptr
Ret * raw_ptr()
Definition: vec_reg.hh:372
VecRegContainer::laneView
VecLaneT< VecElem, false > laneView()
View as the Nth lane of type VecElem.
Definition: vec_reg.hh:596
VecRegContainer::as
VecRegT< VecElem, NumElems, true > as() const
View interposers.
Definition: vec_reg.hh:386
VecRegContainer::copyTo
void copyTo(Container &dst) const
Copy the contents into the input buffer.
Definition: vec_reg.hh:331
VecRegContainer::operator!=
bool operator!=(const VecRegContainer< S2 > &that) const
Inequality operator.
Definition: vec_reg.hh:361
VecRegT::operator==
bool operator==(const VecRegT< VE2, NE2, C2 > &that) const
Equality operator.
Definition: vec_reg.hh:225
VecRegT::zero
std::enable_if< Condition, void >::type zero()
Zero the container.
Definition: vec_reg.hh:196
LaneData::ByteSz
static constexpr auto ByteSz
Definition: vec_reg.hh:472
VecRegContainer::VecRegContainer
VecRegContainer(const std::vector< uint8_t > &that)
Definition: vec_reg.hh:290
DummyVecRegContainer
DummyVecReg::Container DummyVecRegContainer
Definition: vec_reg.hh:668
ArmISA::VecElem
uint32_t VecElem
Definition: registers.hh:68
VecLaneT
Vector Lane abstraction Another view of a container.
Definition: vec_reg.hh:262
VecRegT::operator=
std::enable_if< Condition, MyClass & >::type operator=(const MyClass &that)
Definition: vec_reg.hh:200
VecRegContainer::operator=
MyClass & operator=(const MyClass &that)
Assignment operators.
Definition: vec_reg.hh:302
VecRegT::operator[]
const VecElem & operator[](size_t idx) const
Index operator.
Definition: vec_reg.hh:207
VecRegContainer::zero
void zero()
Zero the container.
Definition: vec_reg.hh:297
ArmISA::d
Bitfield< 9 > d
Definition: miscregs_types.hh:60
VecRegContainer::print
const std::string print() const
Definition: vec_reg.hh:366
to_number
bool to_number(const std::string &value, VecRegContainer< Sz > &v)
Calls required for serialization/deserialization.
Definition: vec_reg.hh:644
LaneSize::FourByte
@ FourByte
cprintf.hh
LaneData::MyClass
LaneData< LS > MyClass
Definition: vec_reg.hh:474
VecRegContainer::container
Container container
Definition: vec_reg.hh:283
DummyVecElem
uint32_t DummyVecElem
Dummy type aliases and constants for architectures that do not implement vector registers.
Definition: vec_reg.hh:664
VecRegT::VecRegT
VecRegT(Container &cnt)
Constructor.
Definition: vec_reg.hh:191
VecRegContainer::size
static constexpr size_t size()
Definition: vec_reg.hh:279
VecRegContainer::copyTo
void copyTo(std::vector< uint8_t > &dst) const
To vector<uint8_t> This is required for serialisation.
Definition: vec_reg.hh:339
LaneSize::Byte
@ Byte
LaneSize::Empty
@ Empty
ArmISA::e
Bitfield< 9 > e
Definition: miscregs_types.hh:61
VecLaneT::operator=
std::enable_if< Assignable, MyClass & >::type operator=(const T &that)
Generic.
Definition: vec_reg.hh:567
LaneData::LaneData
LaneData(typename std::enable_if< sizeof(T)==ByteSz, const T & >::type t)
Definition: vec_reg.hh:478
VecRegContainer::operator==
bool operator==(const VecRegContainer< S2 > &that) const
Equality operator.
Definition: vec_reg.hh:351
VecRegT::operator[]
std::enable_if< Condition, VecElem & >::type operator[](size_t idx)
Index operator.
Definition: vec_reg.hh:215
ArmISA::b
Bitfield< 7 > b
Definition: miscregs_types.hh:376
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
DummyNumVecElemPerVecReg
constexpr unsigned DummyNumVecElemPerVecReg
Definition: vec_reg.hh:665
VecRegContainer::operator<<
friend std::ostream & operator<<(std::ostream &os, const MyClass &v)
Output operator.
Definition: vec_reg.hh:418
logging.hh
operator<<
std::ostream & operator<<(std::ostream &os, const LaneData< LS > &d)
Output operator overload for LaneData<Size>.
Definition: vec_reg.hh:498
VecLaneT::container
Cont & container
Reference to data.
Definition: vec_reg.hh:539
LaneSize::EightByte
@ EightByte
LaneData::UnderlyingType
typename std::conditional< LS==LaneSize::EightByte, uint64_t, typename std::conditional< LS==LaneSize::FourByte, uint32_t, typename std::conditional< LS==LaneSize::TwoByte, uint16_t, typename std::conditional< LS==LaneSize::Byte, uint8_t, void >::type >::type >::type >::type UnderlyingType
Alias to the native type of the appropriate size.
Definition: vec_reg.hh:470
VecRegT::container
Container & container
Reference to container.
Definition: vec_reg.hh:187
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
VecRegContainer< TheISA::VecRegSizeBytes >::Container
std::array< uint8_t, SIZE > Container
Definition: vec_reg.hh:280
HtmFailureFaultCause::SIZE
@ SIZE
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
ArmISA::v
Bitfield< 28 > v
Definition: miscregs_types.hh:51
LaneData
LaneSize is an abstraction of a LS byte value for the execution and thread contexts to handle values ...
Definition: vec_reg.hh:458
VecRegT::operator<<
friend std::ostream & operator<<(std::ostream &os, const MyClass &vr)
Output stream operator.
Definition: vec_reg.hh:241
VecRegContainer
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
Definition: vec_reg.hh:156
VecRegT
Vector Register Abstraction This generic class is a view in a particularization of MVC,...
Definition: vec_reg.hh:170
VecRegT::print
const std::string print() const
Definition: vec_reg.hh:251

Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17