Vc  1.0.0-dev
SIMD Vector Classes for C++
macros.h
1 /* This file is part of the Vc library. {{{
2 Copyright © 2010-2015 Matthias Kretz <kretz@kde.org>
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the names of contributing organizations nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 }}}*/
28 
29 #ifndef VC_COMMON_MACROS_H_
30 #define VC_COMMON_MACROS_H_
31 
32 #include <Vc/global.h>
33 
34 
35 #ifdef Vc_MSVC
36 #define Vc_ALIGNED_TYPEDEF(n__, type__, new_type__) \
37  typedef __declspec(align(n__)) type__ new_type__
38 #elif __GNUC__
39 #define Vc_ALIGNED_TYPEDEF(n__, type__, new_type__) \
40  typedef type__ new_type__[[gnu::aligned(n__)]]
41 #else // the following is actually ill-formed according to C++1[14]
42 #define Vc_ALIGNED_TYPEDEF(n__, type__, new_type__) \
43  using new_type__ alignas(sizeof(n__)) = type__
44 #endif
45 
46 #ifdef Vc_CLANG
47 # define Vc_INTRINSIC_L inline
48 # define Vc_INTRINSIC_R __attribute__((always_inline))
49 # define Vc_INTRINSIC Vc_INTRINSIC_L Vc_INTRINSIC_R
50 # define Vc_FLATTEN
51 # define Vc_CONST __attribute__((const))
52 # define Vc_CONST_L
53 # define Vc_CONST_R Vc_CONST
54 # define Vc_PURE __attribute__((pure))
55 # define Vc_PURE_L
56 # define Vc_PURE_R Vc_PURE
57 # define Vc_MAY_ALIAS __attribute__((may_alias))
58 # define Vc_ALWAYS_INLINE_L inline
59 # define Vc_ALWAYS_INLINE_R __attribute__((always_inline))
60 # define Vc_ALWAYS_INLINE Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE_R
61 # define Vc_IS_UNLIKELY(x) __builtin_expect(x, 0)
62 # define Vc_IS_LIKELY(x) __builtin_expect(x, 1)
63 # define Vc_RESTRICT __restrict__
64 # define Vc_DEPRECATED(msg)
65 # define Vc_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
66 #elif defined(__GNUC__)
67 # if defined Vc_GCC && !defined __OPTIMIZE__
68 # define Vc_MAY_ALIAS
69 # else
70 # define Vc_MAY_ALIAS __attribute__((__may_alias__))
71 # endif
72 # define Vc_INTRINSIC_R __attribute__((__always_inline__, __artificial__))
73 # define Vc_INTRINSIC_L inline
74 # define Vc_INTRINSIC Vc_INTRINSIC_L Vc_INTRINSIC_R
75 # define Vc_FLATTEN __attribute__((__flatten__))
76 # define Vc_ALWAYS_INLINE_L inline
77 # define Vc_ALWAYS_INLINE_R __attribute__((__always_inline__))
78 # define Vc_ALWAYS_INLINE Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE_R
79 # ifdef Vc_ICC
80  // ICC miscompiles if there are functions marked as pure or const
81 # define Vc_PURE
82 # define Vc_CONST
83 # else
84 # define Vc_PURE __attribute__((__pure__))
85 # define Vc_CONST __attribute__((__const__))
86 # endif
87 # define Vc_CONST_L
88 # define Vc_CONST_R Vc_CONST
89 # define Vc_PURE_L
90 # define Vc_PURE_R Vc_PURE
91 # define Vc_IS_UNLIKELY(x) __builtin_expect(x, 0)
92 # define Vc_IS_LIKELY(x) __builtin_expect(x, 1)
93 # define Vc_RESTRICT __restrict__
94 # ifdef Vc_ICC
95 # define Vc_DEPRECATED(msg)
96 # else
97 # define Vc_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
98 # endif
99 # define Vc_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
100 #else
101 # define Vc_FLATTEN
102 # ifdef Vc_PURE
103 # undef Vc_PURE
104 # endif
105 # define Vc_MAY_ALIAS
106 # ifdef Vc_MSVC
107 # define Vc_ALWAYS_INLINE inline __forceinline
108 # define Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE
109 # define Vc_ALWAYS_INLINE_R
110 # define Vc_CONST __declspec(noalias)
111 # define Vc_CONST_L Vc_CONST
112 # define Vc_CONST_R
113 # define Vc_PURE /*Vc_CONST*/
114 # define Vc_PURE_L Vc_PURE
115 # define Vc_PURE_R
116 # define Vc_INTRINSIC inline __forceinline
117 # define Vc_INTRINSIC_L Vc_INTRINSIC
118 # define Vc_INTRINSIC_R
119 # else
120 # define Vc_ALWAYS_INLINE
121 # define Vc_ALWAYS_INLINE_L
122 # define Vc_ALWAYS_INLINE_R
123 # define Vc_CONST
124 # define Vc_CONST_L
125 # define Vc_CONST_R
126 # define Vc_PURE
127 # define Vc_PURE_L
128 # define Vc_PURE_R
129 # define Vc_INTRINSIC
130 # define Vc_INTRINSIC_L
131 # define Vc_INTRINSIC_R
132 # endif
133 # define Vc_IS_UNLIKELY(x) x
134 # define Vc_IS_LIKELY(x) x
135 # define Vc_RESTRICT __restrict
136 # define Vc_DEPRECATED(msg) __declspec(deprecated(msg))
137 # define Vc_WARN_UNUSED_RESULT
138 #endif
139 
140 #define Vc_FREE_STORE_OPERATORS_ALIGNED(alignment) \
141  Vc_ALWAYS_INLINE void *operator new(size_t size) { return Vc::Common::aligned_malloc<alignment>(size); } \
142  Vc_ALWAYS_INLINE void *operator new(size_t, void *p) { return p; } \
143  Vc_ALWAYS_INLINE void *operator new[](size_t size) { return Vc::Common::aligned_malloc<alignment>(size); } \
144  Vc_ALWAYS_INLINE void *operator new[](size_t , void *p) { return p; } \
145  Vc_ALWAYS_INLINE void operator delete(void *ptr, size_t) { Vc::Common::free(ptr); } \
146  Vc_ALWAYS_INLINE void operator delete(void *, void *) {} \
147  Vc_ALWAYS_INLINE void operator delete[](void *ptr, size_t) { Vc::Common::free(ptr); } \
148  Vc_ALWAYS_INLINE void operator delete[](void *, void *) {}
149 
150 #ifdef Vc_ASSERT
151 #define Vc_EXTERNAL_ASSERT 1
152 #else
153 #ifdef NDEBUG
154 #define Vc_ASSERT(x)
155 #else
156 #include <assert.h>
157 #define Vc_ASSERT(x) assert(x);
158 #endif
159 #endif
160 
161 #ifdef Vc_CLANG
162 #define Vc_HAS_BUILTIN(x) __has_builtin(x)
163 #else
164 #define Vc_HAS_BUILTIN(x) 0
165 #endif
166 
167 #define Vc_CAT_HELPER_(a, b, c, d) a##b##c##d
168 #define Vc_CAT(a, b, c, d) Vc_CAT_HELPER_(a, b, c, d)
169 
170 #define Vc_CAT_IMPL(a, b) a##b
171 #define Vc_CAT2(a, b) Vc_CAT_IMPL(a, b)
172 
173 #define Vc_APPLY_IMPL_1_(macro, a, b, c, d, e) macro(a)
174 #define Vc_APPLY_IMPL_2_(macro, a, b, c, d, e) macro(a, b)
175 #define Vc_APPLY_IMPL_3_(macro, a, b, c, d, e) macro(a, b, c)
176 #define Vc_APPLY_IMPL_4_(macro, a, b, c, d, e) macro(a, b, c, d)
177 #define Vc_APPLY_IMPL_5_(macro, a, b, c, d, e) macro(a, b, c, d, e)
178 
179 #define Vc_LIST_FLOAT_VECTOR_TYPES(size, macro, a, b, c, d) \
180  size(macro, double_v, a, b, c, d) \
181  size(macro, float_v, a, b, c, d)
182 #define Vc_LIST_INT_VECTOR_TYPES(size, macro, a, b, c, d) \
183  size(macro, int_v, a, b, c, d) \
184  size(macro, uint_v, a, b, c, d) \
185  size(macro, short_v, a, b, c, d) \
186  size(macro, ushort_v, a, b, c, d)
187 #define Vc_LIST_VECTOR_TYPES(size, macro, a, b, c, d) \
188  Vc_LIST_FLOAT_VECTOR_TYPES(size, macro, a, b, c, d) \
189  Vc_LIST_INT_VECTOR_TYPES(size, macro, a, b, c, d)
190 #define Vc_LIST_COMPARES(size, macro, a, b, c, d) \
191  size(macro, ==, a, b, c, d) \
192  size(macro, !=, a, b, c, d) \
193  size(macro, <=, a, b, c, d) \
194  size(macro, >=, a, b, c, d) \
195  size(macro, < , a, b, c, d) \
196  size(macro, > , a, b, c, d)
197 #define Vc_LIST_LOGICAL(size, macro, a, b, c, d) \
198  size(macro, &&, a, b, c, d) \
199  size(macro, ||, a, b, c, d)
200 #define Vc_LIST_BINARY(size, macro, a, b, c, d) \
201  size(macro, |, a, b, c, d) \
202  size(macro, &, a, b, c, d) \
203  size(macro, ^, a, b, c, d)
204 #define Vc_LIST_SHIFTS(size, macro, a, b, c, d) \
205  size(macro, <<, a, b, c, d) \
206  size(macro, >>, a, b, c, d)
207 #define Vc_LIST_ARITHMETICS(size, macro, a, b, c, d) \
208  size(macro, +, a, b, c, d) \
209  size(macro, -, a, b, c, d) \
210  size(macro, *, a, b, c, d) \
211  size(macro, /, a, b, c, d) \
212  size(macro, %, a, b, c, d)
213 
214 #define Vc_APPLY_0(_list, macro) _list(Vc_APPLY_IMPL_1_, macro, 0, 0, 0, 0)
215 #define Vc_APPLY_1(_list, macro, a) _list(Vc_APPLY_IMPL_2_, macro, a, 0, 0, 0)
216 #define Vc_APPLY_2(_list, macro, a, b) _list(Vc_APPLY_IMPL_3_, macro, a, b, 0, 0)
217 #define Vc_APPLY_3(_list, macro, a, b, c) _list(Vc_APPLY_IMPL_4_, macro, a, b, c, 0)
218 #define Vc_APPLY_4(_list, macro, a, b, c, d) _list(Vc_APPLY_IMPL_5_, macro, a, b, c, d)
219 
220 #define Vc_ALL_COMPARES(macro) Vc_APPLY_0(Vc_LIST_COMPARES, macro)
221 #define Vc_ALL_LOGICAL(macro) Vc_APPLY_0(Vc_LIST_LOGICAL, macro)
222 #define Vc_ALL_BINARY(macro) Vc_APPLY_0(Vc_LIST_BINARY, macro)
223 #define Vc_ALL_SHIFTS(macro) Vc_APPLY_0(Vc_LIST_SHIFTS, macro)
224 #define Vc_ALL_ARITHMETICS(macro) Vc_APPLY_0(Vc_LIST_ARITHMETICS, macro)
225 #define Vc_ALL_FLOAT_VECTOR_TYPES(macro) Vc_APPLY_0(Vc_LIST_FLOAT_VECTOR_TYPES, macro)
226 #define Vc_ALL_VECTOR_TYPES(macro) Vc_APPLY_0(Vc_LIST_VECTOR_TYPES, macro)
227 
228 #define Vc_EXACT_TYPE(_test, _reference, _type) \
229  typename std::enable_if<std::is_same<_test, _reference>::value, _type>::type
230 
231 #ifdef Vc_PASSING_VECTOR_BY_VALUE_IS_BROKEN
232 #define Vc_ALIGNED_PARAMETER(_Type) const _Type &
233 #else
234 #define Vc_ALIGNED_PARAMETER(_Type) const _Type
235 #endif
236 
237 #define Vc__make_unique(name) Vc_CAT(Vc__,name,_,__LINE__)
238 
239 #if defined(Vc_ICC) || defined(Vc_CLANG)
240 #define Vc_OFFSETOF(Type, member) (reinterpret_cast<const char *>(&reinterpret_cast<const Type *>(0)->member) - reinterpret_cast<const char *>(0))
241 #elif defined(Vc_GCC) && Vc_GCC < 0x40500
242 #define Vc_OFFSETOF(Type, member) (reinterpret_cast<const char *>(&reinterpret_cast<const Type *>(0x1000)->member) - reinterpret_cast<const char *>(0x1000))
243 #else
244 #define Vc_OFFSETOF(Type, member) offsetof(Type, member)
245 #endif
246 
247 #if defined(Vc__NO_NOEXCEPT)
248 #define Vc_NOEXCEPT throw()
249 #else
250 #define Vc_NOEXCEPT noexcept
251 #endif
252 
253 #ifdef Vc_NO_ALWAYS_INLINE
254 #undef Vc_ALWAYS_INLINE
255 #undef Vc_ALWAYS_INLINE_L
256 #undef Vc_ALWAYS_INLINE_R
257 #define Vc_ALWAYS_INLINE inline
258 #define Vc_ALWAYS_INLINE_L inline
259 #define Vc_ALWAYS_INLINE_R
260 #undef Vc_INTRINSIC
261 #undef Vc_INTRINSIC_L
262 #undef Vc_INTRINSIC_R
263 #define Vc_INTRINSIC inline
264 #define Vc_INTRINSIC_L inline
265 #define Vc_INTRINSIC_R
266 #endif
267 
268 #endif // VC_COMMON_MACROS_H_