48 #define Vc_ICC __INTEL_COMPILER_BUILD_DATE
57 #define Vc_CLANG (__clang_major__ * 0x10000 + __clang_minor__ * 0x100 + __clang_patchlevel__)
66 #define Vc_APPLECLANG (__clang_major__ * 0x10000 + __clang_minor__ * 0x100 + __clang_patchlevel__)
75 #define Vc_GCC (__GNUC__ * 0x10000 + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
83 #define Vc_MSVC _MSC_FULL_VER
90 #ifdef __INTEL_COMPILER
91 #define Vc_ICC __INTEL_COMPILER_BUILD_DATE
92 #elif defined(__clang__) && defined(__apple_build_version__)
93 #define Vc_APPLECLANG (__clang_major__ * 0x10000 + __clang_minor__ * 0x100 + __clang_patchlevel__)
94 #elif defined(__clang__)
95 #define Vc_CLANG (__clang_major__ * 0x10000 + __clang_minor__ * 0x100 + __clang_patchlevel__)
96 #elif defined(__GNUC__)
97 #define Vc_GCC (__GNUC__ * 0x10000 + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
98 #elif defined(_MSC_VER)
99 #define Vc_MSVC _MSC_FULL_VER
101 #define Vc_UNSUPPORTED_COMPILER 1
104 #if defined Vc_GCC && Vc_GCC >= 0x60000
105 #define Vc_RESET_DIAGNOSTICS _Pragma("GCC diagnostic pop")
106 #pragma GCC diagnostic push
107 #pragma GCC diagnostic ignored "-Wignored-attributes"
109 #define Vc_RESET_DIAGNOSTICS
118 #pragma warning disable 2922
121 #if __cplusplus < 201103 && (!defined Vc_MSVC || _MSC_VER < 1900)
122 # error "Vc requires support for C++11."
123 #elif __cplusplus >= 201402L
125 # if __cplusplus > 201700L
130 #if defined(__GNUC__) && !defined(Vc_NO_INLINE_ASM)
135 # if Vc_GCC >= 0x70000 && defined __i386__
139 # ifdef __GLIBC_PREREQ
140 # if __GLIBC_PREREQ(2,26)
141 # define Vc_HAVE_STD_MAX_ALIGN_T 1
144 # elif Vc_GCC >= 0x40900
145 # define Vc_HAVE_STD_MAX_ALIGN_T 1
147 # define Vc_HAVE_MAX_ALIGN_T 1
149 #elif !defined(Vc_CLANG) && !defined(Vc_ICC)
153 # define Vc_HAVE_STD_MAX_ALIGN_T 1
156 #if defined(Vc_GCC) || defined(Vc_CLANG) || defined Vc_APPLECLANG
157 #define Vc_USE_BUILTIN_VECTOR_TYPES 1
161 # define Vc_CDECL __cdecl
162 # define Vc_VDECL __vectorcall
172 #define Scalar 0x00100000
173 #define SSE 0x00200000
174 #define SSE2 0x00300000
175 #define SSE3 0x00400000
176 #define SSSE3 0x00500000
177 #define SSE4_1 0x00600000
178 #define SSE4_2 0x00700000
179 #define AVX 0x00800000
180 #define AVX2 0x00900000
182 #define XOP 0x00000001
183 #define FMA4 0x00000002
184 #define F16C 0x00000004
185 #define POPCNT 0x00000008
186 #define SSE4a 0x00000010
187 #define FMA 0x00000020
188 #define BMI2 0x00000040
190 #define IMPL_MASK 0xFFF00000
191 #define EXT_MASK 0x000FFFFF
205 # elif defined(_M_AMD64)
216 #if defined Vc_ICC && !defined __POPCNT__
217 # if defined __SSE4_2__ || defined __SSE4A__
218 # define __POPCNT__ 1
223 #error "You are using the old VC_IMPL macro. Since Vc 1.0 all Vc macros start with Vc_, i.e. a lower-case 'c'"
228 # if defined(__AVX2__)
229 # define Vc_IMPL_AVX2 1
230 # define Vc_IMPL_AVX 1
231 # elif defined(__AVX__)
232 # define Vc_IMPL_AVX 1
234 # if defined(__SSE4_2__)
235 # define Vc_IMPL_SSE 1
236 # define Vc_IMPL_SSE4_2 1
238 # if defined(__SSE4_1__)
239 # define Vc_IMPL_SSE 1
240 # define Vc_IMPL_SSE4_1 1
242 # if defined(__SSE3__)
243 # define Vc_IMPL_SSE 1
244 # define Vc_IMPL_SSE3 1
246 # if defined(__SSSE3__)
247 # define Vc_IMPL_SSE 1
248 # define Vc_IMPL_SSSE3 1
250 # if defined(__SSE2__)
251 # define Vc_IMPL_SSE 1
252 # define Vc_IMPL_SSE2 1
255 # if defined(Vc_IMPL_SSE)
258 # define Vc_IMPL_Scalar 1
261 # if !defined(Vc_IMPL_Scalar)
263 # define Vc_IMPL_FMA4 1
266 # define Vc_IMPL_XOP 1
269 # define Vc_IMPL_F16C 1
272 # define Vc_IMPL_POPCNT 1
275 # define Vc_IMPL_SSE4a 1
278 # define Vc_IMPL_FMA 1
281 # define Vc_IMPL_BMI2 1
287 # if (Vc_IMPL & IMPL_MASK) == AVX2
288 # define Vc_IMPL_AVX2 1
289 # define Vc_IMPL_AVX 1
290 # elif (Vc_IMPL & IMPL_MASK) == AVX
291 # define Vc_IMPL_AVX 1
292 # elif (Vc_IMPL & IMPL_MASK) == Scalar
293 # define Vc_IMPL_Scalar 1
294 # elif (Vc_IMPL & IMPL_MASK) == SSE4_2
295 # define Vc_IMPL_SSE4_2 1
296 # define Vc_IMPL_SSE4_1 1
297 # define Vc_IMPL_SSSE3 1
298 # define Vc_IMPL_SSE3 1
299 # define Vc_IMPL_SSE2 1
300 # define Vc_IMPL_SSE 1
301 # elif (Vc_IMPL & IMPL_MASK) == SSE4_1
302 # define Vc_IMPL_SSE4_1 1
303 # define Vc_IMPL_SSSE3 1
304 # define Vc_IMPL_SSE3 1
305 # define Vc_IMPL_SSE2 1
306 # define Vc_IMPL_SSE 1
307 # elif (Vc_IMPL & IMPL_MASK) == SSSE3
308 # define Vc_IMPL_SSSE3 1
309 # define Vc_IMPL_SSE3 1
310 # define Vc_IMPL_SSE2 1
311 # define Vc_IMPL_SSE 1
312 # elif (Vc_IMPL & IMPL_MASK) == SSE3
313 # define Vc_IMPL_SSE3 1
314 # define Vc_IMPL_SSE2 1
315 # define Vc_IMPL_SSE 1
316 # elif (Vc_IMPL & IMPL_MASK) == SSE2
317 # define Vc_IMPL_SSE2 1
318 # define Vc_IMPL_SSE 1
319 # elif (Vc_IMPL & IMPL_MASK) == SSE
320 # define Vc_IMPL_SSE 1
321 # if defined(__SSE4_2__)
322 # define Vc_IMPL_SSE4_2 1
324 # if defined(__SSE4_1__)
325 # define Vc_IMPL_SSE4_1 1
327 # if defined(__SSE3__)
328 # define Vc_IMPL_SSE3 1
330 # if defined(__SSSE3__)
331 # define Vc_IMPL_SSSE3 1
333 # if defined(__SSE2__)
334 # define Vc_IMPL_SSE2 1
336 # elif (Vc_IMPL & IMPL_MASK) == 0 && (Vc_IMPL & SSE4a)
339 # define Vc_IMPL_SSE3 1
340 # define Vc_IMPL_SSE2 1
341 # define Vc_IMPL_SSE 1
344 # define Vc_IMPL_XOP 1
346 # if (Vc_IMPL & FMA4)
347 # define Vc_IMPL_FMA4 1
349 # if (Vc_IMPL & F16C)
350 # define Vc_IMPL_F16C 1
352 # if (!defined(Vc_IMPL_Scalar) && defined(__POPCNT__)) || (Vc_IMPL & POPCNT)
353 # define Vc_IMPL_POPCNT 1
355 # if (Vc_IMPL & SSE4a)
356 # define Vc_IMPL_SSE4a 1
359 # define Vc_IMPL_FMA 1
361 # if (Vc_IMPL & BMI2)
362 # define Vc_IMPL_BMI2 1
370 # define Vc_USE_VEX_CODING 1
375 # define Vc_IMPL_SSE4_2 1
376 # define Vc_IMPL_SSE4_1 1
377 # define Vc_IMPL_SSSE3 1
378 # define Vc_IMPL_SSE3 1
379 # define Vc_IMPL_SSE2 1
380 # define Vc_IMPL_SSE 1
383 #if defined(Vc_CLANG) && Vc_CLANG >= 0x30600 && Vc_CLANG < 0x30700
384 # if defined(Vc_IMPL_AVX)
385 # warning "clang 3.6.x miscompiles AVX code, frequently losing 50% of the data. Vc will fall back to SSE4 instead."
387 # if defined(Vc_IMPL_AVX2)
393 # if !defined(Vc_IMPL_Scalar) && !defined(Vc_IMPL_SSE) && !defined(Vc_IMPL_AVX)
394 # error "No suitable Vc implementation was selected! Probably Vc_IMPL was set to an invalid value."
395 # elif defined(Vc_IMPL_SSE) && !defined(Vc_IMPL_SSE2)
396 # error "SSE requested but no SSE2 support. Vc needs at least SSE2!"
420 #if defined Vc_IMPL_AVX2
421 #define Vc_DEFAULT_IMPL_AVX2
422 #elif defined Vc_IMPL_AVX
423 #define Vc_DEFAULT_IMPL_AVX
424 #elif defined Vc_IMPL_SSE
425 #define Vc_DEFAULT_IMPL_SSE
426 #elif defined Vc_IMPL_Scalar
427 #define Vc_DEFAULT_IMPL_Scalar
429 #error "Preprocessor logic broken. Please report a bug."
434 namespace Vc_VERSIONED_NAMESPACE
437 typedef signed char int8_t;
438 typedef unsigned char uint8_t;
439 typedef signed short int16_t;
440 typedef unsigned short uint16_t;
441 typedef signed int int32_t;
442 typedef unsigned int uint32_t;
443 typedef signed long long int64_t;
444 typedef unsigned long long uint64_t;
501 ImplementationMask = 0xfff
534 ExtraInstructionsMask = 0xfffff000u
550 return static_cast<Implementation>(Features & ImplementationMask);
555 return static_cast<unsigned int>(impl) == current();
563 return static_cast<unsigned int>(low) <= current() &&
564 static_cast<unsigned int>(high) >= current();
569 static constexpr
bool runs_on(
unsigned int extraInstructions)
571 return (extraInstructions & Features & ExtraInstructionsMask) ==
572 (Features & ExtraInstructionsMask);
582 #ifdef Vc_IMPL_Scalar
584 #elif defined(Vc_IMPL_AVX2)
586 #elif defined(Vc_IMPL_AVX)
588 #elif defined(Vc_IMPL_SSE4_2)
590 #elif defined(Vc_IMPL_SSE4_1)
592 #elif defined(Vc_IMPL_SSSE3)
594 #elif defined(Vc_IMPL_SSE3)
596 #elif defined(Vc_IMPL_SSE2)
608 #ifdef Vc_IMPL_POPCNT
617 #ifdef Vc_USE_VEX_CODING
Implementation
Enum to identify a certain SIMD instruction set.
ExtraInstructions
The list of available instructions is not easily described by a linear list of instruction sets.
MallocAlignment
Enum that specifies the alignment and padding restrictions to use for memory allocation with Vc::mall...
@ SSE41Impl
x86 SSE + SSE2 + SSE3 + SSSE3 + SSE4.1
@ SSSE3Impl
x86 SSE + SSE2 + SSE3 + SSSE3
@ SSE3Impl
x86 SSE + SSE2 + SSE3
@ SSE42Impl
x86 SSE + SSE2 + SSE3 + SSSE3 + SSE4.1 + SSE4.2
@ ScalarImpl
uses only fundamental types
@ Bmi2Instructions
Support for BMI2 instructions.
@ XopInstructions
Support for XOP instructions.
@ Fma4Instructions
Support for FMA4 instructions.
@ FmaInstructions
Support for FMA instructions (3 operand variant)
@ VexInstructions
Support for ternary instruction coding (VEX)
@ Float16cInstructions
Support for float16 conversions in hardware.
@ PopcntInstructions
Support for the population count instruction.
@ Sse4aInstructions
Support for SSE4a instructions.
@ AlignOnPage
Align on boundary of page sizes (e.g.
@ AlignOnCacheline
Align on boundary of cache line sizes (e.g.
@ AlignOnVector
Align on boundary of vector sizes (e.g.
This class identifies the specific implementation Vc uses in the current translation unit in terms of...
static constexpr Implementation current()
Returns the currently used Vc::Implementation.
static constexpr bool runs_on(unsigned int extraInstructions)
Returns whether the current code would run on a CPU providing extraInstructions.
static constexpr bool is_between(Implementation low, Implementation high)
Returns whether the current Vc::Implementation implements at least low and at most high.
static constexpr bool is(Implementation impl)
Returns whether impl is the current Vc::Implementation.