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