Vc  1.4.3
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 <ratio>
37 #include "../global.h"
38 #include "../traits/type_traits.h"
39 #include "permutation.h"
40 
41 namespace Vc_VERSIONED_NAMESPACE
42 {
45 
47 using std::size_t;
48 
50 using llong = long long;
52 using ullong = unsigned long long;
54 using ulong = unsigned long;
56 using uint = unsigned int;
58 using ushort = unsigned short;
60 using uchar = unsigned char;
62 using schar = signed char;
63 
67 struct VectorSpecialInitializerZero {};
71 struct VectorSpecialInitializerOne {};
75 struct VectorSpecialInitializerIndexesFromZero {};
76 
81 constexpr VectorSpecialInitializerZero Zero = {};
86 constexpr VectorSpecialInitializerOne One = {};
91 constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero = {};
93 
94 namespace Detail
95 {
96 template<typename T> struct MayAliasImpl {
97 #ifdef Vc_ICC
98 #pragma warning(disable:2621)
99 #endif
100 #ifdef __GNUC__
101 #pragma GCC diagnostic push
102 #pragma GCC diagnostic ignored "-Wattributes"
103 #endif
104  typedef T type Vc_MAY_ALIAS;
105 #ifdef __GNUC__
106 #pragma GCC diagnostic pop
107 #endif
108 #ifdef Vc_ICC
109 #pragma warning(enable:2621)
110 #endif
111 };
112 //template<size_t Bytes> struct MayAlias<MaskBool<Bytes>> { typedef MaskBool<Bytes> type; };
113 } // namespace Detail
120 template <typename T> using MayAlias = typename Detail::MayAliasImpl<T>::type;
121 
122 template <class To, class From> MayAlias<To> &aliasing_cast(From &x)
123 {
124  return *reinterpret_cast<MayAlias<To> *>(&x);
125 }
126 template <class To, class From> const MayAlias<To> &aliasing_cast(const From &x)
127 {
128  return *reinterpret_cast<const MayAlias<To> *>(&x);
129 }
130 
131 template <class To, class From> MayAlias<To> *aliasing_cast(From *x)
132 {
133  return reinterpret_cast<MayAlias<To> *>(x);
134 }
135 template <class To, class From> const MayAlias<To> *aliasing_cast(const From *x)
136 {
137  return reinterpret_cast<const MayAlias<To> *>(x);
138 }
139 
146 enum class Operator : char {
147  Assign,
148  Multiply,
149  MultiplyAssign,
150  Divide,
151  DivideAssign,
152  Remainder,
153  RemainderAssign,
154  Plus,
155  PlusAssign,
156  Minus,
157  MinusAssign,
158  RightShift,
159  RightShiftAssign,
160  LeftShift,
161  LeftShiftAssign,
162  And,
163  AndAssign,
164  Xor,
165  XorAssign,
166  Or,
167  OrAssign,
168  PreIncrement,
169  PostIncrement,
170  PreDecrement,
171  PostDecrement,
172  LogicalAnd,
173  LogicalOr,
174  Comma,
175  UnaryPlus,
176  UnaryMinus,
177  UnaryNot,
178  UnaryOnesComplement,
179  CompareEqual,
180  CompareNotEqual,
181  CompareLess,
182  CompareGreater,
183  CompareLessEqual,
184  CompareGreaterEqual
185 };
186 
187 // forward declaration for Vc::array in <Vc/array>
188 template <typename T, std::size_t N> struct array;
189 // forward declaration for Vc::span in <Vc/span>
190 namespace Common {
191 template <typename T, std::ptrdiff_t N> class span;
192 }
193 
194 /* TODO: add type for half-float, something along these lines:
195 class half_float
196 {
197  uint16_t data;
198 public:
199  constexpr half_float() : data(0) {}
200  constexpr half_float(const half_float &) = default;
201  constexpr half_float(half_float &&) = default;
202  constexpr half_float &operator=(const half_float &) = default;
203 
204  constexpr explicit half_float(float);
205  constexpr explicit half_float(double);
206  constexpr explicit half_float(int);
207  constexpr explicit half_float(unsigned int);
208 
209  explicit operator float () const;
210  explicit operator double () const;
211  explicit operator int () const;
212  explicit operator unsigned int() const;
213 
214  bool operator==(half_float rhs) const;
215  bool operator!=(half_float rhs) const;
216  bool operator>=(half_float rhs) const;
217  bool operator<=(half_float rhs) const;
218  bool operator> (half_float rhs) const;
219  bool operator< (half_float rhs) const;
220 
221  half_float operator+(half_float rhs) const;
222  half_float operator-(half_float rhs) const;
223  half_float operator*(half_float rhs) const;
224  half_float operator/(half_float rhs) const;
225 };
226 */
227 
228 // TODO: the following doesn't really belong into the toplevel Vc namespace.
229 #ifndef Vc_CHECK_ALIGNMENT
230 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *){}
231 #else
232 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *ptr)
233 {
234  const size_t s = alignof(_T);
235  if((reinterpret_cast<size_t>(ptr) & ((s ^ (s & (s - 1))) - 1)) != 0) {
236  fprintf(stderr, "A vector with incorrect alignment has just been created. Look at the stacktrace to find the guilty object.\n");
237  abort();
238  }
239 }
240 #endif
241 
242 namespace Common
243 {
244 // defined in common/simdarrayhelper.h
245 template <typename T, std::size_t Pieces, std::size_t Index> struct Segment;
246 
253 template<size_t StructSize> class SuccessiveEntries
254 {
255 #ifdef Vc_MSVC
256  // scatterinterleavedmemory fails with garbage values in m_first if size_type is a
257  // 64-bit integer type. Using a 32-bit type seems to work around the miscompilation.
258  using size_type = unsigned;
259 #else
260  using size_type = size_t;
261 #endif
262  const size_type m_first;
263 
264 public:
265  typedef SuccessiveEntries AsArg;
266  Vc_INTRINSIC SuccessiveEntries(size_type first) : m_first(first) {}
267  Vc_INTRINSIC Vc_PURE size_type operator[](size_type offset) const
268  {
269  return m_first + offset * StructSize;
270  }
271  Vc_INTRINSIC Vc_PURE size_type data() const { return m_first; }
272  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator+(const SuccessiveEntries &rhs) const
273  {
274  return SuccessiveEntries(m_first + rhs.m_first);
275  }
276  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator*(const SuccessiveEntries &rhs) const
277  {
278  return SuccessiveEntries(m_first * rhs.m_first);
279  }
280  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator<<(size_type x) const
281  {
282  return {m_first << x};
283  }
284 
285  friend Vc_INTRINSIC SuccessiveEntries &internal_data(SuccessiveEntries &x)
286  {
287  return x;
288  }
289  friend Vc_INTRINSIC const SuccessiveEntries &internal_data(const SuccessiveEntries &x)
290  {
291  return x;
292  }
293 };
294 
295 // declaration for functions in common/malloc.h
296 template <std::size_t alignment>
297 Vc_INTRINSIC_L void *aligned_malloc(std::size_t n) Vc_INTRINSIC_R;
298 Vc_ALWAYS_INLINE_L void free(void *p) Vc_ALWAYS_INLINE_R;
299 
303 template <typename Mask, typename T, typename U>
304 using enable_if_mask_converts_implicitly =
305  enable_if<(!std::is_same<Mask, Traits::decay<U>>::value && // that'd be the copy ctor
306  Traits::is_simd_mask<U>::value && !Traits::isSimdMaskArray<U>::value &&
307  Traits::is_implicit_cast_allowed_mask<
308  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value)>;
312 template <typename T, typename U>
313 using enable_if_mask_converts_explicitly = enable_if<(
314  Traits::isSimdMaskArray<U>::value ||
315  (Traits::is_simd_mask<U>::value &&
316  !Traits::is_implicit_cast_allowed_mask<
317  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value))>;
318 
322 template <typename T> using WidthT = std::integral_constant<std::size_t, sizeof(T)>;
323 
324 // forward declaration of MaskBool in common/maskbool.h
325 template <std::size_t Bytes> class MaskBool;
326 
327 // forward declaration of SubscriptOperation in common/subscript.h
328 template <typename T, typename IndexVector, typename Scale, bool>
329 class SubscriptOperation;
330 
338 template <class T, class IndexVector, int Scale = 1>
339 struct GatherArguments {
340  static_assert(std::is_same<T, remove_cvref_t<T>>::value && !std::is_pointer<T>::value,
341  "GatherArguments expects an cv unqualified non-ref/ptr type");
342  const IndexVector indexes;
343  const T *const address;
344 };
345 template <int Scale, class T, class I>
346 GatherArguments<T, I, Scale> make_gather(const T *m, const I &i)
347 {
348  return {i, m};
349 }
350 
358 template <typename T, typename IndexVector> struct ScatterArguments
359 {
360  const IndexVector indexes;
361  T *const address;
362 };
363 
367 template <typename I, I Begin, I End, typename F>
368 Vc_INTRINSIC enable_if<(Begin >= End), void> unrolled_loop(F &&)
369 {
370 }
371 
377 template <typename I, I Begin, I End, typename F>
378 Vc_INTRINSIC Vc_FLATTEN enable_if<(Begin < End), void> unrolled_loop(F &&f)
379 {
380  f(Begin);
381  unrolled_loop<I, Begin + 1, End>(f);
382 }
383 
388 template <std::size_t Size, typename F> Vc_INTRINSIC void for_all_vector_entries(F &&f)
389 {
390  unrolled_loop<std::size_t, 0u, Size>(std::forward<F>(f));
391 }
392 
393 } // namespace Common
394 } // namespace Vc
395 
396 #include "vector.h"
397 #include "mask.h"
398 #include "memoryfwd.h"
399 
400 #endif // VC_COMMON_TYPES_H_
401 
402 // vim: foldmethod=marker
Common::AdaptSubscriptOperator< Common::span< T, Extent > > span
An adapted std::span with additional subscript operators supporting gather and scatter operations.
Definition: span.h:639
result_vector_type< L, R > operator+(L &&lhs, R &&rhs)
Applies + component-wise and concurrently.
Definition: simdarray.h:1722
result_vector_type< L, R > operator*(L &&lhs, R &&rhs)
Applies * component-wise and concurrently.
Definition: simdarray.h:1722
constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero
The special object Vc::IndexesFromZero can be used to construct Vector objects initialized to values ...
Definition: types.h:91
unsigned long long ullong
unsigned long long shorthand
Definition: types.h:52
unsigned long ulong
unsigned long shorthand
Definition: types.h:54
long long llong
long long shorthand
Definition: types.h:50
unsigned int uint
unsigned int shorthand
Definition: types.h:56
constexpr VectorSpecialInitializerOne One
The special object Vc::One can be used to construct Vector and Mask objects initialized to one/true.
Definition: types.h:86
signed char schar
signed char shorthand
Definition: types.h:62
constexpr VectorSpecialInitializerZero Zero
The special object Vc::Zero can be used to construct Vector and Mask objects initialized to zero/fals...
Definition: types.h:81
unsigned char uchar
unsigned char shorthand
Definition: types.h:60
unsigned short ushort
unsigned short shorthand
Definition: types.h:58
void free(T *p)
Frees memory that was allocated with Vc::malloc.
Definition: malloc.h:163
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