20 #ifndef VC_COMMON_MACROS_H
21 #define VC_COMMON_MACROS_H
22 #undef VC_COMMON_UNDOMACROS_H
26 #if defined(VC_GCC) && !defined(__OPTIMIZE__)
27 # if VC_GCC >= 0x40500
28 # pragma GCC diagnostic push
29 # define Vc_POP_GCC_DIAGNOSTIC__ 1
32 # pragma GCC diagnostic ignored "-Wold-style-cast"
36 # define ALIGN(n) __declspec(align(n))
37 # define STRUCT_ALIGN1(n) ALIGN(n)
38 # define STRUCT_ALIGN2(n)
39 # define ALIGNED_TYPEDEF(n, _type_, _newType_) typedef ALIGN(n) _type_ _newType_
41 # define ALIGN(n) __attribute__((aligned(n)))
42 # define STRUCT_ALIGN1(n)
43 # define STRUCT_ALIGN2(n) ALIGN(n)
44 # define ALIGNED_TYPEDEF(n, _type_, _newType_) typedef _type_ _newType_ ALIGN(n)
48 #define Vc_ALIGNOF(_TYPE_) alignof(_TYPE_)
50 #define Vc_ALIGNOF(_TYPE_) __alignof(_TYPE_)
54 # define Vc_INTRINSIC_L inline
55 # define Vc_INTRINSIC_R __attribute__((always_inline))
56 # define Vc_INTRINSIC Vc_INTRINSIC_L Vc_INTRINSIC_R
58 # define Vc_CONST __attribute__((const))
60 # define Vc_CONST_R Vc_CONST
61 # define Vc_PURE __attribute__((pure))
63 # define Vc_PURE_R Vc_PURE
64 # define Vc_MAY_ALIAS __attribute__((may_alias))
65 # define Vc_ALWAYS_INLINE_L inline
66 # define Vc_ALWAYS_INLINE_R __attribute__((always_inline))
67 # define Vc_ALWAYS_INLINE Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE_R
68 # define VC_IS_UNLIKELY(x) __builtin_expect(x, 0)
69 # define VC_IS_LIKELY(x) __builtin_expect(x, 1)
70 # define VC_RESTRICT __restrict__
71 # define VC_DEPRECATED(msg)
72 #elif defined(__GNUC__)
73 # if (defined(VC_GCC) && VC_GCC < 0x40300) || defined(VC_OPEN64)
77 # define Vc_MAY_ALIAS __attribute__((__may_alias__))
79 # if (defined(VC_GCC) && VC_GCC < 0x40300)
81 # define Vc_INTRINSIC_R __attribute__((__flatten__))
82 # elif defined(VC_OPEN64)
84 # define Vc_INTRINSIC_R __attribute__((__flatten__, __always_inline__))
86 # define Vc_INTRINSIC_R __attribute__((__flatten__, __always_inline__, __artificial__))
88 # define Vc_INTRINSIC_L inline
89 # define Vc_INTRINSIC Vc_INTRINSIC_L Vc_INTRINSIC_R
90 # define Vc_FLATTEN __attribute__((__flatten__))
91 # define Vc_ALWAYS_INLINE_L inline
92 # define Vc_ALWAYS_INLINE_R __attribute__((__always_inline__))
93 # define Vc_ALWAYS_INLINE Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE_R
99 # define Vc_PURE __attribute__((__pure__))
100 # define Vc_CONST __attribute__((__const__))
103 # define Vc_CONST_R Vc_CONST
105 # define Vc_PURE_R Vc_PURE
106 # define VC_IS_UNLIKELY(x) __builtin_expect(x, 0)
107 # define VC_IS_LIKELY(x) __builtin_expect(x, 1)
108 # define VC_RESTRICT __restrict__
109 # define VC_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
115 # define Vc_MAY_ALIAS
117 # define Vc_ALWAYS_INLINE inline __forceinline
118 # define Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE
119 # define Vc_ALWAYS_INLINE_R
120 # define Vc_CONST __declspec(noalias)
121 # define Vc_CONST_L Vc_CONST
124 # define Vc_PURE_L Vc_PURE
126 # define Vc_INTRINSIC inline __forceinline
127 # define Vc_INTRINSIC_L Vc_INTRINSIC
128 # define Vc_INTRINSIC_R
130 # define Vc_ALWAYS_INLINE
131 # define Vc_ALWAYS_INLINE_L
132 # define Vc_ALWAYS_INLINE_R
139 # define Vc_INTRINSIC
140 # define Vc_INTRINSIC_L
141 # define Vc_INTRINSIC_R
143 # define VC_IS_UNLIKELY(x) x
144 # define VC_IS_LIKELY(x) x
145 # define VC_RESTRICT __restrict
146 # define VC_DEPRECATED(msg) __declspec(deprecated(msg))
149 #if __cplusplus >= 201103
150 #define _VC_CONSTEXPR constexpr
151 #define _VC_CONSTEXPR_L _VC_CONSTEXPR
152 #define _VC_CONSTEXPR_R
154 #define _VC_CONSTEXPR Vc_INTRINSIC Vc_CONST
155 #define _VC_CONSTEXPR_L Vc_INTRINSIC_L Vc_CONST_L
156 #define _VC_CONSTEXPR_R Vc_INTRINSIC_R Vc_CONST_R
160 # define _VC_NOEXCEPT noexcept
162 # define _VC_NOEXCEPT throw()
165 #define FREE_STORE_OPERATORS_ALIGNED(alignment) \
166 Vc_ALWAYS_INLINE void *operator new(size_t size) { return _mm_malloc(size, alignment); } \
167 Vc_ALWAYS_INLINE void *operator new(size_t, void *p) { return p; } \
168 Vc_ALWAYS_INLINE void *operator new[](size_t size) { return _mm_malloc(size, alignment); } \
169 Vc_ALWAYS_INLINE void *operator new[](size_t , void *p) { return p; } \
170 Vc_ALWAYS_INLINE void operator delete(void *ptr, size_t) { _mm_free(ptr); } \
171 Vc_ALWAYS_INLINE void operator delete(void *, void *) {} \
172 Vc_ALWAYS_INLINE void operator delete[](void *ptr, size_t) { _mm_free(ptr); } \
173 Vc_ALWAYS_INLINE void operator delete[](void *, void *) {}
176 # define VC_WARN_INLINE
177 # define VC_WARN(msg) __attribute__((warning("\n\t" msg)))
179 # define VC_WARN_INLINE inline
180 # define VC_WARN(msg)
183 #define unrolled_loop16(_it_, _start_, _end_, _code_) \
184 if (_start_ + 0 < _end_) { enum { _it_ = (_start_ + 0) < _end_ ? (_start_ + 0) : _start_ }; _code_ } \
185 if (_start_ + 1 < _end_) { enum { _it_ = (_start_ + 1) < _end_ ? (_start_ + 1) : _start_ }; _code_ } \
186 if (_start_ + 2 < _end_) { enum { _it_ = (_start_ + 2) < _end_ ? (_start_ + 2) : _start_ }; _code_ } \
187 if (_start_ + 3 < _end_) { enum { _it_ = (_start_ + 3) < _end_ ? (_start_ + 3) : _start_ }; _code_ } \
188 if (_start_ + 4 < _end_) { enum { _it_ = (_start_ + 4) < _end_ ? (_start_ + 4) : _start_ }; _code_ } \
189 if (_start_ + 5 < _end_) { enum { _it_ = (_start_ + 5) < _end_ ? (_start_ + 5) : _start_ }; _code_ } \
190 if (_start_ + 6 < _end_) { enum { _it_ = (_start_ + 6) < _end_ ? (_start_ + 6) : _start_ }; _code_ } \
191 if (_start_ + 7 < _end_) { enum { _it_ = (_start_ + 7) < _end_ ? (_start_ + 7) : _start_ }; _code_ } \
192 if (_start_ + 8 < _end_) { enum { _it_ = (_start_ + 8) < _end_ ? (_start_ + 8) : _start_ }; _code_ } \
193 if (_start_ + 9 < _end_) { enum { _it_ = (_start_ + 9) < _end_ ? (_start_ + 9) : _start_ }; _code_ } \
194 if (_start_ + 10 < _end_) { enum { _it_ = (_start_ + 10) < _end_ ? (_start_ + 10) : _start_ }; _code_ } \
195 if (_start_ + 11 < _end_) { enum { _it_ = (_start_ + 11) < _end_ ? (_start_ + 11) : _start_ }; _code_ } \
196 if (_start_ + 12 < _end_) { enum { _it_ = (_start_ + 12) < _end_ ? (_start_ + 12) : _start_ }; _code_ } \
197 if (_start_ + 13 < _end_) { enum { _it_ = (_start_ + 13) < _end_ ? (_start_ + 13) : _start_ }; _code_ } \
198 if (_start_ + 14 < _end_) { enum { _it_ = (_start_ + 14) < _end_ ? (_start_ + 14) : _start_ }; _code_ } \
199 if (_start_ + 15 < _end_) { enum { _it_ = (_start_ + 15) < _end_ ? (_start_ + 15) : _start_ }; _code_ } \
200 do {} while ( false )
202 #define for_all_vector_entries(_it_, _code_) \
203 unrolled_loop16(_it_, 0, Size, _code_)
206 #define VC_EXTERNAL_ASSERT 1
212 #define VC_ASSERT(x) assert(x);
217 #define VC_HAS_BUILTIN(x) __has_builtin(x)
219 #define VC_HAS_BUILTIN(x) 0
222 #ifndef VC_COMMON_MACROS_H_ONCE
223 #define VC_COMMON_MACROS_H_ONCE
225 #define _VC_CAT_HELPER(a, b, c, d) a##b##c##d
226 #define _VC_CAT(a, b, c, d) _VC_CAT_HELPER(a, b, c, d)
228 #if __cplusplus >= 201103 || (defined(VC_MSVC) && VC_MSVC >= 160000000)
229 #define VC_STATIC_ASSERT_NC(cond, msg) \
230 static_assert(cond, #msg)
231 #define VC_STATIC_ASSERT(cond, msg) VC_STATIC_ASSERT_NC(cond, msg)
236 template<
bool>
struct STATIC_ASSERT_FAILURE;
237 template<>
struct STATIC_ASSERT_FAILURE<true> {};
241 #define VC_STATIC_ASSERT_NC(cond, msg) \
242 typedef STATIC_ASSERT_FAILURE<cond> _VC_CAT(static_assert_failed_on_line_,__LINE__,_,msg); \
244 _VC_CAT(static_assert_failed__on_line_,__LINE__,_,msg) = sizeof(_VC_CAT(static_assert_failed_on_line_,__LINE__,_,msg)) \
246 #define VC_STATIC_ASSERT(cond, msg) VC_STATIC_ASSERT_NC(cond, msg)
278 #endif // VC_COMMON_MACROS_H_ONCE
280 #define _CAT_IMPL(a, b) a##b
281 #define CAT(a, b) _CAT_IMPL(a, b)
283 #define Vc_buildDouble(sign, mantissa, exponent) \
284 ((static_cast<double>((mantissa & 0x000fffffffffffffull) | 0x0010000000000000ull) / 0x0010000000000000ull) \
285 * exponentToMultiplier<exponent, 0>::Value \
286 * exponentToMultiplier<exponent, 30>::Value \
287 * exponentToMultiplier<exponent, 60>::Value \
288 * exponentToMultiplier<exponent, 90>::Value \
289 / exponentToDivisor<exponent, 0>::Value \
290 / exponentToDivisor<exponent, -30>::Value \
291 / exponentToDivisor<exponent, -60>::Value \
292 / exponentToDivisor<exponent, -90>::Value \
293 * static_cast<double>(sign))
294 #define Vc_buildFloat(sign, mantissa, exponent) \
295 ((static_cast<float>((mantissa & 0x007fffffu) | 0x00800000) / 0x00800000) \
296 * exponentToMultiplier<exponent, 0>::Value \
297 * exponentToMultiplier<exponent, 30>::Value \
298 * exponentToMultiplier<exponent, 60>::Value \
299 * exponentToMultiplier<exponent, 90>::Value \
300 / exponentToDivisor<exponent, 0>::Value \
301 / exponentToDivisor<exponent, -30>::Value \
302 / exponentToDivisor<exponent, -60>::Value \
303 / exponentToDivisor<exponent, -90>::Value \
304 * static_cast<float>(sign))
306 #define _VC_APPLY_IMPL_1(macro, a, b, c, d, e) macro(a)
307 #define _VC_APPLY_IMPL_2(macro, a, b, c, d, e) macro(a, b)
308 #define _VC_APPLY_IMPL_3(macro, a, b, c, d, e) macro(a, b, c)
309 #define _VC_APPLY_IMPL_4(macro, a, b, c, d, e) macro(a, b, c, d)
310 #define _VC_APPLY_IMPL_5(macro, a, b, c, d, e) macro(a, b, c, d, e)
312 #define VC_LIST_FLOAT_VECTOR_TYPES(size, macro, a, b, c, d) \
313 size(macro, double_v, a, b, c, d) \
314 size(macro, float_v, a, b, c, d) \
315 size(macro, sfloat_v, a, b, c, d)
316 #define VC_LIST_INT_VECTOR_TYPES(size, macro, a, b, c, d) \
317 size(macro, int_v, a, b, c, d) \
318 size(macro, uint_v, a, b, c, d) \
319 size(macro, short_v, a, b, c, d) \
320 size(macro, ushort_v, a, b, c, d)
321 #define VC_LIST_VECTOR_TYPES(size, macro, a, b, c, d) \
322 VC_LIST_FLOAT_VECTOR_TYPES(size, macro, a, b, c, d) \
323 VC_LIST_INT_VECTOR_TYPES(size, macro, a, b, c, d)
324 #define VC_LIST_COMPARES(size, macro, a, b, c, d) \
325 size(macro, ==, a, b, c, d) \
326 size(macro, !=, a, b, c, d) \
327 size(macro, <=, a, b, c, d) \
328 size(macro, >=, a, b, c, d) \
329 size(macro, < , a, b, c, d) \
330 size(macro, > , a, b, c, d)
331 #define VC_LIST_LOGICAL(size, macro, a, b, c, d) \
332 size(macro, &&, a, b, c, d) \
333 size(macro, ||, a, b, c, d)
334 #define VC_LIST_BINARY(size, macro, a, b, c, d) \
335 size(macro, |, a, b, c, d) \
336 size(macro, &, a, b, c, d) \
337 size(macro, ^, a, b, c, d)
338 #define VC_LIST_SHIFTS(size, macro, a, b, c, d) \
339 size(macro, <<, a, b, c, d) \
340 size(macro, >>, a, b, c, d)
341 #define VC_LIST_ARITHMETICS(size, macro, a, b, c, d) \
342 size(macro, +, a, b, c, d) \
343 size(macro, -, a, b, c, d) \
344 size(macro, *, a, b, c, d) \
345 size(macro, /, a, b, c, d) \
346 size(macro, %, a, b, c, d)
348 #define VC_APPLY_0(_list, macro) _list(_VC_APPLY_IMPL_1, macro, 0, 0, 0, 0)
349 #define VC_APPLY_1(_list, macro, a) _list(_VC_APPLY_IMPL_2, macro, a, 0, 0, 0)
350 #define VC_APPLY_2(_list, macro, a, b) _list(_VC_APPLY_IMPL_3, macro, a, b, 0, 0)
351 #define VC_APPLY_3(_list, macro, a, b, c) _list(_VC_APPLY_IMPL_4, macro, a, b, c, 0)
352 #define VC_APPLY_4(_list, macro, a, b, c, d) _list(_VC_APPLY_IMPL_5, macro, a, b, c, d)
354 #define VC_ALL_COMPARES(macro) VC_APPLY_0(VC_LIST_COMPARES, macro)
355 #define VC_ALL_LOGICAL(macro) VC_APPLY_0(VC_LIST_LOGICAL, macro)
356 #define VC_ALL_BINARY(macro) VC_APPLY_0(VC_LIST_BINARY, macro)
357 #define VC_ALL_SHIFTS(macro) VC_APPLY_0(VC_LIST_SHIFTS, macro)
358 #define VC_ALL_ARITHMETICS(macro) VC_APPLY_0(VC_LIST_ARITHMETICS, macro)
359 #define VC_ALL_FLOAT_VECTOR_TYPES(macro) VC_APPLY_0(VC_LIST_FLOAT_VECTOR_TYPES, macro)
360 #define VC_ALL_VECTOR_TYPES(macro) VC_APPLY_0(VC_LIST_VECTOR_TYPES, macro)
362 #define VC_EXACT_TYPE(_test, _reference, _type) \
363 typename EnableIf<IsEqualType<_test, _reference>::Value, _type>::Value
365 #ifdef VC_PASSING_VECTOR_BY_VALUE_IS_BROKEN
366 #define VC_ALIGNED_PARAMETER(_Type) const _Type &
368 #define VC_ALIGNED_PARAMETER(_Type) const _Type
371 #ifndef Vc__make_unique
372 #define Vc__make_unique(name) _VC_CAT(Vc__,name,_,__LINE__)
375 #if defined(VC_ICC) || defined(VC_CLANG)
376 #define VC_OFFSETOF(Type, member) (reinterpret_cast<const char *>(&reinterpret_cast<const Type *>(0)->member) - reinterpret_cast<const char *>(0))
377 #elif defined(VC_GCC) && VC_GCC < 0x40500
378 #define VC_OFFSETOF(Type, member) (reinterpret_cast<const char *>(&reinterpret_cast<const Type *>(0x1000)->member) - reinterpret_cast<const char *>(0x1000))
380 #define VC_OFFSETOF(Type, member) offsetof(Type, member)
384 #endif // VC_COMMON_MACROS_H