Vc 1.4.1
SIMD Vector Classes for C++
types.h
1/* This file is part of the Vc library. {{{
2Copyright © 2012-2015 Matthias Kretz <kretz@kde.org>
3
4Redistribution and use in source and binary forms, with or without
5modification, 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
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
19DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22ON 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
24SOFTWARE, 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
41namespace Vc_VERSIONED_NAMESPACE
42{
45
47using std::size_t;
48
50using llong = long long;
52using ullong = unsigned long long;
54using ulong = unsigned long;
56using uint = unsigned int;
58using ushort = unsigned short;
60using uchar = unsigned char;
62using schar = signed char;
63
67struct VectorSpecialInitializerZero {};
71struct VectorSpecialInitializerOne {};
75struct VectorSpecialInitializerIndexesFromZero {};
76
81constexpr VectorSpecialInitializerZero Zero = {};
86constexpr VectorSpecialInitializerOne One = {};
91constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero = {};
93
94namespace Detail
95{
96template<typename T> struct MayAliasImpl {
97#ifdef __GNUC__
98#pragma GCC diagnostic push
99#pragma GCC diagnostic ignored "-Wattributes"
100#endif
101 typedef T type Vc_MAY_ALIAS;
102#ifdef __GNUC__
103#pragma GCC diagnostic pop
104#endif
105};
106//template<size_t Bytes> struct MayAlias<MaskBool<Bytes>> { typedef MaskBool<Bytes> type; };
107} // namespace Detail
114#ifdef Vc_ICC
115template <typename T> using MayAlias [[gnu::may_alias]] = T;
116#else
117template <typename T> using MayAlias = typename Detail::MayAliasImpl<T>::type;
118#endif
119
120template <class To, class From> MayAlias<To> &aliasing_cast(From &x)
121{
122 return *reinterpret_cast<MayAlias<To> *>(&x);
123}
124template <class To, class From> const MayAlias<To> &aliasing_cast(const From &x)
125{
126 return *reinterpret_cast<const MayAlias<To> *>(&x);
127}
128
129template <class To, class From> MayAlias<To> *aliasing_cast(From *x)
130{
131 return reinterpret_cast<MayAlias<To> *>(x);
132}
133template <class To, class From> const MayAlias<To> *aliasing_cast(const From *x)
134{
135 return reinterpret_cast<const MayAlias<To> *>(x);
136}
137
144enum class Operator : char {
145 Assign,
146 Multiply,
147 MultiplyAssign,
148 Divide,
149 DivideAssign,
150 Remainder,
151 RemainderAssign,
152 Plus,
153 PlusAssign,
154 Minus,
155 MinusAssign,
156 RightShift,
157 RightShiftAssign,
158 LeftShift,
159 LeftShiftAssign,
160 And,
161 AndAssign,
162 Xor,
163 XorAssign,
164 Or,
165 OrAssign,
166 PreIncrement,
167 PostIncrement,
168 PreDecrement,
169 PostDecrement,
170 LogicalAnd,
171 LogicalOr,
172 Comma,
173 UnaryPlus,
174 UnaryMinus,
175 UnaryNot,
176 UnaryOnesComplement,
177 CompareEqual,
178 CompareNotEqual,
179 CompareLess,
180 CompareGreater,
181 CompareLessEqual,
182 CompareGreaterEqual
183};
184
185// forward declaration for Vc::array in <Vc/array>
186template <typename T, std::size_t N> struct array;
187// forward declaration for Vc::span in <Vc/span>
188namespace Common {
189template <typename T, std::ptrdiff_t N> class span;
190}
191
192/* TODO: add type for half-float, something along these lines:
193class half_float
194{
195 uint16_t data;
196public:
197 constexpr half_float() : data(0) {}
198 constexpr half_float(const half_float &) = default;
199 constexpr half_float(half_float &&) = default;
200 constexpr half_float &operator=(const half_float &) = default;
201
202 constexpr explicit half_float(float);
203 constexpr explicit half_float(double);
204 constexpr explicit half_float(int);
205 constexpr explicit half_float(unsigned int);
206
207 explicit operator float () const;
208 explicit operator double () const;
209 explicit operator int () const;
210 explicit operator unsigned int() const;
211
212 bool operator==(half_float rhs) const;
213 bool operator!=(half_float rhs) const;
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
219 half_float operator+(half_float rhs) const;
220 half_float operator-(half_float rhs) const;
221 half_float operator*(half_float rhs) const;
222 half_float operator/(half_float rhs) const;
223};
224*/
225
226// TODO: the following doesn't really belong into the toplevel Vc namespace.
227#ifndef Vc_CHECK_ALIGNMENT
228template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *){}
229#else
230template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *ptr)
231{
232 const size_t s = alignof(_T);
233 if((reinterpret_cast<size_t>(ptr) & ((s ^ (s & (s - 1))) - 1)) != 0) {
234 fprintf(stderr, "A vector with incorrect alignment has just been created. Look at the stacktrace to find the guilty object.\n");
235 abort();
236 }
237}
238#endif
239
240namespace Common
241{
242// defined in common/simdarrayhelper.h
243template <typename T, std::size_t Pieces, std::size_t Index> struct Segment;
244
251template<size_t StructSize> class SuccessiveEntries
252{
253#ifdef Vc_MSVC
254 // scatterinterleavedmemory fails with garbage values in m_first if size_type is a
255 // 64-bit integer type. Using a 32-bit type seems to work around the miscompilation.
256 using size_type = unsigned;
257#else
258 using size_type = size_t;
259#endif
260 const size_type m_first;
261
262public:
263 typedef SuccessiveEntries AsArg;
264 Vc_INTRINSIC SuccessiveEntries(size_type first) : m_first(first) {}
265 Vc_INTRINSIC Vc_PURE size_type operator[](size_type offset) const
266 {
267 return m_first + offset * StructSize;
268 }
269 Vc_INTRINSIC Vc_PURE size_type data() const { return m_first; }
270 Vc_INTRINSIC Vc_PURE SuccessiveEntries operator+(const SuccessiveEntries &rhs) const
271 {
272 return SuccessiveEntries(m_first + rhs.m_first);
273 }
274 Vc_INTRINSIC Vc_PURE SuccessiveEntries operator*(const SuccessiveEntries &rhs) const
275 {
276 return SuccessiveEntries(m_first * rhs.m_first);
277 }
278 Vc_INTRINSIC Vc_PURE SuccessiveEntries operator<<(size_type x) const
279 {
280 return {m_first << x};
281 }
282
283 friend Vc_INTRINSIC SuccessiveEntries &internal_data(SuccessiveEntries &x)
284 {
285 return x;
286 }
287 friend Vc_INTRINSIC const SuccessiveEntries &internal_data(const SuccessiveEntries &x)
288 {
289 return x;
290 }
291};
292
293// declaration for functions in common/malloc.h
294template <std::size_t alignment>
295Vc_INTRINSIC_L void *aligned_malloc(std::size_t n) Vc_INTRINSIC_R;
296Vc_ALWAYS_INLINE_L void free(void *p) Vc_ALWAYS_INLINE_R;
297
301template <typename Mask, typename T, typename U>
302using enable_if_mask_converts_implicitly =
303 enable_if<(!std::is_same<Mask, Traits::decay<U>>::value && // that'd be the copy ctor
304 Traits::is_simd_mask<U>::value && !Traits::isSimdMaskArray<U>::value &&
305 Traits::is_implicit_cast_allowed_mask<
306 Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value)>;
310template <typename T, typename U>
311using enable_if_mask_converts_explicitly = enable_if<(
312 Traits::isSimdMaskArray<U>::value ||
313 (Traits::is_simd_mask<U>::value &&
314 !Traits::is_implicit_cast_allowed_mask<
315 Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value))>;
316
320template <typename T> using WidthT = std::integral_constant<std::size_t, sizeof(T)>;
321
322// forward declaration of MaskBool in common/maskbool.h
323template <std::size_t Bytes> class MaskBool;
324
325// forward declaration of SubscriptOperation in common/subscript.h
326template <typename T, typename IndexVector, typename Scale, bool>
327class SubscriptOperation;
328
336template <class T, class IndexVector, int Scale = 1>
337struct GatherArguments {
338 static_assert(std::is_same<T, remove_cvref_t<T>>::value && !std::is_pointer<T>::value,
339 "GatherArguments expects an cv unqualified non-ref/ptr type");
340 const IndexVector indexes;
341 const T *const address;
342};
343template <int Scale, class T, class I>
344GatherArguments<T, I, Scale> make_gather(const T *m, const I &i)
345{
346 return {i, m};
347}
348
356template <typename T, typename IndexVector> struct ScatterArguments
357{
358 const IndexVector indexes;
359 T *const address;
360};
361
365template <typename I, I Begin, I End, typename F>
366Vc_INTRINSIC enable_if<(Begin >= End), void> unrolled_loop(F &&)
367{
368}
369
375template <typename I, I Begin, I End, typename F>
376Vc_INTRINSIC Vc_FLATTEN enable_if<(Begin < End), void> unrolled_loop(F &&f)
377{
378 f(Begin);
379 unrolled_loop<I, Begin + 1, End>(f);
380}
381
386template <std::size_t Size, typename F> Vc_INTRINSIC void for_all_vector_entries(F &&f)
387{
388 unrolled_loop<std::size_t, 0u, Size>(std::forward<F>(f));
389}
390
391} // namespace Common
392} // namespace Vc
393
394#include "vector.h"
395#include "mask.h"
396#include "memoryfwd.h"
397
398#endif // VC_COMMON_TYPES_H_
399
400// 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:635
result_vector_type< L, R > operator*(L &&lhs, R &&rhs)
Applies * component-wise and concurrently.
Definition: simdarray.h:1721
result_vector_type< L, R > operator+(L &&lhs, R &&rhs)
Applies + component-wise and concurrently.
Definition: simdarray.h:1721
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