Vc  1.3.2-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 
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_MACROS_H_
29 #define VC_COMMON_MACROS_H_
30 
31 #include <Vc/global.h>
32 
33 
34 #ifdef Vc_MSVC
35 #define Vc_ALIGNED_TYPEDEF(n_, type_, new_type_) \
36  typedef __declspec(align(n_)) type_ new_type_
37 #elif __GNUC__
38 #define Vc_ALIGNED_TYPEDEF(n_, type_, new_type_) \
39  typedef type_ new_type_[[gnu::aligned(n_)]]
40 #else // the following is actually ill-formed according to C++1[14]
41 #define Vc_ALIGNED_TYPEDEF(n_, type_, new_type_) \
42  using new_type_ alignas(sizeof(n_)) = type_
43 #endif
44 
45 // On Windows (WIN32) we might see macros called min and max. Just undefine them and hope
46 // noone (re)defines them (NOMINMAX should help).
47 #ifdef WIN32
48 #define NOMINMAX 1
49 #if defined min
50 #undef min
51 #endif
52 #if defined max
53 #undef max
54 #endif
55 #endif // WIN32
56 
57 #if defined Vc_GCC && Vc_GCC >= 0x60000
58 // GCC 6 drops all attributes on types passed as template arguments. This is important
59 // if a may_alias gets lost and therefore needs to be readded in the implementation of
60 // the class template.
61 #define Vc_TEMPLATES_DROP_ATTRIBUTES 1
62 #endif
63 
64 #if Vc_IS_VERSION_2 || (defined Vc_GCC && Vc_GCC >= 0x60000)
65 // GCC 6 optimizes the RowMemory::fromRawData hack away (common/memorybase.h). Therefore
66 // the 2D Memory class is implemented recursively using 1D Memory members. Since this is
67 // an ABI break this is only enabled for GCC 6. With Vc 2.x all implementations should do
68 // this.
69 #define Vc_RECURSIVE_MEMORY 1
70 #endif
71 
72 #if defined Vc_CLANG || defined Vc_APPLECLANG
73 # define Vc_UNREACHABLE __builtin_unreachable
74 # define Vc_NEVER_INLINE [[gnu::noinline]]
75 # define Vc_INTRINSIC_L inline
76 # define Vc_INTRINSIC_R __attribute__((always_inline))
77 # define Vc_INTRINSIC Vc_INTRINSIC_L Vc_INTRINSIC_R
78 # define Vc_FLATTEN
79 # define Vc_CONST __attribute__((const))
80 # define Vc_CONST_L
81 # define Vc_CONST_R Vc_CONST
82 # define Vc_PURE __attribute__((pure))
83 # define Vc_PURE_L
84 # define Vc_PURE_R Vc_PURE
85 # define Vc_MAY_ALIAS __attribute__((may_alias))
86 # define Vc_ALWAYS_INLINE_L inline
87 # define Vc_ALWAYS_INLINE_R __attribute__((always_inline))
88 # define Vc_ALWAYS_INLINE Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE_R
89 # define Vc_IS_UNLIKELY(x) __builtin_expect(x, 0)
90 # define Vc_IS_LIKELY(x) __builtin_expect(x, 1)
91 # define Vc_RESTRICT __restrict__
92 # define Vc_DEPRECATED(msg)
93 # define Vc_DEPRECATED_ALIAS(msg)
94 # define Vc_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
95 #elif defined(__GNUC__)
96 # define Vc_UNREACHABLE __builtin_unreachable
97 # if defined Vc_GCC && !defined __OPTIMIZE__
98 # define Vc_MAY_ALIAS
99 # else
100 # define Vc_MAY_ALIAS __attribute__((__may_alias__))
101 # endif
102 # define Vc_INTRINSIC_R __attribute__((__always_inline__, __artificial__))
103 # define Vc_INTRINSIC_L inline
104 # define Vc_INTRINSIC Vc_INTRINSIC_L Vc_INTRINSIC_R
105 # define Vc_FLATTEN __attribute__((__flatten__))
106 # define Vc_ALWAYS_INLINE_L inline
107 # define Vc_ALWAYS_INLINE_R __attribute__((__always_inline__))
108 # define Vc_ALWAYS_INLINE Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE_R
109 # ifdef Vc_ICC
110 // ICC miscompiles if there are functions marked as pure or const
111 # define Vc_PURE
112 # define Vc_CONST
113 # define Vc_NEVER_INLINE
114 # else
115 # define Vc_NEVER_INLINE [[gnu::noinline]]
116 # define Vc_PURE __attribute__((__pure__))
117 # define Vc_CONST __attribute__((__const__))
118 # endif
119 # define Vc_CONST_L
120 # define Vc_CONST_R Vc_CONST
121 # define Vc_PURE_L
122 # define Vc_PURE_R Vc_PURE
123 # define Vc_IS_UNLIKELY(x) __builtin_expect(x, 0)
124 # define Vc_IS_LIKELY(x) __builtin_expect(x, 1)
125 # define Vc_RESTRICT __restrict__
126 # ifdef Vc_ICC
127 # define Vc_DEPRECATED(msg)
128 # define Vc_DEPRECATED_ALIAS(msg)
129 # else
130 # define Vc_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
131 # define Vc_DEPRECATED_ALIAS(msg) __attribute__((__deprecated__(msg)))
132 # endif
133 # define Vc_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
134 #else
135 # define Vc_NEVER_INLINE
136 # define Vc_FLATTEN
137 # ifdef Vc_PURE
138 # undef Vc_PURE
139 # endif
140 # define Vc_MAY_ALIAS
141 # ifdef Vc_MSVC
142 # define Vc_ALWAYS_INLINE inline __forceinline
143 # define Vc_ALWAYS_INLINE_L Vc_ALWAYS_INLINE
144 # define Vc_ALWAYS_INLINE_R
145 # define Vc_CONST __declspec(noalias)
146 # define Vc_CONST_L Vc_CONST
147 # define Vc_CONST_R
148 # define Vc_PURE /*Vc_CONST*/
149 # define Vc_PURE_L Vc_PURE
150 # define Vc_PURE_R
151 # define Vc_INTRINSIC inline __forceinline
152 # define Vc_INTRINSIC_L Vc_INTRINSIC
153 # define Vc_INTRINSIC_R
154 namespace Vc_VERSIONED_NAMESPACE {
155 namespace detail
156 {
157 static Vc_INTRINSIC void unreachable() { __assume(0); }
158 } // namespace detail
159 }
160 # define Vc_UNREACHABLE Vc::detail::unreachable
161 # else
162 # define Vc_ALWAYS_INLINE
163 # define Vc_ALWAYS_INLINE_L
164 # define Vc_ALWAYS_INLINE_R
165 # define Vc_CONST
166 # define Vc_CONST_L
167 # define Vc_CONST_R
168 # define Vc_PURE
169 # define Vc_PURE_L
170 # define Vc_PURE_R
171 # define Vc_INTRINSIC
172 # define Vc_INTRINSIC_L
173 # define Vc_INTRINSIC_R
174 # define Vc_UNREACHABLE std::abort
175 # endif
176 # define Vc_IS_UNLIKELY(x) x
177 # define Vc_IS_LIKELY(x) x
178 # define Vc_RESTRICT __restrict
179 # define Vc_DEPRECATED(msg) __declspec(deprecated(msg))
180 # define Vc_DEPRECATED_ALIAS(msg)
181 # define Vc_WARN_UNUSED_RESULT
182 #endif
183 
184 #ifdef Vc_CXX14
185 #undef Vc_DEPRECATED
186 #define Vc_DEPRECATED(msg_) [[deprecated(msg_)]]
187 #endif
188 
189 #define Vc_NOTHING_EXPECTING_SEMICOLON static_assert(true, "")
190 
191 #define Vc_FREE_STORE_OPERATORS_ALIGNED(align_) \
192  \
193  \
194  \
195  Vc_ALWAYS_INLINE void *operator new(size_t size) \
196  { \
197  return Vc::Common::aligned_malloc<align_>(size); \
198  } \
199  \
200  Vc_ALWAYS_INLINE void *operator new(size_t, void *p) { return p; } \
201  \
202  Vc_ALWAYS_INLINE void *operator new[](size_t size) \
203  { \
204  return Vc::Common::aligned_malloc<align_>(size); \
205  } \
206  \
207  Vc_ALWAYS_INLINE void *operator new[](size_t, void *p) { return p; } \
208  \
209  Vc_ALWAYS_INLINE void operator delete(void *ptr, size_t) { Vc::Common::free(ptr); } \
210  \
211  Vc_ALWAYS_INLINE void operator delete(void *, void *) {} \
212  \
213  Vc_ALWAYS_INLINE void operator delete[](void *ptr, size_t) \
214  { \
215  Vc::Common::free(ptr); \
216  } \
217  \
218  Vc_ALWAYS_INLINE void operator delete[](void *, void *) {} \
219  \
220  Vc_NOTHING_EXPECTING_SEMICOLON
221 
222 #ifdef Vc_ASSERT
223 #define Vc_EXTERNAL_ASSERT 1
224 #else
225 #ifdef NDEBUG
226 #define Vc_ASSERT(x)
227 #else
228 #include <assert.h>
229 #define Vc_ASSERT(x) assert(x);
230 #endif
231 #endif
232 
233 #if defined Vc_CLANG || defined Vc_APPLECLANG
234 #define Vc_HAS_BUILTIN(x) __has_builtin(x)
235 #else
236 #define Vc_HAS_BUILTIN(x) 0
237 #endif
238 
239 #define Vc_CAT_HELPER_(a, b, c, d) a##b##c##d
240 #define Vc_CAT(a, b, c, d) Vc_CAT_HELPER_(a, b, c, d)
241 
242 #define Vc_CAT_IMPL(a, b) a##b
243 #define Vc_CAT2(a, b) Vc_CAT_IMPL(a, b)
244 
245 #define Vc_APPLY_IMPL_1_(macro, a, b, c, d, e) macro(a)
246 #define Vc_APPLY_IMPL_2_(macro, a, b, c, d, e) macro(a, b)
247 #define Vc_APPLY_IMPL_3_(macro, a, b, c, d, e) macro(a, b, c)
248 #define Vc_APPLY_IMPL_4_(macro, a, b, c, d, e) macro(a, b, c, d)
249 #define Vc_APPLY_IMPL_5_(macro, a, b, c, d, e) macro(a, b, c, d, e)
250 
251 #define Vc_LIST_FLOAT_VECTOR_TYPES(size, macro, a, b, c, d) \
252  size(macro, double_v, a, b, c, d) \
253  size(macro, float_v, a, b, c, d)
254 #define Vc_LIST_INT_VECTOR_TYPES(size, macro, a, b, c, d) \
255  size(macro, int_v, a, b, c, d) \
256  size(macro, uint_v, a, b, c, d) \
257  size(macro, short_v, a, b, c, d) \
258  size(macro, ushort_v, a, b, c, d)
259 #define Vc_LIST_VECTOR_TYPES(size, macro, a, b, c, d) \
260  Vc_LIST_FLOAT_VECTOR_TYPES(size, macro, a, b, c, d) \
261  Vc_LIST_INT_VECTOR_TYPES(size, macro, a, b, c, d)
262 #define Vc_LIST_COMPARES(size, macro, a, b, c, d) \
263  size(macro, ==, a, b, c, d) \
264  size(macro, !=, a, b, c, d) \
265  size(macro, <=, a, b, c, d) \
266  size(macro, >=, a, b, c, d) \
267  size(macro, < , a, b, c, d) \
268  size(macro, > , a, b, c, d)
269 #define Vc_LIST_LOGICAL(size, macro, a, b, c, d) \
270  size(macro, &&, a, b, c, d) \
271  size(macro, ||, a, b, c, d)
272 #define Vc_LIST_BINARY(size, macro, a, b, c, d) \
273  size(macro, |, a, b, c, d) \
274  size(macro, &, a, b, c, d) \
275  size(macro, ^, a, b, c, d)
276 #define Vc_LIST_SHIFTS(size, macro, a, b, c, d) \
277  size(macro, <<, a, b, c, d) \
278  size(macro, >>, a, b, c, d)
279 #define Vc_LIST_ARITHMETICS(size, macro, a, b, c, d) \
280  size(macro, +, a, b, c, d) \
281  size(macro, -, a, b, c, d) \
282  size(macro, *, a, b, c, d) \
283  size(macro, /, a, b, c, d) \
284  size(macro, %, a, b, c, d)
285 
286 #define Vc_APPLY_0(_list, macro) _list(Vc_APPLY_IMPL_1_, macro, 0, 0, 0, 0) Vc_NOTHING_EXPECTING_SEMICOLON
287 #define Vc_APPLY_1(_list, macro, a) _list(Vc_APPLY_IMPL_2_, macro, a, 0, 0, 0) Vc_NOTHING_EXPECTING_SEMICOLON
288 #define Vc_APPLY_2(_list, macro, a, b) _list(Vc_APPLY_IMPL_3_, macro, a, b, 0, 0) Vc_NOTHING_EXPECTING_SEMICOLON
289 #define Vc_APPLY_3(_list, macro, a, b, c) _list(Vc_APPLY_IMPL_4_, macro, a, b, c, 0) Vc_NOTHING_EXPECTING_SEMICOLON
290 #define Vc_APPLY_4(_list, macro, a, b, c, d) _list(Vc_APPLY_IMPL_5_, macro, a, b, c, d) Vc_NOTHING_EXPECTING_SEMICOLON
291 
292 #define Vc_ALL_COMPARES(macro) Vc_APPLY_0(Vc_LIST_COMPARES, macro)
293 #define Vc_ALL_LOGICAL(macro) Vc_APPLY_0(Vc_LIST_LOGICAL, macro)
294 #define Vc_ALL_BINARY(macro) Vc_APPLY_0(Vc_LIST_BINARY, macro)
295 #define Vc_ALL_SHIFTS(macro) Vc_APPLY_0(Vc_LIST_SHIFTS, macro)
296 #define Vc_ALL_ARITHMETICS(macro) Vc_APPLY_0(Vc_LIST_ARITHMETICS, macro)
297 #define Vc_ALL_FLOAT_VECTOR_TYPES(macro) Vc_APPLY_0(Vc_LIST_FLOAT_VECTOR_TYPES, macro)
298 #define Vc_ALL_VECTOR_TYPES(macro) Vc_APPLY_0(Vc_LIST_VECTOR_TYPES, macro)
299 
300 #define Vc_EXACT_TYPE(_test, _reference, _type) \
301  typename std::enable_if<std::is_same<_test, _reference>::value, _type>::type
302 
303 #define Vc_make_unique(name) Vc_CAT(Vc_,name,_,__LINE__)
304 
305 #if defined(Vc_ICC) || defined(Vc_CLANG) || defined Vc_APPLECLANG
306 #define Vc_OFFSETOF(Type, member) (reinterpret_cast<const char *>(&reinterpret_cast<const Type *>(0)->member) - reinterpret_cast<const char *>(0))
307 #else
308 #define Vc_OFFSETOF(Type, member) offsetof(Type, member)
309 #endif
310 
311 #if defined(Vc_NO_NOEXCEPT)
312 #define Vc_NOEXCEPT throw()
313 #else
314 #define Vc_NOEXCEPT noexcept
315 #endif
316 
317 #ifdef Vc_NO_ALWAYS_INLINE
318 #undef Vc_ALWAYS_INLINE
319 #undef Vc_ALWAYS_INLINE_L
320 #undef Vc_ALWAYS_INLINE_R
321 #define Vc_ALWAYS_INLINE inline
322 #define Vc_ALWAYS_INLINE_L inline
323 #define Vc_ALWAYS_INLINE_R
324 #undef Vc_INTRINSIC
325 #undef Vc_INTRINSIC_L
326 #undef Vc_INTRINSIC_R
327 #define Vc_INTRINSIC inline
328 #define Vc_INTRINSIC_L inline
329 #define Vc_INTRINSIC_R
330 #endif
331 
332 #endif // VC_COMMON_MACROS_H_