10b57cec5SDimitry Andric /*===---- mm_malloc.h - Allocating and Freeing Aligned Memory Blocks -------===
20b57cec5SDimitry Andric  *
30b57cec5SDimitry Andric  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric  * See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric  *
70b57cec5SDimitry Andric  *===-----------------------------------------------------------------------===
80b57cec5SDimitry Andric  */
90b57cec5SDimitry Andric 
100b57cec5SDimitry Andric #ifndef __MM_MALLOC_H
110b57cec5SDimitry Andric #define __MM_MALLOC_H
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include <stdlib.h>
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #ifdef _WIN32
160b57cec5SDimitry Andric #include <malloc.h>
170b57cec5SDimitry Andric #else
180b57cec5SDimitry Andric #ifndef __cplusplus
190b57cec5SDimitry Andric extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
200b57cec5SDimitry Andric #else
210b57cec5SDimitry Andric // Some systems (e.g. those with GNU libc) declare posix_memalign with an
220b57cec5SDimitry Andric // exception specifier. Via an "egregious workaround" in
230b57cec5SDimitry Andric // Sema::CheckEquivalentExceptionSpec, Clang accepts the following as a valid
240b57cec5SDimitry Andric // redeclaration of glibc's declaration.
250b57cec5SDimitry Andric extern "C" int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
260b57cec5SDimitry Andric #endif
270b57cec5SDimitry Andric #endif
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric #if !(defined(_WIN32) && defined(_mm_malloc))
300b57cec5SDimitry Andric static __inline__ void *__attribute__((__always_inline__, __nodebug__,
3181ad6265SDimitry Andric                                        __malloc__, __alloc_size__(1),
3281ad6265SDimitry Andric                                        __alloc_align__(2)))
_mm_malloc(size_t __size,size_t __align)3381ad6265SDimitry Andric _mm_malloc(size_t __size, size_t __align) {
340b57cec5SDimitry Andric   if (__align == 1) {
350b57cec5SDimitry Andric     return malloc(__size);
360b57cec5SDimitry Andric   }
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   if (!(__align & (__align - 1)) && __align < sizeof(void *))
390b57cec5SDimitry Andric     __align = sizeof(void *);
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   void *__mallocedMemory;
420b57cec5SDimitry Andric #if defined(__MINGW32__)
430b57cec5SDimitry Andric   __mallocedMemory = __mingw_aligned_malloc(__size, __align);
440b57cec5SDimitry Andric #elif defined(_WIN32)
450b57cec5SDimitry Andric   __mallocedMemory = _aligned_malloc(__size, __align);
460b57cec5SDimitry Andric #else
470b57cec5SDimitry Andric   if (posix_memalign(&__mallocedMemory, __align, __size))
480b57cec5SDimitry Andric     return 0;
490b57cec5SDimitry Andric #endif
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   return __mallocedMemory;
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__))
_mm_free(void * __p)550b57cec5SDimitry Andric _mm_free(void *__p)
560b57cec5SDimitry Andric {
57e8d8bef9SDimitry Andric #if defined(__MINGW32__)
58e8d8bef9SDimitry Andric   __mingw_aligned_free(__p);
59e8d8bef9SDimitry Andric #elif defined(_WIN32)
60e8d8bef9SDimitry Andric   _aligned_free(__p);
61e8d8bef9SDimitry Andric #else
620b57cec5SDimitry Andric   free(__p);
63e8d8bef9SDimitry Andric #endif
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric #endif
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric #endif /* __MM_MALLOC_H */
68