SDL
3.0
SDL_intrin.h
Go to the documentation of this file.
1
/*
2
Simple DirectMedia Layer
3
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
4
5
This software is provided 'as-is', without any express or implied
6
warranty. In no event will the authors be held liable for any damages
7
arising from the use of this software.
8
9
Permission is granted to anyone to use this software for any purpose,
10
including commercial applications, and to alter it and redistribute it
11
freely, subject to the following restrictions:
12
13
1. The origin of this software must not be misrepresented; you must not
14
claim that you wrote the original software. If you use this software
15
in a product, an acknowledgment in the product documentation would be
16
appreciated but is not required.
17
2. Altered source versions must be plainly marked as such, and must not be
18
misrepresented as being the original software.
19
3. This notice may not be removed or altered from any source distribution.
20
*/
21
22
/* WIKI CATEGORY: Intrinsics */
23
24
/**
25
* # CategoryIntrinsics
26
*
27
* SDL does some preprocessor gymnastics to determine if any CPU-specific
28
* compiler intrinsics are available, as this is not necessarily an easy thing
29
* to calculate, and sometimes depends on quirks of a system, versions of
30
* build tools, and other external forces.
31
*
32
* Apps including SDL's headers will be able to check consistent preprocessor
33
* definitions to decide if it's safe to use compiler intrinsics for a
34
* specific CPU architecture. This check only tells you that the compiler is
35
* capable of using those intrinsics; at runtime, you should still check if
36
* they are available on the current system with the
37
* [CPU info functions](https://wiki.libsdl.org/SDL3/CategoryCPUInfo)
38
* , such as SDL_HasSSE() or SDL_HasNEON(). Otherwise, the process might crash
39
* for using an unsupported CPU instruction.
40
*
41
* SDL only sets preprocessor defines for CPU intrinsics if they are
42
* supported, so apps should check with `#ifdef` and not `#if`.
43
*
44
* SDL will also include the appropriate instruction-set-specific support
45
* headers, so if SDL decides to define SDL_SSE2_INTRINSICS, it will also
46
* `#include <emmintrin.h>` as well.
47
*/
48
49
#ifndef SDL_intrin_h_
50
#define SDL_intrin_h_
51
52
#include <
SDL3/SDL_stdinc.h
>
53
54
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
55
56
/**
57
* Defined if (and only if) the compiler supports Loongarch LSX intrinsics.
58
*
59
* If this macro is defined, SDL will have already included `<lsxintrin.h>`
60
*
61
* \since This macro is available since SDL 3.2.0.
62
*
63
* \sa SDL_LASX_INTRINSICS
64
*/
65
#define SDL_LSX_INTRINSICS 1
66
67
/**
68
* Defined if (and only if) the compiler supports Loongarch LSX intrinsics.
69
*
70
* If this macro is defined, SDL will have already included `<lasxintrin.h>`
71
*
72
* \since This macro is available since SDL 3.2.0.
73
*
74
* \sa SDL_LASX_INTRINSICS
75
*/
76
#define SDL_LASX_INTRINSICS 1
77
78
/**
79
* Defined if (and only if) the compiler supports ARM NEON intrinsics.
80
*
81
* If this macro is defined, SDL will have already included `<armintr.h>`
82
* `<arm_neon.h>`, `<arm64intr.h>`, and `<arm64_neon.h>`, as appropriate.
83
*
84
* \since This macro is available since SDL 3.2.0.
85
*/
86
#define SDL_NEON_INTRINSICS 1
87
88
/**
89
* Defined if (and only if) the compiler supports ARM SVE2 intrinsics.
90
*
91
* If this macro is defined, `<arm_sve.h>` (providing SVE intrinsics) will
92
* only be included if the target architecture supports SVE
93
* (`__ARM_FEATURE_SVE` feature macro). Some toolchains do not support
94
* `SDL_TARGETING("arch=armv8-a+sve2")`, so for best portability you need to
95
* write all SVE code in a separate translation unit and add appropriate
96
* compile flags.
97
*
98
* \since This macro is available since SDL 3.6.0.
99
*/
100
#define SDL_SVE2_INTRINSICS 1
101
102
/**
103
* Defined if (and only if) the compiler supports PowerPC Altivec intrinsics.
104
*
105
* If this macro is defined, SDL will have already included `<altivec.h>`
106
*
107
* \since This macro is available since SDL 3.2.0.
108
*/
109
#define SDL_ALTIVEC_INTRINSICS 1
110
111
/**
112
* Defined if (and only if) the compiler supports Intel MMX intrinsics.
113
*
114
* If this macro is defined, SDL will have already included `<mmintrin.h>`
115
*
116
* \since This macro is available since SDL 3.2.0.
117
*
118
* \sa SDL_SSE_INTRINSICS
119
*/
120
#define SDL_MMX_INTRINSICS 1
121
122
/**
123
* Defined if (and only if) the compiler supports Intel SSE intrinsics.
124
*
125
* If this macro is defined, SDL will have already included `<xmmintrin.h>`
126
*
127
* \since This macro is available since SDL 3.2.0.
128
*
129
* \sa SDL_SSE2_INTRINSICS
130
* \sa SDL_SSE3_INTRINSICS
131
* \sa SDL_SSE4_1_INTRINSICS
132
* \sa SDL_SSE4_2_INTRINSICS
133
*/
134
#define SDL_SSE_INTRINSICS 1
135
136
/**
137
* Defined if (and only if) the compiler supports Intel SSE2 intrinsics.
138
*
139
* If this macro is defined, SDL will have already included `<emmintrin.h>`
140
*
141
* \since This macro is available since SDL 3.2.0.
142
*
143
* \sa SDL_SSE_INTRINSICS
144
* \sa SDL_SSE3_INTRINSICS
145
* \sa SDL_SSE4_1_INTRINSICS
146
* \sa SDL_SSE4_2_INTRINSICS
147
*/
148
#define SDL_SSE2_INTRINSICS 1
149
150
/**
151
* Defined if (and only if) the compiler supports Intel SSE3 intrinsics.
152
*
153
* If this macro is defined, SDL will have already included `<pmmintrin.h>`
154
*
155
* \since This macro is available since SDL 3.2.0.
156
*
157
* \sa SDL_SSE_INTRINSICS
158
* \sa SDL_SSE2_INTRINSICS
159
* \sa SDL_SSE4_1_INTRINSICS
160
* \sa SDL_SSE4_2_INTRINSICS
161
*/
162
#define SDL_SSE3_INTRINSICS 1
163
164
/**
165
* Defined if (and only if) the compiler supports Intel SSE4.1 intrinsics.
166
*
167
* If this macro is defined, SDL will have already included `<smmintrin.h>`
168
*
169
* \since This macro is available since SDL 3.2.0.
170
*
171
* \sa SDL_SSE_INTRINSICS
172
* \sa SDL_SSE2_INTRINSICS
173
* \sa SDL_SSE3_INTRINSICS
174
* \sa SDL_SSE4_2_INTRINSICS
175
*/
176
#define SDL_SSE4_1_INTRINSICS 1
177
178
/**
179
* Defined if (and only if) the compiler supports Intel SSE4.2 intrinsics.
180
*
181
* If this macro is defined, SDL will have already included `<nmmintrin.h>`
182
*
183
* \since This macro is available since SDL 3.2.0.
184
*
185
* \sa SDL_SSE_INTRINSICS
186
* \sa SDL_SSE2_INTRINSICS
187
* \sa SDL_SSE3_INTRINSICS
188
* \sa SDL_SSE4_1_INTRINSICS
189
*/
190
#define SDL_SSE4_2_INTRINSICS 1
191
192
/**
193
* Defined if (and only if) the compiler supports Intel AVX intrinsics.
194
*
195
* If this macro is defined, SDL will have already included `<immintrin.h>`
196
*
197
* \since This macro is available since SDL 3.2.0.
198
*
199
* \sa SDL_AVX2_INTRINSICS
200
* \sa SDL_AVX512F_INTRINSICS
201
*/
202
#define SDL_AVX_INTRINSICS 1
203
204
/**
205
* Defined if (and only if) the compiler supports Intel AVX2 intrinsics.
206
*
207
* If this macro is defined, SDL will have already included `<immintrin.h>`
208
*
209
* \since This macro is available since SDL 3.2.0.
210
*
211
* \sa SDL_AVX_INTRINSICS
212
* \sa SDL_AVX512F_INTRINSICS
213
*/
214
#define SDL_AVX2_INTRINSICS 1
215
216
/**
217
* Defined if (and only if) the compiler supports Intel AVX-512F intrinsics.
218
*
219
* AVX-512F is also sometimes referred to as "AVX-512 Foundation."
220
*
221
* If this macro is defined, SDL will have already included `<immintrin.h>`
222
*
223
* \since This macro is available since SDL 3.2.0.
224
*
225
* \sa SDL_AVX_INTRINSICS
226
* \sa SDL_AVX2_INTRINSICS
227
*/
228
#define SDL_AVX512F_INTRINSICS 1
229
#endif
230
231
/* Need to do this here because intrin.h has C++ code in it */
232
/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */
233
#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64))
234
/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
235
so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
236
#if defined(__clang__) && !SDL_HAS_BUILTIN(_m_prefetch)
237
#ifndef __PRFCHWINTRIN_H
238
#define __PRFCHWINTRIN_H
239
static
__inline__
void
__attribute__((__always_inline__, __nodebug__))
240
_m_prefetch(
void
*__P)
241
{
242
__builtin_prefetch (__P, 0, 3
/* _MM_HINT_T0 */
);
243
}
244
#endif
/* __PRFCHWINTRIN_H */
245
#endif
/* __clang__ */
246
#include <intrin.h>
247
248
#elif defined(__MINGW64_VERSION_MAJOR)
249
#include <intrin.h>
250
#if defined(__ARM_NEON) && !defined(SDL_DISABLE_NEON)
251
# define SDL_NEON_INTRINSICS 1
252
# include <arm_neon.h>
253
#endif
254
#if !defined(SDL_DISABLE_SVE2)
255
# define SDL_SVE2_INTRINSICS 1
256
# if defined(__ARM_FEATURE_SVE)
257
# include <arm_sve.h>
258
# endif
259
#endif
260
261
#else
262
/* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC to have it included. */
263
#if defined(__ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC)
264
#define SDL_ALTIVEC_INTRINSICS 1
265
#include <altivec.h>
266
#endif
267
#ifndef SDL_DISABLE_NEON
268
# ifdef __ARM_NEON
269
# define SDL_NEON_INTRINSICS 1
270
# include <arm_neon.h>
271
# elif defined(SDL_PLATFORM_WINDOWS)
272
/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */
273
# ifdef _M_ARM
274
# define SDL_NEON_INTRINSICS 1
275
# include <armintr.h>
276
# include <arm_neon.h>
277
# define __ARM_NEON 1
/* Set __ARM_NEON so that it can be used elsewhere, at compile time */
278
# endif
279
# if defined (_M_ARM64)
280
# define SDL_NEON_INTRINSICS 1
281
# include <arm64intr.h>
282
# include <arm64_neon.h>
283
# define __ARM_NEON 1
/* Set __ARM_NEON so that it can be used elsewhere, at compile time */
284
# define __ARM_ARCH 8
285
# endif
286
# endif
287
#endif
288
#ifndef SDL_DISABLE_SVE2
289
# if defined(SDL_PLATFORM_WINDOWS)
290
/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */
291
# if defined (_M_ARM64) && 0
/* Please only remove this 0 when MSVC releasing support for SVE2 officially. */
292
# define SDL_SVE2_INTRINSICS 1
293
# define __ARM_FEATURE_SVE2 1
/* Set __ARM_FEATURE_SVE2 so that it can be used elsewhere, at compile time */
294
# define __ARM_FEATURE_SVE 1
/* Set __ARM_FEATURE_SVE so that it can be used elsewhere, at compile time */
295
# define __ARM_ARCH 8
296
# include <arm_sve.h>
297
# endif
298
# elif defined(SDL_PLATFORM_APPLE)
299
/* Apple has no AArch64 device supporting SVE2 */
300
# elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && (defined(__aarch64__) || defined(_M_ARM64)) && \
301
defined(__has_include) && __has_include(<arm_sve.h>)
302
# define SDL_SVE2_INTRINSICS 1
303
# if defined(__ARM_FEATURE_SVE)
304
# include <arm_sve.h>
305
# endif
306
# endif
307
#endif
308
#endif
/* compiler version */
309
310
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
311
312
/**
313
* A macro to decide if the compiler supports `__attribute__((target))`.
314
*
315
* Even though this is defined in SDL's public headers, it is generally not
316
* used directly by apps. Apps should probably just use SDL_TARGETING
317
* directly, instead.
318
*
319
* \since This macro is available since SDL 3.2.0.
320
*
321
* \sa SDL_TARGETING
322
*/
323
#define SDL_HAS_TARGET_ATTRIBS
324
#elif defined(__loongarch64) && defined(__GNUC__) && (__GNUC__ >= 15)
325
/* LoongArch requires GCC 15+ for target attribute support */
326
# define SDL_HAS_TARGET_ATTRIBS
327
#elif defined(__clang__) && defined(__has_attribute)
328
# if __has_attribute(target)
329
# define SDL_HAS_TARGET_ATTRIBS
330
# endif
331
#elif defined(__GNUC__) && !defined(__loongarch64) && (__GNUC__ + (__GNUC_MINOR__ >= 9) > 4)
/* gcc >= 4.9 */
332
# define SDL_HAS_TARGET_ATTRIBS
333
#elif defined(__ICC) && __ICC >= 1600
334
# define SDL_HAS_TARGET_ATTRIBS
335
#endif
336
337
338
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
339
340
/**
341
* A macro to tag a function as targeting a specific CPU architecture.
342
*
343
* This is a hint to the compiler that a function should be built with support
344
* for a CPU instruction set that might be different than the rest of the
345
* program.
346
*
347
* The particulars of this are explained in the GCC documentation:
348
*
349
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-target-function-attribute
350
*
351
* An example of using this feature is to turn on SSE2 support for a specific
352
* function, even if the rest of the source code is not compiled to use SSE2
353
* code:
354
*
355
* ```c
356
* #ifdef SDL_SSE2_INTRINSICS
357
* static void SDL_TARGETING("sse2") DoSomethingWithSSE2(char *x) {
358
* ...use SSE2 intrinsic functions, etc...
359
* }
360
* #endif
361
*
362
* // later...
363
* #ifdef SDL_SSE2_INTRINSICS
364
* if (SDL_HasSSE2()) {
365
* DoSomethingWithSSE2(str);
366
* }
367
* #endif
368
* ```
369
*
370
* The application is, on a whole, built without SSE2 instructions, so it will
371
* run on Intel machines that don't support SSE2. But then at runtime, it
372
* checks if the system supports the instructions, and then calls into a
373
* function that uses SSE2 opcodes. The ifdefs make sure that this code isn't
374
* used on platforms that don't have SSE2 at all.
375
*
376
* On compilers without target support, this is defined to nothing.
377
*
378
* This symbol is used by SDL internally, but apps and other libraries are
379
* welcome to use it for their own interfaces as well.
380
*
381
* \since This macro is available since SDL 3.2.0.
382
*/
383
#define SDL_TARGETING(x) __attribute__((target(x)))
384
385
#elif defined(SDL_HAS_TARGET_ATTRIBS)
386
# define SDL_TARGETING(x) __attribute__((target(x)))
387
#else
388
# define SDL_TARGETING(x)
389
#endif
390
391
#ifdef __loongarch64
392
# ifndef SDL_DISABLE_LSX
393
# define SDL_LSX_INTRINSICS 1
394
# include <lsxintrin.h>
395
# endif
396
# ifndef SDL_DISABLE_LASX
397
# define SDL_LASX_INTRINSICS 1
398
# include <lasxintrin.h>
399
# endif
400
#endif
401
402
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
403
# if ((defined(_MSC_VER) && !defined(_M_X64)) || defined(__MMX__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_MMX)
404
# define SDL_MMX_INTRINSICS 1
405
# include <mmintrin.h>
406
# endif
407
# if (defined(_MSC_VER) || defined(__SSE__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE)
408
# define SDL_SSE_INTRINSICS 1
409
# include <xmmintrin.h>
410
# endif
411
# if (defined(_MSC_VER) || defined(__SSE2__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE2)
412
# define SDL_SSE2_INTRINSICS 1
413
# include <emmintrin.h>
414
# endif
415
# if (defined(_MSC_VER) || defined(__SSE3__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE3)
416
# define SDL_SSE3_INTRINSICS 1
417
# include <pmmintrin.h>
418
# endif
419
# if (defined(_MSC_VER) || defined(__SSE4_1__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE4_1)
420
# define SDL_SSE4_1_INTRINSICS 1
421
# include <smmintrin.h>
422
# endif
423
# if (defined(_MSC_VER) || defined(__SSE4_2__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_SSE4_2)
424
# define SDL_SSE4_2_INTRINSICS 1
425
# include <nmmintrin.h>
426
# endif
427
# if defined(__clang__) && (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX__) && !defined(SDL_DISABLE_AVX)
428
# define SDL_DISABLE_AVX
/* see https://reviews.llvm.org/D20291 and https://reviews.llvm.org/D79194 */
429
# endif
430
# if (defined(_MSC_VER) || defined(__AVX__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(_M_ARM64EC) && !defined(SDL_DISABLE_AVX)
431
# define SDL_AVX_INTRINSICS 1
432
# include <immintrin.h>
433
# endif
434
# if defined(__clang__) && (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX2__) && !defined(SDL_DISABLE_AVX2)
435
# define SDL_DISABLE_AVX2
/* see https://reviews.llvm.org/D20291 and https://reviews.llvm.org/D79194 */
436
# endif
437
# if (defined(_MSC_VER) || defined(__AVX2__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(_M_ARM64EC) && !defined(SDL_DISABLE_AVX2)
438
# define SDL_AVX2_INTRINSICS 1
439
# include <immintrin.h>
440
# endif
441
# if defined(__clang__) && (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX512F__) && !defined(SDL_DISABLE_AVX512F)
442
# define SDL_DISABLE_AVX512F
/* see https://reviews.llvm.org/D20291 and https://reviews.llvm.org/D79194 */
443
# endif
444
# if (defined(_MSC_VER) || defined(__AVX512F__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(_M_ARM64EC) && !defined(SDL_DISABLE_AVX512F)
445
# define SDL_AVX512F_INTRINSICS 1
446
# include <immintrin.h>
447
# endif
448
#endif
/* defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) */
449
450
#endif
/* SDL_intrin_h_ */
__inline__
#define __inline__
Definition
SDL_begin_code.h:452
SDL_stdinc.h
include
SDL3
SDL_intrin.h
Generated by
1.15.0