1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2024 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 | /** |
23 | * \file SDL_cpuinfo.h |
24 | * |
25 | * CPU feature detection for SDL. |
26 | */ |
27 | |
28 | #ifndef SDL_cpuinfo_h_ |
29 | #define SDL_cpuinfo_h_ |
30 | |
31 | #include "SDL_stdinc.h" |
32 | |
33 | /* Need to do this here because intrin.h has C++ code in it */ |
34 | /* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ |
35 | #if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64)) |
36 | #ifdef __clang__ |
37 | /* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, |
38 | so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ |
39 | |
40 | #ifndef __PRFCHWINTRIN_H |
41 | #define __PRFCHWINTRIN_H |
42 | |
43 | static __inline__ void __attribute__((__always_inline__, __nodebug__)) |
44 | _m_prefetch(void *__P) |
45 | { |
46 | __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */); |
47 | } |
48 | |
49 | #endif /* __PRFCHWINTRIN_H */ |
50 | #endif /* __clang__ */ |
51 | #include <intrin.h> |
52 | #ifndef _WIN64 |
53 | #ifndef __MMX__ |
54 | #define __MMX__ |
55 | #endif |
56 | #ifndef __3dNOW__ |
57 | #define __3dNOW__ |
58 | #endif |
59 | #endif |
60 | #ifndef __SSE__ |
61 | #define __SSE__ |
62 | #endif |
63 | #ifndef __SSE2__ |
64 | #define __SSE2__ |
65 | #endif |
66 | #ifndef __SSE3__ |
67 | #define __SSE3__ |
68 | #endif |
69 | #elif defined(__MINGW64_VERSION_MAJOR) |
70 | #include <intrin.h> |
71 | #if !defined(SDL_DISABLE_ARM_NEON_H) && defined(__ARM_NEON) |
72 | # include <arm_neon.h> |
73 | #endif |
74 | #else |
75 | /* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC_H to have it included. */ |
76 | #if defined(HAVE_ALTIVEC_H) && defined(__ALTIVEC__) && !defined(__APPLE_ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC_H) |
77 | #include <altivec.h> |
78 | #endif |
79 | #if !defined(SDL_DISABLE_ARM_NEON_H) |
80 | # if defined(__ARM_NEON) |
81 | # include <arm_neon.h> |
82 | # elif defined(__WINDOWS__) || defined(__WINRT__) || defined(__GDK__) |
83 | /* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */ |
84 | # if defined(_M_ARM) |
85 | # include <armintr.h> |
86 | # include <arm_neon.h> |
87 | # define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ |
88 | # endif |
89 | # if defined (_M_ARM64) |
90 | # include <arm64intr.h> |
91 | # include <arm64_neon.h> |
92 | # define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ |
93 | # define __ARM_ARCH 8 |
94 | # endif |
95 | # endif |
96 | #endif |
97 | #endif /* compiler version */ |
98 | |
99 | #if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H) |
100 | #include <mm3dnow.h> |
101 | #endif |
102 | #if defined(__loongarch_sx) && !defined(SDL_DISABLE_LSX_H) |
103 | #include <lsxintrin.h> |
104 | #define __LSX__ |
105 | #endif |
106 | #if defined(__loongarch_asx) && !defined(SDL_DISABLE_LASX_H) |
107 | #include <lasxintrin.h> |
108 | #define __LASX__ |
109 | #endif |
110 | #if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H) |
111 | #include <immintrin.h> |
112 | #else |
113 | #if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H) |
114 | #include <mmintrin.h> |
115 | #endif |
116 | #if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H) |
117 | #include <xmmintrin.h> |
118 | #endif |
119 | #if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H) |
120 | #include <emmintrin.h> |
121 | #endif |
122 | #if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H) |
123 | #include <pmmintrin.h> |
124 | #endif |
125 | #endif /* HAVE_IMMINTRIN_H */ |
126 | |
127 | #include "begin_code.h" |
128 | /* Set up for C function definitions, even when using C++ */ |
129 | #ifdef __cplusplus |
130 | extern "C" { |
131 | #endif |
132 | |
133 | /* This is a guess for the cacheline size used for padding. |
134 | * Most x86 processors have a 64 byte cache line. |
135 | * The 64-bit PowerPC processors have a 128 byte cache line. |
136 | * We'll use the larger value to be generally safe. |
137 | */ |
138 | #define SDL_CACHELINE_SIZE 128 |
139 | |
140 | /** |
141 | * Get the number of CPU cores available. |
142 | * |
143 | * \returns the total number of logical CPU cores. On CPUs that include |
144 | * technologies such as hyperthreading, the number of logical cores |
145 | * may be more than the number of physical cores. |
146 | * |
147 | * \since This function is available since SDL 2.0.0. |
148 | */ |
149 | extern DECLSPEC int SDLCALL SDL_GetCPUCount(void); |
150 | |
151 | /** |
152 | * Determine the L1 cache line size of the CPU. |
153 | * |
154 | * This is useful for determining multi-threaded structure padding or SIMD |
155 | * prefetch sizes. |
156 | * |
157 | * \returns the L1 cache line size of the CPU, in bytes. |
158 | * |
159 | * \since This function is available since SDL 2.0.0. |
160 | */ |
161 | extern DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void); |
162 | |
163 | /** |
164 | * Determine whether the CPU has the RDTSC instruction. |
165 | * |
166 | * This always returns false on CPUs that aren't using Intel instruction sets. |
167 | * |
168 | * \returns SDL_TRUE if the CPU has the RDTSC instruction or SDL_FALSE if not. |
169 | * |
170 | * \since This function is available since SDL 2.0.0. |
171 | * |
172 | * \sa SDL_Has3DNow |
173 | * \sa SDL_HasAltiVec |
174 | * \sa SDL_HasAVX |
175 | * \sa SDL_HasAVX2 |
176 | * \sa SDL_HasMMX |
177 | * \sa SDL_HasSSE |
178 | * \sa SDL_HasSSE2 |
179 | * \sa SDL_HasSSE3 |
180 | * \sa SDL_HasSSE41 |
181 | * \sa SDL_HasSSE42 |
182 | */ |
183 | extern DECLSPEC SDL_bool SDLCALL SDL_HasRDTSC(void); |
184 | |
185 | /** |
186 | * Determine whether the CPU has AltiVec features. |
187 | * |
188 | * This always returns false on CPUs that aren't using PowerPC instruction |
189 | * sets. |
190 | * |
191 | * \returns SDL_TRUE if the CPU has AltiVec features or SDL_FALSE if not. |
192 | * |
193 | * \since This function is available since SDL 2.0.0. |
194 | * |
195 | * \sa SDL_Has3DNow |
196 | * \sa SDL_HasAVX |
197 | * \sa SDL_HasAVX2 |
198 | * \sa SDL_HasMMX |
199 | * \sa SDL_HasRDTSC |
200 | * \sa SDL_HasSSE |
201 | * \sa SDL_HasSSE2 |
202 | * \sa SDL_HasSSE3 |
203 | * \sa SDL_HasSSE41 |
204 | * \sa SDL_HasSSE42 |
205 | */ |
206 | extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void); |
207 | |
208 | /** |
209 | * Determine whether the CPU has MMX features. |
210 | * |
211 | * This always returns false on CPUs that aren't using Intel instruction sets. |
212 | * |
213 | * \returns SDL_TRUE if the CPU has MMX features or SDL_FALSE if not. |
214 | * |
215 | * \since This function is available since SDL 2.0.0. |
216 | * |
217 | * \sa SDL_Has3DNow |
218 | * \sa SDL_HasAltiVec |
219 | * \sa SDL_HasAVX |
220 | * \sa SDL_HasAVX2 |
221 | * \sa SDL_HasRDTSC |
222 | * \sa SDL_HasSSE |
223 | * \sa SDL_HasSSE2 |
224 | * \sa SDL_HasSSE3 |
225 | * \sa SDL_HasSSE41 |
226 | * \sa SDL_HasSSE42 |
227 | */ |
228 | extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void); |
229 | |
230 | /** |
231 | * Determine whether the CPU has 3DNow! features. |
232 | * |
233 | * This always returns false on CPUs that aren't using AMD instruction sets. |
234 | * |
235 | * \returns SDL_TRUE if the CPU has 3DNow! features or SDL_FALSE if not. |
236 | * |
237 | * \since This function is available since SDL 2.0.0. |
238 | * |
239 | * \sa SDL_HasAltiVec |
240 | * \sa SDL_HasAVX |
241 | * \sa SDL_HasAVX2 |
242 | * \sa SDL_HasMMX |
243 | * \sa SDL_HasRDTSC |
244 | * \sa SDL_HasSSE |
245 | * \sa SDL_HasSSE2 |
246 | * \sa SDL_HasSSE3 |
247 | * \sa SDL_HasSSE41 |
248 | * \sa SDL_HasSSE42 |
249 | */ |
250 | extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void); |
251 | |
252 | /** |
253 | * Determine whether the CPU has SSE features. |
254 | * |
255 | * This always returns false on CPUs that aren't using Intel instruction sets. |
256 | * |
257 | * \returns SDL_TRUE if the CPU has SSE features or SDL_FALSE if not. |
258 | * |
259 | * \since This function is available since SDL 2.0.0. |
260 | * |
261 | * \sa SDL_Has3DNow |
262 | * \sa SDL_HasAltiVec |
263 | * \sa SDL_HasAVX |
264 | * \sa SDL_HasAVX2 |
265 | * \sa SDL_HasMMX |
266 | * \sa SDL_HasRDTSC |
267 | * \sa SDL_HasSSE2 |
268 | * \sa SDL_HasSSE3 |
269 | * \sa SDL_HasSSE41 |
270 | * \sa SDL_HasSSE42 |
271 | */ |
272 | extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void); |
273 | |
274 | /** |
275 | * Determine whether the CPU has SSE2 features. |
276 | * |
277 | * This always returns false on CPUs that aren't using Intel instruction sets. |
278 | * |
279 | * \returns SDL_TRUE if the CPU has SSE2 features or SDL_FALSE if not. |
280 | * |
281 | * \since This function is available since SDL 2.0.0. |
282 | * |
283 | * \sa SDL_Has3DNow |
284 | * \sa SDL_HasAltiVec |
285 | * \sa SDL_HasAVX |
286 | * \sa SDL_HasAVX2 |
287 | * \sa SDL_HasMMX |
288 | * \sa SDL_HasRDTSC |
289 | * \sa SDL_HasSSE |
290 | * \sa SDL_HasSSE3 |
291 | * \sa SDL_HasSSE41 |
292 | * \sa SDL_HasSSE42 |
293 | */ |
294 | extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void); |
295 | |
296 | /** |
297 | * Determine whether the CPU has SSE3 features. |
298 | * |
299 | * This always returns false on CPUs that aren't using Intel instruction sets. |
300 | * |
301 | * \returns SDL_TRUE if the CPU has SSE3 features or SDL_FALSE if not. |
302 | * |
303 | * \since This function is available since SDL 2.0.0. |
304 | * |
305 | * \sa SDL_Has3DNow |
306 | * \sa SDL_HasAltiVec |
307 | * \sa SDL_HasAVX |
308 | * \sa SDL_HasAVX2 |
309 | * \sa SDL_HasMMX |
310 | * \sa SDL_HasRDTSC |
311 | * \sa SDL_HasSSE |
312 | * \sa SDL_HasSSE2 |
313 | * \sa SDL_HasSSE41 |
314 | * \sa SDL_HasSSE42 |
315 | */ |
316 | extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE3(void); |
317 | |
318 | /** |
319 | * Determine whether the CPU has SSE4.1 features. |
320 | * |
321 | * This always returns false on CPUs that aren't using Intel instruction sets. |
322 | * |
323 | * \returns SDL_TRUE if the CPU has SSE4.1 features or SDL_FALSE if not. |
324 | * |
325 | * \since This function is available since SDL 2.0.0. |
326 | * |
327 | * \sa SDL_Has3DNow |
328 | * \sa SDL_HasAltiVec |
329 | * \sa SDL_HasAVX |
330 | * \sa SDL_HasAVX2 |
331 | * \sa SDL_HasMMX |
332 | * \sa SDL_HasRDTSC |
333 | * \sa SDL_HasSSE |
334 | * \sa SDL_HasSSE2 |
335 | * \sa SDL_HasSSE3 |
336 | * \sa SDL_HasSSE42 |
337 | */ |
338 | extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE41(void); |
339 | |
340 | /** |
341 | * Determine whether the CPU has SSE4.2 features. |
342 | * |
343 | * This always returns false on CPUs that aren't using Intel instruction sets. |
344 | * |
345 | * \returns SDL_TRUE if the CPU has SSE4.2 features or SDL_FALSE if not. |
346 | * |
347 | * \since This function is available since SDL 2.0.0. |
348 | * |
349 | * \sa SDL_Has3DNow |
350 | * \sa SDL_HasAltiVec |
351 | * \sa SDL_HasAVX |
352 | * \sa SDL_HasAVX2 |
353 | * \sa SDL_HasMMX |
354 | * \sa SDL_HasRDTSC |
355 | * \sa SDL_HasSSE |
356 | * \sa SDL_HasSSE2 |
357 | * \sa SDL_HasSSE3 |
358 | * \sa SDL_HasSSE41 |
359 | */ |
360 | extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void); |
361 | |
362 | /** |
363 | * Determine whether the CPU has AVX features. |
364 | * |
365 | * This always returns false on CPUs that aren't using Intel instruction sets. |
366 | * |
367 | * \returns SDL_TRUE if the CPU has AVX features or SDL_FALSE if not. |
368 | * |
369 | * \since This function is available since SDL 2.0.2. |
370 | * |
371 | * \sa SDL_Has3DNow |
372 | * \sa SDL_HasAltiVec |
373 | * \sa SDL_HasAVX2 |
374 | * \sa SDL_HasMMX |
375 | * \sa SDL_HasRDTSC |
376 | * \sa SDL_HasSSE |
377 | * \sa SDL_HasSSE2 |
378 | * \sa SDL_HasSSE3 |
379 | * \sa SDL_HasSSE41 |
380 | * \sa SDL_HasSSE42 |
381 | */ |
382 | extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void); |
383 | |
384 | /** |
385 | * Determine whether the CPU has AVX2 features. |
386 | * |
387 | * This always returns false on CPUs that aren't using Intel instruction sets. |
388 | * |
389 | * \returns SDL_TRUE if the CPU has AVX2 features or SDL_FALSE if not. |
390 | * |
391 | * \since This function is available since SDL 2.0.4. |
392 | * |
393 | * \sa SDL_Has3DNow |
394 | * \sa SDL_HasAltiVec |
395 | * \sa SDL_HasAVX |
396 | * \sa SDL_HasMMX |
397 | * \sa SDL_HasRDTSC |
398 | * \sa SDL_HasSSE |
399 | * \sa SDL_HasSSE2 |
400 | * \sa SDL_HasSSE3 |
401 | * \sa SDL_HasSSE41 |
402 | * \sa SDL_HasSSE42 |
403 | */ |
404 | extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void); |
405 | |
406 | /** |
407 | * Determine whether the CPU has AVX-512F (foundation) features. |
408 | * |
409 | * This always returns false on CPUs that aren't using Intel instruction sets. |
410 | * |
411 | * \returns SDL_TRUE if the CPU has AVX-512F features or SDL_FALSE if not. |
412 | * |
413 | * \since This function is available since SDL 2.0.9. |
414 | * |
415 | * \sa SDL_HasAVX |
416 | */ |
417 | extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void); |
418 | |
419 | /** |
420 | * Determine whether the CPU has ARM SIMD (ARMv6) features. |
421 | * |
422 | * This is different from ARM NEON, which is a different instruction set. |
423 | * |
424 | * This always returns false on CPUs that aren't using ARM instruction sets. |
425 | * |
426 | * \returns SDL_TRUE if the CPU has ARM SIMD features or SDL_FALSE if not. |
427 | * |
428 | * \since This function is available since SDL 2.0.12. |
429 | * |
430 | * \sa SDL_HasNEON |
431 | */ |
432 | extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void); |
433 | |
434 | /** |
435 | * Determine whether the CPU has NEON (ARM SIMD) features. |
436 | * |
437 | * This always returns false on CPUs that aren't using ARM instruction sets. |
438 | * |
439 | * \returns SDL_TRUE if the CPU has ARM NEON features or SDL_FALSE if not. |
440 | * |
441 | * \since This function is available since SDL 2.0.6. |
442 | */ |
443 | extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void); |
444 | |
445 | /** |
446 | * Determine whether the CPU has LSX (LOONGARCH SIMD) features. |
447 | * |
448 | * This always returns false on CPUs that aren't using LOONGARCH instruction |
449 | * sets. |
450 | * |
451 | * \returns SDL_TRUE if the CPU has LOONGARCH LSX features or SDL_FALSE if |
452 | * not. |
453 | * |
454 | * \since This function is available since SDL 2.24.0. |
455 | */ |
456 | extern DECLSPEC SDL_bool SDLCALL SDL_HasLSX(void); |
457 | |
458 | /** |
459 | * Determine whether the CPU has LASX (LOONGARCH SIMD) features. |
460 | * |
461 | * This always returns false on CPUs that aren't using LOONGARCH instruction |
462 | * sets. |
463 | * |
464 | * \returns SDL_TRUE if the CPU has LOONGARCH LASX features or SDL_FALSE if |
465 | * not. |
466 | * |
467 | * \since This function is available since SDL 2.24.0. |
468 | */ |
469 | extern DECLSPEC SDL_bool SDLCALL SDL_HasLASX(void); |
470 | |
471 | /** |
472 | * Get the amount of RAM configured in the system. |
473 | * |
474 | * \returns the amount of RAM configured in the system in MiB. |
475 | * |
476 | * \since This function is available since SDL 2.0.1. |
477 | */ |
478 | extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void); |
479 | |
480 | /** |
481 | * Report the alignment this system needs for SIMD allocations. |
482 | * |
483 | * This will return the minimum number of bytes to which a pointer must be |
484 | * aligned to be compatible with SIMD instructions on the current machine. For |
485 | * example, if the machine supports SSE only, it will return 16, but if it |
486 | * supports AVX-512F, it'll return 64 (etc). This only reports values for |
487 | * instruction sets SDL knows about, so if your SDL build doesn't have |
488 | * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and |
489 | * not 64 for the AVX-512 instructions that exist but SDL doesn't know about. |
490 | * Plan accordingly. |
491 | * |
492 | * \returns the alignment in bytes needed for available, known SIMD |
493 | * instructions. |
494 | * |
495 | * \since This function is available since SDL 2.0.10. |
496 | */ |
497 | extern DECLSPEC size_t SDLCALL SDL_SIMDGetAlignment(void); |
498 | |
499 | /** |
500 | * Allocate memory in a SIMD-friendly way. |
501 | * |
502 | * This will allocate a block of memory that is suitable for use with SIMD |
503 | * instructions. Specifically, it will be properly aligned and padded for the |
504 | * system's supported vector instructions. |
505 | * |
506 | * The memory returned will be padded such that it is safe to read or write an |
507 | * incomplete vector at the end of the memory block. This can be useful so you |
508 | * don't have to drop back to a scalar fallback at the end of your SIMD |
509 | * processing loop to deal with the final elements without overflowing the |
510 | * allocated buffer. |
511 | * |
512 | * You must free this memory with SDL_FreeSIMD(), not free() or SDL_free() or |
513 | * delete[], etc. |
514 | * |
515 | * Note that SDL will only deal with SIMD instruction sets it is aware of; for |
516 | * example, SDL 2.0.8 knows that SSE wants 16-byte vectors (SDL_HasSSE()), and |
517 | * AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't know that AVX-512 wants |
518 | * 64. To be clear: if you can't decide to use an instruction set with an |
519 | * SDL_Has*() function, don't use that instruction set with memory allocated |
520 | * through here. |
521 | * |
522 | * SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't |
523 | * out of memory, but you are not allowed to dereference it (because you only |
524 | * own zero bytes of that buffer). |
525 | * |
526 | * \param len The length, in bytes, of the block to allocate. The actual |
527 | * allocated block might be larger due to padding, etc. |
528 | * \returns a pointer to the newly-allocated block, NULL if out of memory. |
529 | * |
530 | * \since This function is available since SDL 2.0.10. |
531 | * |
532 | * \sa SDL_SIMDGetAlignment |
533 | * \sa SDL_SIMDRealloc |
534 | * \sa SDL_SIMDFree |
535 | */ |
536 | extern DECLSPEC void * SDLCALL SDL_SIMDAlloc(const size_t len); |
537 | |
538 | /** |
539 | * Reallocate memory obtained from SDL_SIMDAlloc |
540 | * |
541 | * It is not valid to use this function on a pointer from anything but |
542 | * SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, |
543 | * SDL_malloc, memalign, new[], etc. |
544 | * |
545 | * \param mem The pointer obtained from SDL_SIMDAlloc. This function also |
546 | * accepts NULL, at which point this function is the same as |
547 | * calling SDL_SIMDAlloc with a NULL pointer. |
548 | * \param len The length, in bytes, of the block to allocated. The actual |
549 | * allocated block might be larger due to padding, etc. Passing 0 |
550 | * will return a non-NULL pointer, assuming the system isn't out of |
551 | * memory. |
552 | * \returns a pointer to the newly-reallocated block, NULL if out of memory. |
553 | * |
554 | * \since This function is available since SDL 2.0.14. |
555 | * |
556 | * \sa SDL_SIMDGetAlignment |
557 | * \sa SDL_SIMDAlloc |
558 | * \sa SDL_SIMDFree |
559 | */ |
560 | extern DECLSPEC void * SDLCALL SDL_SIMDRealloc(void *mem, const size_t len); |
561 | |
562 | /** |
563 | * Deallocate memory obtained from SDL_SIMDAlloc |
564 | * |
565 | * It is not valid to use this function on a pointer from anything but |
566 | * SDL_SIMDAlloc() or SDL_SIMDRealloc(). It can't be used on pointers from |
567 | * malloc, realloc, SDL_malloc, memalign, new[], etc. |
568 | * |
569 | * However, SDL_SIMDFree(NULL) is a legal no-op. |
570 | * |
571 | * The memory pointed to by `ptr` is no longer valid for access upon return, |
572 | * and may be returned to the system or reused by a future allocation. The |
573 | * pointer passed to this function is no longer safe to dereference once this |
574 | * function returns, and should be discarded. |
575 | * |
576 | * \param ptr The pointer, returned from SDL_SIMDAlloc or SDL_SIMDRealloc, to |
577 | * deallocate. NULL is a legal no-op. |
578 | * |
579 | * \since This function is available since SDL 2.0.10. |
580 | * |
581 | * \sa SDL_SIMDAlloc |
582 | * \sa SDL_SIMDRealloc |
583 | */ |
584 | extern DECLSPEC void SDLCALL SDL_SIMDFree(void *ptr); |
585 | |
586 | /* Ends C function definitions when using C++ */ |
587 | #ifdef __cplusplus |
588 | } |
589 | #endif |
590 | #include "close_code.h" |
591 | |
592 | #endif /* SDL_cpuinfo_h_ */ |
593 | |
594 | /* vi: set ts=4 sw=4 expandtab: */ |
595 | |