blob: fbb2a21c6b9913da2eddf91c6be71566954e2957 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/*
16 Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
17
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
25
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
28
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36*/
37
38#ifndef included_clib_h
39#define included_clib_h
40
41/* Standalone means to not assume we are running on a Unix box. */
42#if ! defined (CLIB_STANDALONE) && ! defined (CLIB_LINUX_KERNEL)
43#define CLIB_UNIX
44#endif
45
46#include <vppinfra/types.h>
47
48/* Global DEBUG flag. Setting this to 1 or 0 turns off
49 ASSERT (see vppinfra/error.h) & other debugging code. */
50#ifndef CLIB_DEBUG
51#define CLIB_DEBUG 0
52#endif
53
54#ifndef NULL
55#define NULL ((void *) 0)
56#endif
57
58#define BITS(x) (8*sizeof(x))
59#define ARRAY_LEN(x) (sizeof (x)/sizeof (x[0]))
60
61#define _STRUCT_FIELD(t,f) (((t *) 0)->f)
62#define STRUCT_OFFSET_OF(t,f) ((uword) & _STRUCT_FIELD (t, f))
63#define STRUCT_BIT_OFFSET_OF(t,f) (BITS(u8) * (uword) & _STRUCT_FIELD (t, f))
64#define STRUCT_SIZE_OF(t,f) (sizeof (_STRUCT_FIELD (t, f)))
65#define STRUCT_BITS_OF(t,f) (BITS (_STRUCT_FIELD (t, f)))
66#define STRUCT_ARRAY_LEN(t,f) ARRAY_LEN (_STRUCT_FIELD (t, f))
Dave Barachdbf19ca2016-03-15 10:21:54 +010067#define STRUCT_MARK(mark) u8 mark[0]
68#define STRUCT_MARK_PTR(v, f) &(v)->f
Ed Warnickecb9cada2015-12-08 15:45:58 -070069
70/* Stride in bytes between struct array elements. */
71#define STRUCT_STRIDE_OF(t,f) \
72 ( ((uword) & (((t *) 0)[1].f)) \
73 - ((uword) & (((t *) 0)[0].f)))
74
75#define STRUCT_OFFSET_OF_VAR(v,f) ((uword) (&(v)->f) - (uword) (v))
76
77/* Used to pack structure elements. */
78#define CLIB_PACKED(x) x __attribute__ ((packed))
Dave Barachc3799992016-08-15 11:12:27 -040079#define CLIB_UNUSED(x) x __attribute__ ((unused))
Ed Warnickecb9cada2015-12-08 15:45:58 -070080
81#define never_inline __attribute__ ((__noinline__))
82
83#if CLIB_DEBUG > 0
84#define always_inline static inline
85#define static_always_inline static inline
86#else
87#define always_inline static inline __attribute__ ((__always_inline__))
88#define static_always_inline static inline __attribute__ ((__always_inline__))
89#endif
90
91
92/* Reserved (unused) structure element with address offset between
93 from and to. */
94#define CLIB_PAD_FROM_TO(from,to) u8 pad_##from[(to) - (from)]
95
96/* Hints to compiler about hot/cold code. */
97#define PREDICT_FALSE(x) __builtin_expect((x),0)
98#define PREDICT_TRUE(x) __builtin_expect((x),1)
99
100/* Full memory barrier (read and write). */
101#define CLIB_MEMORY_BARRIER() __sync_synchronize ()
102
Damjan Marioneaabe072017-03-22 10:18:13 +0100103#if __x86_64__
104#define CLIB_MEMORY_STORE_BARRIER() __builtin_ia32_sfence ()
105#else
106#define CLIB_MEMORY_STORE_BARRIER() __sync_synchronize ()
107#endif
108
Ed Warnickecb9cada2015-12-08 15:45:58 -0700109/* Arranges for function to be called before main. */
110#define INIT_FUNCTION(decl) \
111 decl __attribute ((constructor)); \
112 decl
113
114/* Arranges for function to be called before exit. */
115#define EXIT_FUNCTION(decl) \
116 decl __attribute ((destructor)); \
117 decl
118
119/* Use __builtin_clz if available. */
120#ifdef __GNUC__
121#include <features.h>
122#if __GNUC_PREREQ(3, 4)
123#if uword_bits == 64
124#define count_leading_zeros(count,x) count = __builtin_clzll (x)
125#define count_trailing_zeros(count,x) count = __builtin_ctzll (x)
126#else
127#define count_leading_zeros(count,x) count = __builtin_clzl (x)
128#define count_trailing_zeros(count,x) count = __builtin_ctzl (x)
129#endif
130#endif
131#endif
132
133#ifndef count_leading_zeros
134
135/* Misc. integer arithmetic functions. */
136#if defined (i386)
137#define count_leading_zeros(count, x) \
138 do { \
139 word _clz; \
140 __asm__ ("bsrl %1,%0" \
141 : "=r" (_clz) : "rm" ((word) (x)));\
142 (count) = _clz ^ 31; \
143 } while (0)
144
145#define count_trailing_zeros(count, x) \
146 __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((word)(x)))
147#endif /* i386 */
148
149#if defined (__alpha__) && defined (HAVE_CIX)
150#define count_leading_zeros(count, x) \
151 __asm__ ("ctlz %1,%0" \
152 : "=r" ((word) (count)) \
153 : "r" ((word) (x)))
154#define count_trailing_zeros(count, x) \
155 __asm__ ("cttz %1,%0" \
156 : "=r" ((word) (count)) \
157 : "r" ((word) (x)))
158#endif /* alpha && HAVE_CIX */
159
160#if __mips >= 4
161
162/* Select between 32/64 opcodes. */
163#if uword_bits == 32
164#define count_leading_zeros(_count, _x) \
165 __asm__ ("clz %[count],%[x]" \
166 : [count] "=r" ((word) (_count)) \
167 : [x] "r" ((word) (_x)))
168#else
169#define count_leading_zeros(_count, _x) \
170 __asm__ ("dclz %[count],%[x]" \
171 : [count] "=r" ((word) (_count)) \
172 : [x] "r" ((word) (_x)))
173#endif
174
175#endif /* __mips >= 4 */
176
177#endif /* count_leading_zeros */
178
179#if defined (count_leading_zeros)
Dave Barachc3799992016-08-15 11:12:27 -0400180always_inline uword
181min_log2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700182{
183 uword n;
184 count_leading_zeros (n, x);
185 return BITS (uword) - n - 1;
186}
187#else
Dave Barachc3799992016-08-15 11:12:27 -0400188always_inline uword
189min_log2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700190{
Dave Barachc3799992016-08-15 11:12:27 -0400191 uword a = x, b = BITS (uword) / 2, c = 0, r = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700192
193 /* Reduce x to 4 bit result. */
194#define _ \
195{ \
196 c = a >> b; \
197 if (c) a = c; \
198 if (c) r += b; \
199 b /= 2; \
200}
201
Dave Barachc3799992016-08-15 11:12:27 -0400202 if (BITS (uword) > 32)
203 _;
204 _;
205 _;
206 _;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700207#undef _
208
209 /* Do table lookup on 4 bit partial. */
210 if (BITS (uword) > 32)
211 {
212 const u64 table = 0x3333333322221104LL;
Dave Barachc3799992016-08-15 11:12:27 -0400213 uword t = (table >> (4 * a)) & 0xf;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700214 r = t < 4 ? r + t : ~0;
215 }
216 else
217 {
218 const u32 table = 0x22221104;
Dave Barachc3799992016-08-15 11:12:27 -0400219 uword t = (a & 8) ? 3 : ((table >> (4 * a)) & 0xf);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700220 r = t < 4 ? r + t : ~0;
Dave Barachc3799992016-08-15 11:12:27 -0400221 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700222
223 return r;
224}
225#endif
226
Dave Barachc3799992016-08-15 11:12:27 -0400227always_inline uword
228max_log2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700229{
230 uword l = min_log2 (x);
231 if (x > ((uword) 1 << l))
232 l++;
233 return l;
234}
235
Dave Barachc3799992016-08-15 11:12:27 -0400236always_inline u64
237min_log2_u64 (u64 x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700238{
239 if (BITS (uword) == 64)
240 return min_log2 (x);
241 else
242 {
243 uword l, y;
244 y = x;
245 l = 0;
Dave Barachc3799992016-08-15 11:12:27 -0400246 if (y == 0)
247 {
248 l += 32;
249 x >>= 32;
250 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700251 l += min_log2 (x);
252 return l;
253 }
254}
255
Dave Barachc3799992016-08-15 11:12:27 -0400256always_inline uword
257pow2_mask (uword x)
258{
259 return ((uword) 1 << x) - (uword) 1;
260}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700261
Dave Barachc3799992016-08-15 11:12:27 -0400262always_inline uword
263max_pow2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700264{
265 word y = (word) 1 << min_log2 (x);
Dave Barachc3799992016-08-15 11:12:27 -0400266 if (x > y)
267 y *= 2;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700268 return y;
269}
270
Dave Barachc3799992016-08-15 11:12:27 -0400271always_inline uword
272is_pow2 (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700273{
Dave Barachc3799992016-08-15 11:12:27 -0400274 return 0 == (x & (x - 1));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700275}
276
Dave Barachc3799992016-08-15 11:12:27 -0400277always_inline uword
278round_pow2 (uword x, uword pow2)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700279{
Dave Barachc3799992016-08-15 11:12:27 -0400280 return (x + pow2 - 1) & ~(pow2 - 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700281}
282
Dave Barachc3799992016-08-15 11:12:27 -0400283always_inline u64
284round_pow2_u64 (u64 x, u64 pow2)
285{
286 return (x + pow2 - 1) & ~(pow2 - 1);
287}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700288
Dave Barachc3799992016-08-15 11:12:27 -0400289always_inline uword
290first_set (uword x)
291{
292 return x & -x;
293}
294
295always_inline uword
296log2_first_set (uword x)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700297{
298 uword result;
299#ifdef count_trailing_zeros
300 count_trailing_zeros (result, x);
301#else
302 result = min_log2 (first_set (x));
303#endif
304 return result;
305}
306
Dave Barachc3799992016-08-15 11:12:27 -0400307always_inline f64
308flt_round_down (f64 x)
309{
310 return (int) x;
311}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700312
Dave Barachc3799992016-08-15 11:12:27 -0400313always_inline word
314flt_round_nearest (f64 x)
315{
316 return (word) (x + .5);
317}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700318
Dave Barachc3799992016-08-15 11:12:27 -0400319always_inline f64
320flt_round_to_multiple (f64 x, f64 f)
321{
322 return f * flt_round_nearest (x / f);
323}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700324
325#define clib_max(x,y) \
326({ \
327 __typeof__ (x) _x = (x); \
328 __typeof__ (y) _y = (y); \
329 _x > _y ? _x : _y; \
330})
331
332#define clib_min(x,y) \
333({ \
334 __typeof__ (x) _x = (x); \
335 __typeof__ (y) _y = (y); \
336 _x < _y ? _x : _y; \
337})
338
339#define clib_abs(x) \
340({ \
341 __typeof__ (x) _x = (x); \
342 _x < 0 ? -_x : _x; \
343})
344
345/* Standard standalone-only function declarations. */
346#ifndef CLIB_UNIX
Dave Barachc3799992016-08-15 11:12:27 -0400347void clib_standalone_init (void *memory, uword memory_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700348
Dave Barachc3799992016-08-15 11:12:27 -0400349void qsort (void *base, uword n, uword size,
350 int (*)(const void *, const void *));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700351#endif
352
353/* Stack backtrace. */
354uword
Dave Barachc3799992016-08-15 11:12:27 -0400355clib_backtrace (uword * callers, uword max_callers, uword n_frames_to_skip);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700356
357#endif /* included_clib_h */
Dave Barachc3799992016-08-15 11:12:27 -0400358
359/*
360 * fd.io coding-style-patch-verification: ON
361 *
362 * Local Variables:
363 * eval: (c-set-style "gnu")
364 * End:
365 */