Vc  1.4.0
SIMD Vector Classes for C++
types.h
1 /* This file is part of the Vc library. {{{
2 Copyright © 2012-2015 Matthias Kretz <kretz@kde.org>
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6  * Redistributions of source code must retain the above copyright
7  notice, this list of conditions and the following disclaimer.
8  * Redistributions in binary form must reproduce the above copyright
9  notice, this list of conditions and the following disclaimer in the
10  documentation and/or other materials provided with the distribution.
11  * Neither the names of contributing organizations nor the
12  names of its contributors may be used to endorse or promote products
13  derived from this software without specific prior written permission.
14 
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
19 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 }}}*/
27 
28 #ifndef VC_COMMON_TYPES_H_
29 #define VC_COMMON_TYPES_H_
30 
31 #ifdef Vc_CHECK_ALIGNMENT
32 #include <cstdlib>
33 #include <cstdio>
34 #endif
35 
36 #include "../global.h"
37 #include "../traits/type_traits.h"
38 #include "permutation.h"
39 
40 namespace Vc_VERSIONED_NAMESPACE
41 {
44 
46 using std::size_t;
47 
49 using llong = long long;
51 using ullong = unsigned long long;
53 using ulong = unsigned long;
55 using uint = unsigned int;
57 using ushort = unsigned short;
59 using uchar = unsigned char;
61 using schar = signed char;
62 
66 struct VectorSpecialInitializerZero {};
70 struct VectorSpecialInitializerOne {};
74 struct VectorSpecialInitializerIndexesFromZero {};
75 
80 constexpr VectorSpecialInitializerZero Zero = {};
85 constexpr VectorSpecialInitializerOne One = {};
90 constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero = {};
92 
93 namespace Detail
94 {
95 template<typename T> struct MayAliasImpl {
96 #ifdef __GNUC__
97 #pragma GCC diagnostic push
98 #pragma GCC diagnostic ignored "-Wattributes"
99 #endif
100  typedef T type Vc_MAY_ALIAS;
101 #ifdef __GNUC__
102 #pragma GCC diagnostic pop
103 #endif
104 };
105 //template<size_t Bytes> struct MayAlias<MaskBool<Bytes>> { typedef MaskBool<Bytes> type; };
106 } // namespace Detail
113 #ifdef Vc_ICC
114 template <typename T> using MayAlias [[gnu::may_alias]] = T;
115 #else
116 template <typename T> using MayAlias = typename Detail::MayAliasImpl<T>::type;
117 #endif
118 
119 template <class To, class From> MayAlias<To> &aliasing_cast(From &x)
120 {
121  return *reinterpret_cast<MayAlias<To> *>(&x);
122 }
123 template <class To, class From> const MayAlias<To> &aliasing_cast(const From &x)
124 {
125  return *reinterpret_cast<const MayAlias<To> *>(&x);
126 }
127 
128 template <class To, class From> MayAlias<To> *aliasing_cast(From *x)
129 {
130  return reinterpret_cast<MayAlias<To> *>(x);
131 }
132 template <class To, class From> const MayAlias<To> *aliasing_cast(const From *x)
133 {
134  return reinterpret_cast<const MayAlias<To> *>(x);
135 }
136 
143 enum class Operator : char {
144  Assign,
145  Multiply,
146  MultiplyAssign,
147  Divide,
148  DivideAssign,
149  Remainder,
150  RemainderAssign,
151  Plus,
152  PlusAssign,
153  Minus,
154  MinusAssign,
155  RightShift,
156  RightShiftAssign,
157  LeftShift,
158  LeftShiftAssign,
159  And,
160  AndAssign,
161  Xor,
162  XorAssign,
163  Or,
164  OrAssign,
165  PreIncrement,
166  PostIncrement,
167  PreDecrement,
168  PostDecrement,
169  LogicalAnd,
170  LogicalOr,
171  Comma,
172  UnaryPlus,
173  UnaryMinus,
174  UnaryNot,
175  UnaryOnesComplement,
176  CompareEqual,
177  CompareNotEqual,
178  CompareLess,
179  CompareGreater,
180  CompareLessEqual,
181  CompareGreaterEqual
182 };
183 
184 // forward declaration for Vc::array in <Vc/array>
185 template <typename T, std::size_t N> struct array;
186 
187 /* TODO: add type for half-float, something along these lines:
188 class half_float
189 {
190  uint16_t data;
191 public:
192  constexpr half_float() : data(0) {}
193  constexpr half_float(const half_float &) = default;
194  constexpr half_float(half_float &&) = default;
195  constexpr half_float &operator=(const half_float &) = default;
196 
197  constexpr explicit half_float(float);
198  constexpr explicit half_float(double);
199  constexpr explicit half_float(int);
200  constexpr explicit half_float(unsigned int);
201 
202  explicit operator float () const;
203  explicit operator double () const;
204  explicit operator int () const;
205  explicit operator unsigned int() const;
206 
207  bool operator==(half_float rhs) const;
208  bool operator!=(half_float rhs) const;
209  bool operator>=(half_float rhs) const;
210  bool operator<=(half_float rhs) const;
211  bool operator> (half_float rhs) const;
212  bool operator< (half_float rhs) const;
213 
214  half_float operator+(half_float rhs) const;
215  half_float operator-(half_float rhs) const;
216  half_float operator*(half_float rhs) const;
217  half_float operator/(half_float rhs) const;
218 };
219 */
220 
221 // TODO: the following doesn't really belong into the toplevel Vc namespace.
222 #ifndef Vc_CHECK_ALIGNMENT
223 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *){}
224 #else
225 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *ptr)
226 {
227  const size_t s = alignof(_T);
228  if((reinterpret_cast<size_t>(ptr) & ((s ^ (s & (s - 1))) - 1)) != 0) {
229  fprintf(stderr, "A vector with incorrect alignment has just been created. Look at the stacktrace to find the guilty object.\n");
230  abort();
231  }
232 }
233 #endif
234 
235 namespace Common
236 {
237 // defined in common/simdarrayhelper.h
238 template <typename T, std::size_t Pieces, std::size_t Index> struct Segment;
239 
246 template<size_t StructSize> class SuccessiveEntries
247 {
248 #ifdef Vc_MSVC
249  // scatterinterleavedmemory fails with garbage values in m_first if size_type is a
250  // 64-bit integer type. Using a 32-bit type seems to work around the miscompilation.
251  using size_type = unsigned;
252 #else
253  using size_type = size_t;
254 #endif
255  const size_type m_first;
256 
257 public:
258  typedef SuccessiveEntries AsArg;
259  Vc_INTRINSIC SuccessiveEntries(size_type first) : m_first(first) {}
260  Vc_INTRINSIC Vc_PURE size_type operator[](size_type offset) const
261  {
262  return m_first + offset * StructSize;
263  }
264  Vc_INTRINSIC Vc_PURE size_type data() const { return m_first; }
265  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator+(const SuccessiveEntries &rhs) const
266  {
267  return SuccessiveEntries(m_first + rhs.m_first);
268  }
269  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator*(const SuccessiveEntries &rhs) const
270  {
271  return SuccessiveEntries(m_first * rhs.m_first);
272  }
273  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator<<(size_type x) const
274  {
275  return {m_first << x};
276  }
277 
278  friend Vc_INTRINSIC SuccessiveEntries &internal_data(SuccessiveEntries &x)
279  {
280  return x;
281  }
282  friend Vc_INTRINSIC const SuccessiveEntries &internal_data(const SuccessiveEntries &x)
283  {
284  return x;
285  }
286 };
287 
288 // declaration for functions in common/malloc.h
289 template <std::size_t alignment>
290 Vc_INTRINSIC_L void *aligned_malloc(std::size_t n) Vc_INTRINSIC_R;
291 Vc_ALWAYS_INLINE_L void free(void *p) Vc_ALWAYS_INLINE_R;
292 
296 template <typename Mask, typename T, typename U>
297 using enable_if_mask_converts_implicitly =
298  enable_if<(!std::is_same<Mask, Traits::decay<U>>::value && // that'd be the copy ctor
300  Traits::is_implicit_cast_allowed_mask<
301  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value)>;
305 template <typename T, typename U>
306 using enable_if_mask_converts_explicitly = enable_if<(
309  !Traits::is_implicit_cast_allowed_mask<
310  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value))>;
311 
315 template <typename T> using WidthT = std::integral_constant<std::size_t, sizeof(T)>;
316 
317 // forward declaration of MaskBool in common/maskbool.h
318 template <std::size_t Bytes> class MaskBool;
319 
320 // forward declaration of SubscriptOperation in common/subscript.h
321 template <typename T, typename IndexVector, typename Scale, bool>
322 class SubscriptOperation;
323 
331 template <typename T, typename IndexVector> struct GatherArguments
332 {
333  const IndexVector indexes;
334  const T *const address;
335 };
336 
344 template <typename T, typename IndexVector> struct ScatterArguments
345 {
346  const IndexVector indexes;
347  T *const address;
348 };
349 
353 template <typename I, I Begin, I End, typename F>
354 Vc_INTRINSIC enable_if<(Begin >= End), void> unrolled_loop(F &&)
355 {
356 }
357 
363 template <typename I, I Begin, I End, typename F>
364 Vc_INTRINSIC Vc_FLATTEN enable_if<(Begin < End), void> unrolled_loop(F &&f)
365 {
366  f(Begin);
367  unrolled_loop<I, Begin + 1, End>(f);
368 }
369 
374 template <std::size_t Size, typename F> Vc_INTRINSIC void for_all_vector_entries(F &&f)
375 {
376  unrolled_loop<std::size_t, 0u, Size>(std::forward<F>(f));
377 }
378 
383 template <class T, std::size_t Size = sizeof(T), std::size_t Alignment = alignof(T)>
384 struct ensure_alignment_equals_sizeof {
385  Vc_ALIGNED_TYPEDEF(Size, T, type);
386 };
387 template <class T, std::size_t Size>
388 struct ensure_alignment_equals_sizeof<T, Size, Size> {
389  using type = T;
390 };
391 
392 } // namespace Common
393 } // namespace Vc
394 
395 #include "vector.h"
396 #include "mask.h"
397 #include "memoryfwd.h"
398 
399 #endif // VC_COMMON_TYPES_H_
400 
401 // vim: foldmethod=marker
signed char schar
signed char shorthand
Definition: types.h:61
void free(T *p)
Frees memory that was allocated with Vc::malloc.
Definition: memory.h:102
unsigned char uchar
unsigned char shorthand
Definition: types.h:59
unsigned int uint
unsigned int shorthand
Definition: types.h:55
unsigned long long ullong
unsigned long long shorthand
Definition: types.h:51
constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero
The special object Vc::IndexesFromZero can be used to construct Vector objects initialized to values ...
Definition: types.h:90
std::ostream & operator<<(std::ostream &out, const Vc::Vector< T, Abi > &v)
Prints the contents of a vector into a stream object.
Definition: IO:117
result_vector_type< L, R > operator*(L &&lhs, R &&rhs)
Applies * component-wise and concurrently.
Definition: simdarray.h:1682
Identifies any possible SimdMaskArray<T, N> type (independent of const/volatile or reference) ...
Definition: type_traits.h:151
long long llong
long long shorthand
Definition: types.h:49
result_vector_type< L, R > operator+(L &&lhs, R &&rhs)
Applies + component-wise and concurrently.
Definition: simdarray.h:1682
unsigned long ulong
unsigned long shorthand
Definition: types.h:53
unsigned short ushort
unsigned short shorthand
Definition: types.h:57
constexpr VectorSpecialInitializerZero Zero
The special object Vc::Zero can be used to construct Vector and Mask objects initialized to zero/fals...
Definition: types.h:80
constexpr VectorSpecialInitializerOne One
The special object Vc::One can be used to construct Vector and Mask objects initialized to one/true...
Definition: types.h:85
Identifies any SIMD mask type (independent of implementation or whether it&#39;s SimdMaskArray<T, N>).
Definition: type_traits.h:125
This is std::array with additional subscript operators supporting gather and scatter operations...
Definition: array:86