1/***************************************************************************
2 * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and *
3 * Martin Renou *
4 * Copyright (c) QuantStack *
5 * Copyright (c) Serge Guelton *
6 * *
7 * Distributed under the terms of the BSD 3-Clause License. *
8 * *
9 * The full license is in the file LICENSE, distributed with this software. *
10 ****************************************************************************/
11
12#ifndef XSIMD_CONFIG_HPP
13#define XSIMD_CONFIG_HPP
14
15#define XSIMD_VERSION_MAJOR 10
16#define XSIMD_VERSION_MINOR 0
17#define XSIMD_VERSION_PATCH 0
18
19/**
20 * high level free functions
21 *
22 * @defgroup xsimd_config_macro Instruction Set Detection
23 */
24
25/**
26 * @ingroup xsimd_config_macro
27 *
28 * Set to 1 if SSE2 is available at compile-time, to 0 otherwise.
29 */
30#ifdef __SSE2__
31#define XSIMD_WITH_SSE2 1
32#else
33#define XSIMD_WITH_SSE2 0
34#endif
35
36/**
37 * @ingroup xsimd_config_macro
38 *
39 * Set to 1 if SSE3 is available at compile-time, to 0 otherwise.
40 */
41#ifdef __SSE3__
42#define XSIMD_WITH_SSE3 1
43#else
44#define XSIMD_WITH_SSE3 0
45#endif
46
47/**
48 * @ingroup xsimd_config_macro
49 *
50 * Set to 1 if SSSE3 is available at compile-time, to 0 otherwise.
51 */
52#ifdef __SSSE3__
53#define XSIMD_WITH_SSSE3 1
54#else
55#define XSIMD_WITH_SSSE3 0
56#endif
57
58/**
59 * @ingroup xsimd_config_macro
60 *
61 * Set to 1 if SSE4.1 is available at compile-time, to 0 otherwise.
62 */
63#ifdef __SSE4_1__
64#define XSIMD_WITH_SSE4_1 1
65#else
66#define XSIMD_WITH_SSE4_1 0
67#endif
68
69/**
70 * @ingroup xsimd_config_macro
71 *
72 * Set to 1 if SSE4.2 is available at compile-time, to 0 otherwise.
73 */
74#ifdef __SSE4_2__
75#define XSIMD_WITH_SSE4_2 1
76#else
77#define XSIMD_WITH_SSE4_2 0
78#endif
79
80/**
81 * @ingroup xsimd_config_macro
82 *
83 * Set to 1 if AVX is available at compile-time, to 0 otherwise.
84 */
85#ifdef __AVX__
86#define XSIMD_WITH_AVX 1
87#else
88#define XSIMD_WITH_AVX 0
89#endif
90
91/**
92 * @ingroup xsimd_config_macro
93 *
94 * Set to 1 if AVX2 is available at compile-time, to 0 otherwise.
95 */
96#ifdef __AVX2__
97#define XSIMD_WITH_AVX2 1
98#else
99#define XSIMD_WITH_AVX2 0
100#endif
101
102/**
103 * @ingroup xsimd_config_macro
104 *
105 * Set to 1 if FMA3 for SSE is available at compile-time, to 0 otherwise.
106 */
107#ifdef __FMA__
108
109#if defined(__SSE__) && !defined(__AVX__)
110#ifndef XSIMD_WITH_FMA3_SSE // Leave the opportunity to manually disable it, see #643
111#define XSIMD_WITH_FMA3_SSE 1
112#endif
113#else
114
115#if XSIMD_WITH_FMA3_SSE
116#error "Manually set XSIMD_WITH_FMA3_SSE is incompatible with current compiler flags"
117#endif
118
119#define XSIMD_WITH_FMA3_SSE 0
120#endif
121
122#else
123
124#if XSIMD_WITH_FMA3_SSE
125#error "Manually set XSIMD_WITH_FMA3_SSE is incompatible with current compiler flags"
126#endif
127
128#define XSIMD_WITH_FMA3_SSE 0
129#endif
130
131/**
132 * @ingroup xsimd_config_macro
133 *
134 * Set to 1 if FMA3 for AVX is available at compile-time, to 0 otherwise.
135 */
136#ifdef __FMA__
137
138#if defined(__AVX__)
139#ifndef XSIMD_WITH_FMA3_AVX // Leave the opportunity to manually disable it, see #643
140#define XSIMD_WITH_FMA3_AVX 1
141#endif
142#else
143
144#if XSIMD_WITH_FMA3_AVX
145#error "Manually set XSIMD_WITH_FMA3_AVX is incompatible with current compiler flags"
146#endif
147
148#define XSIMD_WITH_FMA3_AVX 0
149#endif
150
151#if defined(__AVX2__)
152#ifndef XSIMD_WITH_FMA3_AVX2 // Leave the opportunity to manually disable it, see #643
153#define XSIMD_WITH_FMA3_AVX2 1
154#endif
155#else
156
157#if XSIMD_WITH_FMA3_AVX2
158#error "Manually set XSIMD_WITH_FMA3_AVX2 is incompatible with current compiler flags"
159#endif
160
161#define XSIMD_WITH_FMA3_AVX2 0
162#endif
163
164#else
165
166#if XSIMD_WITH_FMA3_AVX
167#error "Manually set XSIMD_WITH_FMA3_AVX is incompatible with current compiler flags"
168#endif
169
170#if XSIMD_WITH_FMA3_AVX2
171#error "Manually set XSIMD_WITH_FMA3_AVX2 is incompatible with current compiler flags"
172#endif
173
174#define XSIMD_WITH_FMA3_AVX 0
175#define XSIMD_WITH_FMA3_AVX2 0
176
177#endif
178
179/**
180 * @ingroup xsimd_config_macro
181 *
182 * Set to 1 if FMA4 is available at compile-time, to 0 otherwise.
183 */
184#ifdef __FMA4__
185#define XSIMD_WITH_FMA4 1
186#else
187#define XSIMD_WITH_FMA4 0
188#endif
189
190/**
191 * @ingroup xsimd_config_macro
192 *
193 * Set to 1 if AVX512F is available at compile-time, to 0 otherwise.
194 */
195#ifdef __AVX512F__
196// AVX512 instructions are supported starting with gcc 6
197// see https://www.gnu.org/software/gcc/gcc-6/changes.html
198// check clang first, newer clang always defines __GNUC__ = 4
199#if defined(__clang__) && __clang_major__ >= 6
200#define XSIMD_WITH_AVX512F 1
201#elif defined(__GNUC__) && __GNUC__ < 6
202#define XSIMD_WITH_AVX512F 0
203#else
204#define XSIMD_WITH_AVX512F 1
205#if __GNUC__ == 6
206#define XSIMD_AVX512_SHIFT_INTRINSICS_IMM_ONLY 1
207#endif
208#endif
209#else
210#define XSIMD_WITH_AVX512F 0
211#endif
212
213/**
214 * @ingroup xsimd_config_macro
215 *
216 * Set to 1 if AVX512CD is available at compile-time, to 0 otherwise.
217 */
218#ifdef __AVX512CD__
219// Avoids repeating the GCC workaround over and over
220#define XSIMD_WITH_AVX512CD XSIMD_WITH_AVX512F
221#else
222#define XSIMD_WITH_AVX512CD 0
223#endif
224
225/**
226 * @ingroup xsimd_config_macro
227 *
228 * Set to 1 if AVX512DQ is available at compile-time, to 0 otherwise.
229 */
230#ifdef __AVX512DQ__
231#define XSIMD_WITH_AVX512DQ XSIMD_WITH_AVX512F
232#else
233#define XSIMD_WITH_AVX512DQ 0
234#endif
235
236/**
237 * @ingroup xsimd_config_macro
238 *
239 * Set to 1 if AVX512BW is available at compile-time, to 0 otherwise.
240 */
241#ifdef __AVX512BW__
242#define XSIMD_WITH_AVX512BW XSIMD_WITH_AVX512F
243#else
244#define XSIMD_WITH_AVX512BW 0
245#endif
246
247#ifdef __ARM_NEON
248
249/**
250 * @ingroup xsimd_config_macro
251 *
252 * Set to 1 if NEON is available at compile-time, to 0 otherwise.
253 */
254#if __ARM_ARCH >= 7
255#define XSIMD_WITH_NEON 1
256#else
257#define XSIMD_WITH_NEON 0
258#endif
259
260/**
261 * @ingroup xsimd_config_macro
262 *
263 * Set to 1 if NEON64 is available at compile-time, to 0 otherwise.
264 */
265#ifdef __aarch64__
266#define XSIMD_WITH_NEON64 1
267#else
268#define XSIMD_WITH_NEON64 0
269#endif
270#else
271#define XSIMD_WITH_NEON 0
272#define XSIMD_WITH_NEON64 0
273#endif
274
275/**
276 * @ingroup xsimd_config_macro
277 *
278 * Set to 1 if SVE is available and bit width is pre-set at compile-time, to 0 otherwise.
279 */
280#if defined(__ARM_FEATURE_SVE) && defined(__ARM_FEATURE_SVE_BITS) && __ARM_FEATURE_SVE_BITS > 0
281#define XSIMD_WITH_SVE 1
282#define XSIMD_SVE_BITS __ARM_FEATURE_SVE_BITS
283#else
284#define XSIMD_WITH_SVE 0
285#define XSIMD_SVE_BITS 0
286#endif
287
288// Workaround for MSVC compiler
289#ifdef _MSC_VER
290
291#if XSIMD_WITH_AVX512
292#undef XSIMD_WITH_AVX2
293#define XSIMD_WITH_AVX2 1
294#endif
295
296#if XSIMD_WITH_AVX2
297#undef XSIMD_WITH_AVX
298#define XSIMD_WITH_AVX 1
299#undef XSIMD_WITH_FMA3_AVX
300#define XSIMD_WITH_FMA3_AVX 1
301#undef XSIMD_WITH_FMA3_AVX2
302#define XSIMD_WITH_FMA3_AVX2 1
303#endif
304
305#if XSIMD_WITH_AVX
306#undef XSIMD_WITH_SSE4_2
307#define XSIMD_WITH_SSE4_2 1
308#endif
309
310#if !defined(__clang__) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2))
311#undef XSIMD_WITH_SSE4_2
312#define XSIMD_WITH_SSE4_2 1
313#endif
314
315#if XSIMD_WITH_SSE4_2
316#undef XSIMD_WITH_SSE4_1
317#define XSIMD_WITH_SSE4_1 1
318#endif
319
320#if XSIMD_WITH_SSE4_1
321#undef XSIMD_WITH_SSSE3
322#define XSIMD_WITH_SSSE3 1
323#endif
324
325#if XSIMD_WITH_SSSE3
326#undef XSIMD_WITH_SSE3
327#define XSIMD_WITH_SSE3 1
328#endif
329
330#if XSIMD_WITH_SSE3 || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
331#undef XSIMD_WITH_SSE2
332#define XSIMD_WITH_SSE2 1
333#endif
334
335#endif
336
337#if !XSIMD_WITH_SSE2 && !XSIMD_WITH_SSE3 && !XSIMD_WITH_SSSE3 && !XSIMD_WITH_SSE4_1 && !XSIMD_WITH_SSE4_2 && !XSIMD_WITH_AVX && !XSIMD_WITH_AVX2 && !XSIMD_WITH_FMA3_SSE && !XSIMD_WITH_FMA4 && !XSIMD_WITH_FMA3_AVX && !XSIMD_WITH_FMA3_AVX2 && !XSIMD_WITH_AVX512F && !XSIMD_WITH_AVX512CD && !XSIMD_WITH_AVX512DQ && !XSIMD_WITH_AVX512BW && !XSIMD_WITH_NEON && !XSIMD_WITH_NEON64 && !XSIMD_WITH_SVE
338#define XSIMD_NO_SUPPORTED_ARCHITECTURE
339#endif
340
341#endif
342