blob: a13e13dd2edf13a4a2dbf73fb727b063303f483f [file] [log] [blame]
/*
* Copyright (C) Igor Sysoev
* Copyright (C) NGINX, Inc.
*/
#ifndef _NJS_CLANG_H_INCLUDED_
#define _NJS_CLANG_H_INCLUDED_
#include <stdarg.h>
#include <stddef.h> /* offsetof(). */
#define njs_inline static inline __attribute__((always_inline))
#define njs_noinline __attribute__((noinline))
#define njs_cdecl
#define njs_container_of(p, type, field) \
(type *) ((u_char *) (p) - offsetof(type, field))
#define njs_nitems(x) \
(sizeof(x) / sizeof((x)[0]))
#define njs_max(val1, val2) \
((val1 < val2) ? (val2) : (val1))
#define njs_min(val1, val2) \
((val1 < val2) ? (val1) : (val2))
#if (NJS_HAVE_BUILTIN_EXPECT)
#define njs_expect(c, x) __builtin_expect((long) (x), (c))
#define njs_fast_path(x) njs_expect(1, x)
#define njs_slow_path(x) njs_expect(0, x)
#else
#define njs_expect(c, x) (x)
#define njs_fast_path(x) (x)
#define njs_slow_path(x) (x)
#endif
#if (NJS_HAVE_BUILTIN_UNREACHABLE)
#define njs_unreachable() __builtin_unreachable()
#else
#define njs_unreachable()
#endif
#if (NJS_HAVE_BUILTIN_PREFETCH)
#define njs_prefetch(a) __builtin_prefetch(a)
#else
#define njs_prefetch(a)
#endif
#if (NJS_HAVE_BUILTIN_CLZ)
#define njs_leading_zeros(x) (((x) == 0) ? 32 : __builtin_clz(x))
#else
njs_inline uint32_t
njs_leading_zeros(uint32_t x)
{
uint32_t n;
/*
* There is no sense to optimize this function, since almost
* all platforms nowadays support the built-in instruction.
*/
if (x == 0) {
return 32;
}
n = 0;
while ((x & 0x80000000) == 0) {
n++;
x <<= 1;
}
return n;
}
#endif
#if (NJS_HAVE_BUILTIN_CLZLL)
#define njs_leading_zeros64(x) (((x) == 0) ? 64 : __builtin_clzll(x))
#else
njs_inline uint64_t
njs_leading_zeros64(uint64_t x)
{
uint64_t n;
/*
* There is no sense to optimize this function, since almost
* all platforms nowadays support the built-in instruction.
*/
if (x == 0) {
return 64;
}
n = 0;
while ((x & 0x8000000000000000) == 0) {
n++;
x <<= 1;
}
return n;
}
#endif
#if (NJS_HAVE_GCC_ATTRIBUTE_VISIBILITY)
#define NJS_EXPORT __attribute__((visibility("default")))
#else
#define NJS_EXPORT
#endif
#if (NJS_HAVE_GCC_ATTRIBUTE_ALIGNED)
#define njs_aligned(x) __attribute__((aligned(x)))
#else
#define njs_aligned(x)
#endif
#if (NJS_HAVE_GCC_ATTRIBUTE_PACKED)
#define NJS_PACKED __attribute__((packed))
#else
#define NJS_PACKED
#endif
#if (NJS_HAVE_GCC_ATTRIBUTE_MALLOC)
#define NJS_MALLOC_LIKE __attribute__((__malloc__))
#else
#define NJS_MALLOC_LIKE
#endif
#if (NJS_CLANG)
/* Any __asm__ directive disables loop vectorization in GCC and Clang. */
#define njs_pragma_loop_disable_vectorization __asm__("")
#else
#define njs_pragma_loop_disable_vectorization
#endif
#define njs_stringify(v) #v
#if (NJS_HAVE_MEMORY_SANITIZER)
#include <sanitizer/msan_interface.h>
#define njs_msan_unpoison(ptr, size) __msan_unpoison(ptr, size)
#else
#define njs_msan_unpoison(ptr, size)
#endif
#if (NJS_HAVE_DENORMALS_CONTROL)
#include <xmmintrin.h>
/*
* 0x8000 Flush to zero
* 0x0040 Denormals are zeros
*/
#define NJS_MM_DENORMALS_MASK 0x8040
#define njs_mm_denormals(on) \
_mm_setcsr((_mm_getcsr() & ~NJS_MM_DENORMALS_MASK) | (!(on) ? 0x8040: 0x0))
#else
#define njs_mm_denormals(on)
#endif
#ifndef NJS_MAX_ALIGNMENT
#if (NJS_SOLARIS)
/* x86_64: 16, i386: 4, sparcv9: 16, sparcv8: 8. */
#define NJS_MAX_ALIGNMENT _MAX_ALIGNMENT
#elif (NJS_WINDOWS)
/* Win64: 16, Win32: 8. */
#define NJS_MAX_ALIGNMENT MEMORY_ALLOCATION_ALIGNMENT
#elif (__amd64__)
#define NJS_MAX_ALIGNMENT 16
#elif (__i386__ || __i386)
#define NJS_MAX_ALIGNMENT 4
#elif (__arm__)
#define NJS_MAX_ALIGNMENT 16
#else
#define NJS_MAX_ALIGNMENT 16
#endif
#endif
#define njs_align_size(size, a) \
(((size) + ((size_t) (a) - 1)) & ~((size_t) (a) - 1))
#define njs_align_ptr(p, a) \
(u_char *) (((uintptr_t) (p) + ((uintptr_t) (a) - 1)) \
& ~((uintptr_t) (a) - 1))
#define njs_trunc_ptr(p, a) \
(u_char *) ((uintptr_t) (p) & ~((uintptr_t) (a) - 1))
#endif /* _NJS_CLANG_H_INCLUDED_ */