]> git.uio.no Git - u/mrichter/AliRoot.git/blame - Vc/include/Vc/common/macros.h
Vc: update to 0.7.4 release
[u/mrichter/AliRoot.git] / Vc / include / Vc / common / macros.h
CommitLineData
f22341db 1/* This file is part of the Vc library.
2
3 Copyright (C) 2010-2012 Matthias Kretz <kretz@kde.org>
4
5 Vc is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation, either version 3 of
8 the License, or (at your option) any later version.
9
10 Vc is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with Vc. If not, see <http://www.gnu.org/licenses/>.
17
18*/
19
20#ifndef VC_COMMON_MACROS_H
21#define VC_COMMON_MACROS_H
22#undef VC_COMMON_UNDOMACROS_H
23
24#include <Vc/global.h>
25
79c86c14 26#if defined(VC_GCC) && !defined(__OPTIMIZE__)
27# if VC_GCC >= 0x40500
28# pragma GCC diagnostic push
29# define Vc_POP_GCC_DIAGNOSTIC__ 1
30# endif
c017a39f 31// GCC uses lots of old-style-casts in macros that disguise as intrinsics
79c86c14 32# pragma GCC diagnostic ignored "-Wold-style-cast"
c017a39f 33#endif
34
f22341db 35#ifdef VC_MSVC
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_
40#else
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)
45#endif
46
c017a39f 47#ifdef VC_CXX11
48#define Vc_ALIGNOF(_TYPE_) alignof(_TYPE_)
49#else
50#define Vc_ALIGNOF(_TYPE_) __alignof(_TYPE_)
51#endif
f22341db 52
53#ifdef VC_CLANG
c017a39f 54# define Vc_INTRINSIC_L inline
55# define Vc_INTRINSIC_R __attribute__((always_inline))
56# define Vc_INTRINSIC Vc_INTRINSIC_L Vc_INTRINSIC_R
57# define Vc_FLATTEN
58# define Vc_CONST __attribute__((const))
59# define Vc_CONST_L
60# define Vc_CONST_R Vc_CONST
61# define Vc_PURE __attribute__((pure))
62# define Vc_PURE_L
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
f22341db 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__
c017a39f 71# define VC_DEPRECATED(msg)
f22341db 72#elif defined(__GNUC__)
c017a39f 73# if (defined(VC_GCC) && VC_GCC < 0x40300) || defined(VC_OPEN64)
6936ae04 74// GCC 4.1 and 4.2 ICE on may_alias. Since Open64 uses the GCC 4.2 frontend it has the same problem.
c017a39f 75# define Vc_MAY_ALIAS
6936ae04 76# else
c017a39f 77# define Vc_MAY_ALIAS __attribute__((__may_alias__))
6936ae04 78# endif
c017a39f 79# if (defined(VC_GCC) && VC_GCC < 0x40300)
6936ae04 80// GCC 4.1 fails with "sorry unimplemented: inlining failed"
c017a39f 81# define Vc_INTRINSIC_R __attribute__((__flatten__))
82# elif defined(VC_OPEN64)
6936ae04 83// the GCC 4.2 frontend doesn't know the __artificial__ attribute
c017a39f 84# define Vc_INTRINSIC_R __attribute__((__flatten__, __always_inline__))
f22341db 85# else
c017a39f 86# define Vc_INTRINSIC_R __attribute__((__flatten__, __always_inline__, __artificial__))
f22341db 87# endif
c017a39f 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
94# ifdef VC_ICC
95 // ICC miscompiles if there are functions marked as pure or const
96# define Vc_PURE
97# define Vc_CONST
98# else
99# define Vc_PURE __attribute__((__pure__))
100# define Vc_CONST __attribute__((__const__))
101# endif
102# define Vc_CONST_L
103# define Vc_CONST_R Vc_CONST
104# define Vc_PURE_L
105# define Vc_PURE_R Vc_PURE
f22341db 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__
c017a39f 109# define VC_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
f22341db 110#else
c017a39f 111# define Vc_FLATTEN
112# ifdef Vc_PURE
113# undef Vc_PURE
f22341db 114# endif
c017a39f 115# define Vc_MAY_ALIAS
f22341db 116# ifdef VC_MSVC
c017a39f 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
122# define Vc_CONST_R
123# define Vc_PURE /*Vc_CONST*/
124# define Vc_PURE_L Vc_PURE
125# define Vc_PURE_R
126# define Vc_INTRINSIC inline __forceinline
127# define Vc_INTRINSIC_L Vc_INTRINSIC
128# define Vc_INTRINSIC_R
f22341db 129# else
c017a39f 130# define Vc_ALWAYS_INLINE
131# define Vc_ALWAYS_INLINE_L
132# define Vc_ALWAYS_INLINE_R
133# define Vc_CONST
134# define Vc_CONST_L
135# define Vc_CONST_R
136# define Vc_PURE
137# define Vc_PURE_L
138# define Vc_PURE_R
139# define Vc_INTRINSIC
140# define Vc_INTRINSIC_L
141# define Vc_INTRINSIC_R
f22341db 142# endif
143# define VC_IS_UNLIKELY(x) x
144# define VC_IS_LIKELY(x) x
145# define VC_RESTRICT __restrict
c017a39f 146# define VC_DEPRECATED(msg) __declspec(deprecated(msg))
f22341db 147#endif
148
149#if __cplusplus >= 201103 /*C++11*/
150#define _VC_CONSTEXPR constexpr
151#define _VC_CONSTEXPR_L _VC_CONSTEXPR
152#define _VC_CONSTEXPR_R
153#else
c017a39f 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
f22341db 157#endif
158
c017a39f 159#ifdef VC_CXX11
f22341db 160# define _VC_NOEXCEPT noexcept
161#else
162# define _VC_NOEXCEPT throw()
163#endif
164
79c86c14 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 *) {}
f22341db 174
175#ifdef VC_GCC
176# define VC_WARN_INLINE
177# define VC_WARN(msg) __attribute__((warning("\n\t" msg)))
178#else
179# define VC_WARN_INLINE inline
180# define VC_WARN(msg)
181#endif
182
183#define unrolled_loop16(_it_, _start_, _end_, _code_) \
184if (_start_ + 0 < _end_) { enum { _it_ = (_start_ + 0) < _end_ ? (_start_ + 0) : _start_ }; _code_ } \
185if (_start_ + 1 < _end_) { enum { _it_ = (_start_ + 1) < _end_ ? (_start_ + 1) : _start_ }; _code_ } \
186if (_start_ + 2 < _end_) { enum { _it_ = (_start_ + 2) < _end_ ? (_start_ + 2) : _start_ }; _code_ } \
187if (_start_ + 3 < _end_) { enum { _it_ = (_start_ + 3) < _end_ ? (_start_ + 3) : _start_ }; _code_ } \
188if (_start_ + 4 < _end_) { enum { _it_ = (_start_ + 4) < _end_ ? (_start_ + 4) : _start_ }; _code_ } \
189if (_start_ + 5 < _end_) { enum { _it_ = (_start_ + 5) < _end_ ? (_start_ + 5) : _start_ }; _code_ } \
190if (_start_ + 6 < _end_) { enum { _it_ = (_start_ + 6) < _end_ ? (_start_ + 6) : _start_ }; _code_ } \
191if (_start_ + 7 < _end_) { enum { _it_ = (_start_ + 7) < _end_ ? (_start_ + 7) : _start_ }; _code_ } \
192if (_start_ + 8 < _end_) { enum { _it_ = (_start_ + 8) < _end_ ? (_start_ + 8) : _start_ }; _code_ } \
193if (_start_ + 9 < _end_) { enum { _it_ = (_start_ + 9) < _end_ ? (_start_ + 9) : _start_ }; _code_ } \
194if (_start_ + 10 < _end_) { enum { _it_ = (_start_ + 10) < _end_ ? (_start_ + 10) : _start_ }; _code_ } \
195if (_start_ + 11 < _end_) { enum { _it_ = (_start_ + 11) < _end_ ? (_start_ + 11) : _start_ }; _code_ } \
196if (_start_ + 12 < _end_) { enum { _it_ = (_start_ + 12) < _end_ ? (_start_ + 12) : _start_ }; _code_ } \
197if (_start_ + 13 < _end_) { enum { _it_ = (_start_ + 13) < _end_ ? (_start_ + 13) : _start_ }; _code_ } \
198if (_start_ + 14 < _end_) { enum { _it_ = (_start_ + 14) < _end_ ? (_start_ + 14) : _start_ }; _code_ } \
199if (_start_ + 15 < _end_) { enum { _it_ = (_start_ + 15) < _end_ ? (_start_ + 15) : _start_ }; _code_ } \
200do {} while ( false )
201
202#define for_all_vector_entries(_it_, _code_) \
203 unrolled_loop16(_it_, 0, Size, _code_)
204
c017a39f 205#ifdef VC_ASSERT
206#define VC_EXTERNAL_ASSERT 1
207#else
f22341db 208#ifdef NDEBUG
209#define VC_ASSERT(x)
210#else
211#include <assert.h>
212#define VC_ASSERT(x) assert(x);
213#endif
c017a39f 214#endif
f22341db 215
216#ifdef VC_CLANG
217#define VC_HAS_BUILTIN(x) __has_builtin(x)
218#else
219#define VC_HAS_BUILTIN(x) 0
220#endif
221
222#ifndef VC_COMMON_MACROS_H_ONCE
223#define VC_COMMON_MACROS_H_ONCE
224
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)
227
c017a39f 228#if __cplusplus >= 201103 /*C++11*/ || (defined(VC_MSVC) && VC_MSVC >= 160000000)
f22341db 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)
232#else // C++98
c017a39f 233namespace AliRoot {
f22341db 234namespace Vc {
235 namespace {
236 template<bool> struct STATIC_ASSERT_FAILURE;
237 template<> struct STATIC_ASSERT_FAILURE<true> {};
238}}
c017a39f 239} // namespace AliRoot
f22341db 240
241#define VC_STATIC_ASSERT_NC(cond, msg) \
242 typedef STATIC_ASSERT_FAILURE<cond> _VC_CAT(static_assert_failed_on_line_,__LINE__,_,msg); \
243 enum { \
244 _VC_CAT(static_assert_failed__on_line_,__LINE__,_,msg) = sizeof(_VC_CAT(static_assert_failed_on_line_,__LINE__,_,msg)) \
245 }
246#define VC_STATIC_ASSERT(cond, msg) VC_STATIC_ASSERT_NC(cond, msg)
247#endif // C++11/98
248
79c86c14 249 template<int e, int center> struct exponentToMultiplier { enum Values__ {
f22341db 250 X = exponentToMultiplier<e - 1, center>::X * ((e - center < 31) ? 2 : 1),
251 Value = (X == 0 ? 1 : X)
252 }; };
79c86c14 253 template<int center> struct exponentToMultiplier<center,center> { enum Values__ { X = 1, Value = X }; };
254 template<int center> struct exponentToMultiplier< -1, center> { enum Values__ { X = 0, Value = 1 }; };
255 template<int center> struct exponentToMultiplier< -128, center> { enum Values__ { X = 0, Value = 1 }; };
256 template<int center> struct exponentToMultiplier< -256, center> { enum Values__ { X = 0, Value = 1 }; };
257 template<int center> struct exponentToMultiplier< -384, center> { enum Values__ { X = 0, Value = 1 }; };
258 template<int center> struct exponentToMultiplier< -512, center> { enum Values__ { X = 0, Value = 1 }; };
259 template<int center> struct exponentToMultiplier< -640, center> { enum Values__ { X = 0, Value = 1 }; };
260 template<int center> struct exponentToMultiplier< -768, center> { enum Values__ { X = 0, Value = 1 }; };
261 template<int center> struct exponentToMultiplier< -896, center> { enum Values__ { X = 0, Value = 1 }; };
262 template<int center> struct exponentToMultiplier<-1024, center> { enum Values__ { X = 0, Value = 1 }; };
c017a39f 263
79c86c14 264 template<int e, int center> struct exponentToDivisor { enum Values__ {
c017a39f 265 X = exponentToDivisor<e + 1, center>::X * ((center - e < 31) ? 2 : 1),
266 Value = (X == 0 ? 1 : X)
f22341db 267 }; };
79c86c14 268 template<int center> struct exponentToDivisor<center, center> { enum Values__ { X = 1, Value = X }; };
269 template<int center> struct exponentToDivisor< 1, center> { enum Values__ { X = 0, Value = 1 }; };
270 template<int center> struct exponentToDivisor< 128, center> { enum Values__ { X = 0, Value = 1 }; };
271 template<int center> struct exponentToDivisor< 256, center> { enum Values__ { X = 0, Value = 1 }; };
272 template<int center> struct exponentToDivisor< 384, center> { enum Values__ { X = 0, Value = 1 }; };
273 template<int center> struct exponentToDivisor< 512, center> { enum Values__ { X = 0, Value = 1 }; };
274 template<int center> struct exponentToDivisor< 640, center> { enum Values__ { X = 0, Value = 1 }; };
275 template<int center> struct exponentToDivisor< 768, center> { enum Values__ { X = 0, Value = 1 }; };
276 template<int center> struct exponentToDivisor< 896, center> { enum Values__ { X = 0, Value = 1 }; };
277 template<int center> struct exponentToDivisor< 1024, center> { enum Values__ { X = 0, Value = 1 }; };
f22341db 278#endif // VC_COMMON_MACROS_H_ONCE
279
280#define _CAT_IMPL(a, b) a##b
281#define CAT(a, b) _CAT_IMPL(a, b)
282
283#define Vc_buildDouble(sign, mantissa, exponent) \
284 ((static_cast<double>((mantissa & 0x000fffffffffffffull) | 0x0010000000000000ull) / 0x0010000000000000ull) \
c017a39f 285 * exponentToMultiplier<exponent, 0>::Value \
f22341db 286 * exponentToMultiplier<exponent, 30>::Value \
287 * exponentToMultiplier<exponent, 60>::Value \
288 * exponentToMultiplier<exponent, 90>::Value \
c017a39f 289 / exponentToDivisor<exponent, 0>::Value \
290 / exponentToDivisor<exponent, -30>::Value \
291 / exponentToDivisor<exponent, -60>::Value \
292 / exponentToDivisor<exponent, -90>::Value \
f22341db 293 * static_cast<double>(sign))
294#define Vc_buildFloat(sign, mantissa, exponent) \
295 ((static_cast<float>((mantissa & 0x007fffffu) | 0x00800000) / 0x00800000) \
c017a39f 296 * exponentToMultiplier<exponent, 0>::Value \
f22341db 297 * exponentToMultiplier<exponent, 30>::Value \
298 * exponentToMultiplier<exponent, 60>::Value \
299 * exponentToMultiplier<exponent, 90>::Value \
c017a39f 300 / exponentToDivisor<exponent, 0>::Value \
301 / exponentToDivisor<exponent, -30>::Value \
302 / exponentToDivisor<exponent, -60>::Value \
303 / exponentToDivisor<exponent, -90>::Value \
f22341db 304 * static_cast<float>(sign))
305
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)
311
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)
347
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)
353
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)
361
362#define VC_EXACT_TYPE(_test, _reference, _type) \
363 typename EnableIf<IsEqualType<_test, _reference>::Value, _type>::Value
364
c017a39f 365#ifdef VC_PASSING_VECTOR_BY_VALUE_IS_BROKEN
366#define VC_ALIGNED_PARAMETER(_Type) const _Type &
367#else
368#define VC_ALIGNED_PARAMETER(_Type) const _Type
369#endif
370
371#ifndef Vc__make_unique
372#define Vc__make_unique(name) _VC_CAT(Vc__,name,_,__LINE__)
373#endif
374
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))
379#else
380#define VC_OFFSETOF(Type, member) offsetof(Type, member)
381#endif
382
383
f22341db 384#endif // VC_COMMON_MACROS_H