1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #ifndef _NJS_CLANG_H_INCLUDED_
8 #define _NJS_CLANG_H_INCLUDED_
9 
10 
11 #include <stdarg.h>
12 #include <stddef.h>       /* offsetof(). */
13 
14 
15 #define njs_inline         static inline __attribute__((always_inline))
16 #define njs_noinline       __attribute__((noinline))
17 #define njs_cdecl
18 
19 
20 #define njs_container_of(p, type, field)                                      \
21     (type *) ((u_char *) (p) - offsetof(type, field))
22 
23 #define njs_nitems(x)                                                         \
24     (sizeof(x) / sizeof((x)[0]))
25 
26 #define njs_max(val1, val2)                                                   \
27     ((val1 < val2) ? (val2) : (val1))
28 
29 #define njs_min(val1, val2)                                                   \
30     ((val1 < val2) ? (val1) : (val2))
31 
32 
33 #if (NJS_HAVE_BUILTIN_EXPECT)
34 #define njs_expect(c, x)   __builtin_expect((long) (x), (c))
35 #define njs_fast_path(x)   njs_expect(1, x)
36 #define njs_slow_path(x)   njs_expect(0, x)
37 
38 #else
39 #define njs_expect(c, x)   (x)
40 #define njs_fast_path(x)   (x)
41 #define njs_slow_path(x)   (x)
42 #endif
43 
44 
45 #if (NJS_HAVE_BUILTIN_UNREACHABLE)
46 #define njs_unreachable()  __builtin_unreachable()
47 
48 #else
49 #define njs_unreachable()
50 #endif
51 
52 
53 #if (NJS_HAVE_BUILTIN_PREFETCH)
54 #define njs_prefetch(a)    __builtin_prefetch(a)
55 
56 #else
57 #define njs_prefetch(a)
58 #endif
59 
60 
61 #if (NJS_HAVE_BUILTIN_CLZ)
62 #define njs_leading_zeros(x)  (((x) == 0) ? 32 : __builtin_clz(x))
63 
64 #else
65 
66 njs_inline uint32_t
njs_leading_zeros(uint32_t x)67 njs_leading_zeros(uint32_t x)
68 {
69     uint32_t  n;
70 
71     /*
72      * There is no sense to optimize this function, since almost
73      * all platforms nowadays support the built-in instruction.
74      */
75 
76     if (x == 0) {
77         return 32;
78     }
79 
80     n = 0;
81 
82     while ((x & 0x80000000) == 0) {
83         n++;
84         x <<= 1;
85     }
86 
87     return n;
88 }
89 
90 #endif
91 
92 
93 #if (NJS_HAVE_BUILTIN_CLZLL)
94 #define njs_leading_zeros64(x)  (((x) == 0) ? 64 : __builtin_clzll(x))
95 
96 #else
97 
98 njs_inline uint64_t
njs_leading_zeros64(uint64_t x)99 njs_leading_zeros64(uint64_t x)
100 {
101     uint64_t  n;
102 
103     /*
104      * There is no sense to optimize this function, since almost
105      * all platforms nowadays support the built-in instruction.
106      */
107 
108     if (x == 0) {
109         return 64;
110     }
111 
112     n = 0;
113 
114     while ((x & 0x8000000000000000) == 0) {
115         n++;
116         x <<= 1;
117     }
118 
119     return n;
120 }
121 
122 #endif
123 
124 
125 #if (NJS_HAVE_GCC_ATTRIBUTE_VISIBILITY)
126 #define NJS_EXPORT         __attribute__((visibility("default")))
127 
128 #else
129 #define NJS_EXPORT
130 #endif
131 
132 
133 #if (NJS_HAVE_GCC_ATTRIBUTE_ALIGNED)
134 #define njs_aligned(x)     __attribute__((aligned(x)))
135 
136 #else
137 #define njs_aligned(x)
138 #endif
139 
140 
141 #if (NJS_HAVE_GCC_ATTRIBUTE_PACKED)
142 #define NJS_PACKED    __attribute__((packed))
143 
144 #else
145 #define NJS_PACKED
146 #endif
147 
148 
149 #if (NJS_HAVE_GCC_ATTRIBUTE_MALLOC)
150 #define NJS_MALLOC_LIKE    __attribute__((__malloc__))
151 
152 #else
153 #define NJS_MALLOC_LIKE
154 #endif
155 
156 
157 #if (NJS_CLANG)
158 /* Any __asm__ directive disables loop vectorization in GCC and Clang. */
159 #define njs_pragma_loop_disable_vectorization  __asm__("")
160 
161 #else
162 #define njs_pragma_loop_disable_vectorization
163 #endif
164 
165 
166 #define njs_stringify(v)    #v
167 
168 
169 #if (NJS_HAVE_MEMORY_SANITIZER)
170 #include <sanitizer/msan_interface.h>
171 
172 #define njs_msan_unpoison(ptr, size)  __msan_unpoison(ptr, size)
173 #else
174 
175 #define njs_msan_unpoison(ptr, size)
176 #endif
177 
178 
179 #if (NJS_HAVE_DENORMALS_CONTROL)
180 #include <xmmintrin.h>
181 
182 /*
183  * 0x8000 Flush to zero
184  * 0x0040 Denormals are zeros
185  */
186 
187 #define NJS_MM_DENORMALS_MASK 0x8040
188 
189 #define njs_mm_denormals(on)                                                  \
190     _mm_setcsr((_mm_getcsr() & ~NJS_MM_DENORMALS_MASK) | (!(on) ? 0x8040: 0x0))
191 #else
192 
193 #define njs_mm_denormals(on)
194 #endif
195 
196 
197 #ifndef NJS_MAX_ALIGNMENT
198 
199 #if (NJS_SOLARIS)
200 /* x86_64: 16, i386: 4, sparcv9: 16, sparcv8: 8. */
201 #define NJS_MAX_ALIGNMENT  _MAX_ALIGNMENT
202 
203 #elif (NJS_WINDOWS)
204 /* Win64: 16, Win32: 8. */
205 #define NJS_MAX_ALIGNMENT  MEMORY_ALLOCATION_ALIGNMENT
206 
207 #elif (__amd64__)
208 #define NJS_MAX_ALIGNMENT  16
209 
210 #elif (__i386__ || __i386)
211 #define NJS_MAX_ALIGNMENT  4
212 
213 #elif (__arm__)
214 #define NJS_MAX_ALIGNMENT  16
215 
216 #else
217 #define NJS_MAX_ALIGNMENT  16
218 #endif
219 
220 #endif
221 
222 
223 #define njs_align_size(size, a)                                               \
224     (((size) + ((size_t) (a) - 1)) & ~((size_t) (a) - 1))
225 
226 
227 #define njs_align_ptr(p, a)                                                   \
228     (u_char *) (((uintptr_t) (p) + ((uintptr_t) (a) - 1))                     \
229                  & ~((uintptr_t) (a) - 1))
230 
231 #define njs_trunc_ptr(p, a)                                                   \
232     (u_char *) ((uintptr_t) (p) & ~((uintptr_t) (a) - 1))
233 
234 
235 #endif /* _NJS_CLANG_H_INCLUDED_ */
236