ic-macros  0.1.5
util.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2014, Wind River Systems, Inc.
3  * Copyright (c) 2023, Intercreate, Inc.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #pragma once
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #include <stdbool.h>
15 #include <stddef.h>
16 #include <stdint.h>
17 #include <tgmath.h>
18 
20 #include "ic_macros/assert_type.h"
22 #include "zephyr/build_assert.h"
23 
25 #define _IC_MAKE_SINGLE_EVAL_1(macro, arg1) \
26  __builtin_constant_p(arg1) ? macro(arg1) : ({ \
27  __auto_type const _##macro##_1_ = (arg1); \
28  macro(_##macro##_1_); \
29  })
30 
32 #define _IC_MAKE_SINGLE_EVAL_2(macro, arg1, arg2) \
33  __builtin_constant_p(arg1) && __builtin_constant_p(arg2) ? macro(arg1, arg2) : ({ \
34  __auto_type const _##macro##_1_ = (arg1); \
35  __auto_type const _##macro##_2_ = (arg2); \
36  macro(_##macro##_1_, _##macro##_2_); \
37  })
38 
40 #define _IC_MAKE_SINGLE_EVAL_3(macro, arg1, arg2, arg3) \
41  __builtin_constant_p(arg1) && __builtin_constant_p(arg2) && __builtin_constant_p(arg3) \
42  ? macro(arg1, arg2, arg3) \
43  : ({ \
44  __auto_type const _##macro##_1_ = (arg1); \
45  __auto_type const _##macro##_2_ = (arg2); \
46  __auto_type const _##macro##_3_ = (arg3); \
47  macro(_##macro##_1_, _##macro##_2_, _##macro##_3_); \
48  })
49 
50 
52 #define IC_NUM_BITS(t) (sizeof(t) * 8)
53 
55 #define IC_POINTER_TO_UINT(x) ((uintptr_t) (x))
57 #define IC_UINT_TO_POINTER(x) ((void *) (uintptr_t) (x))
59 #define IC_POINTER_TO_INT(x) ((intptr_t) (x))
61 #define IC_INT_TO_POINTER(x) ((void *) (intptr_t) (x))
62 
67 #define IC_GENMASK32(h, l) (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (32UL - 1 - (h))))
68 
73 #define IC_GENMASK64(h, l) (((~0ULL) - (1ULL << (l)) + 1) & (~0ULL >> (64ULL - 1 - (h))))
74 
75 
77 #define IC_G_LSB_GET(value) ((value) & -(value))
78 
80 #define IC_LSB_GET(value) _IC_MAKE_SINGLE_EVAL_1(value)
81 
86 #define IC_G_FIELD_GET(mask, value) (((value) & (mask)) / IC_LSB_GET(mask))
87 
92 #define IC_FIELD_GET(mask, value) _IC_MAKE_SINGLE_EVAL_2(IC_G_FIELD_GET, mask, value)
93 
99 #define IC_G_FIELD_PREP(mask, value) (((value) * IC_LSB_GET(mask)) & (mask))
100 
106 #define IC_FIELD_PREP(mask, value) _IC_MAKE_SINGLE_EVAL_2(IC_G_FIELD_PREP, mask, value)
107 
109 #define IC_ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
110 
111 #if !defined(__cplusplus)
117 # define _IC_IS_ARRAY(array) \
118  IC_ZERO_OR_COMPILE_ERROR( \
119  !__builtin_types_compatible_p(__typeof__(array), __typeof__(&(array)[0])) \
120  )
121 
130 # define IC_ARRAY_LENGTH(array) \
131  (unsigned int) (_IC_IS_ARRAY(array) + (sizeof(array) / sizeof((array)[0])))
132 
141 # define IC_ARRAY_SIZE(array) (size_t)(_IC_IS_ARRAY(array) + sizeof(array))
142 
143 #endif /* not __cplusplus */
144 
159 #define IC_IS_ARRAY_ELEMENT(array, ptr) \
160  ((ptr) && IC_POINTER_TO_UINT(array) <= IC_POINTER_TO_UINT(ptr) \
161  && IC_POINTER_TO_UINT(ptr) < IC_POINTER_TO_UINT(&(array)[IC_ARRAY_LENGTH(array)]) \
162  && (IC_POINTER_TO_UINT(ptr) - IC_POINTER_TO_UINT(array)) % sizeof((array)[0]) == 0)
163 
178 #define IC_ARRAY_INDEX(array, ptr) \
179  IC_IS_ARRAY_ELEMENT(array, ptr) ? (__typeof__((array)[0]) *) (ptr) - (array) : -1
180 
191 #define IC_PART_OF_ARRAY(array, ptr) \
192  ((ptr) && IC_POINTER_TO_UINT(array) <= IC_POINTER_TO_UINT(ptr) \
193  && IC_POINTER_TO_UINT(ptr) < IC_POINTER_TO_UINT(&(array)[IC_ARRAY_LENGTH(array)]))
194 
212 #define IC_ARRAY_INDEX_FLOOR(array, ptr) \
213  IC_PART_OF_ARRAY(array, ptr) \
214  ? (IC_POINTER_TO_UINT(ptr) - IC_POINTER_TO_UINT(array)) / sizeof((array)[0]) : -1
215 
223 #define IC_SAME_TYPE(a, b) __builtin_types_compatible_p(__typeof__(a), __typeof__(b))
224 
225 #ifndef __cplusplus
229 # define _IC_CONTAINER_OF_VALIDATE(ptr, type, field) \
230  IC_BUILD_ASSERT( \
231  IC_SAME_TYPE(*(ptr), ((type *) 0)->field) || IC_SAME_TYPE(*(ptr), void), \
232  "pointer type mismatch in IC_CONTAINER_OF" \
233  );
234 #else
235 # define _IC_CONTAINER_OF_VALIDATE(ptr, type, field)
236 #endif
237 
259 #define IC_CONTAINER_OF(ptr, type, field) \
260  ({ \
261  _IC_CONTAINER_OF_VALIDATE(ptr, type, field) \
262  ((type *) (((char *) (ptr)) - offsetof(type, field))); \
263  })
264 
271 #define IC_G_IROUND_UP(x, align) \
272  ((((unsigned long) (x) + ((unsigned long) (align) -1)) / (unsigned long) (align)) \
273  * (unsigned long) (align))
274 
280 #define IC_IROUND_UP(x, align) _IC_MAKE_SINGLE_EVAL_2(IC_G_IROUND_UP, x, align)
281 
288 #define IC_G_IROUND_DOWN(x, align) \
289  (((unsigned long) (x) / (unsigned long) (align)) * (unsigned long) (align));
290 
296 #define IC_IROUND_DOWN(x, align) _IC_MAKE_SINGLE_EVAL_2(IC_IROUND_DOWN, x, align)
297 
299 #define IC_WB_UP(x) IC_IROUND_UP(x, sizeof(void *))
300 
302 #define IC_WB_DN(x) IC_IROUND_DOWN(x, sizeof(void *))
303 
304 
313 #define IC_G_CEIL(x) ceil(x)
314 
325 #define IC_CEIL(x) \
326  ({ \
327  IC_BUILD_ASSERT( \
328  IC_SAME_TYPE(x, float) || IC_SAME_TYPE(x, double) || IC_SAME_TYPE(x, long double), \
329  "Argument must be a floating point number!" \
330  ); \
331  /* use <tgmath.h> */ \
332  IC_REQUIRE_CONSTANT(ceil(x)); \
333  })
334 
345 #define IC_G_FLOOR(x) floor(x)
346 
356 #define IC_FLOOR(x) \
357  ({ \
358  IC_BUILD_ASSERT( \
359  IC_SAME_TYPE(x, float) || IC_SAME_TYPE(x, double) || IC_SAME_TYPE(x, long double), \
360  "Argument must be a floating point number!" \
361  ); \
362  /* use <tgmath.h> */ \
363  IC_REQUIRE_CONSTANT(floor(x)); \
364  })
365 
375 #define IC_G_ROUND(x) (__typeof__(x)) (int64_t) ((x) + ((x) >= 0 ? 0.5 : -0.5))
376 
388 #define IC_ROUND(x) \
389  ({ \
390  IC_BUILD_ASSERT( \
391  IC_SAME_TYPE(x, float) || IC_SAME_TYPE(x, double) || IC_SAME_TYPE(x, long double), \
392  "Argument must be a floating point number!" \
393  ); /* unclear that ARM's <tgmath.h> implements round() */ \
394  IC_BUILD_ASSERT((x) >= INT64_MIN || (x) <= INT64_MAX); \
395  IC_REQUIRE_CONSTANT(IC_G_ROUND(x)); \
396  })
397 
412 #define IC_G_DIV_ROUND_UP(n, d) (((n) + (d) -1) / (d))
413 
430 #define IC_DIV_ROUND_UP(n, d) _IC_MAKE_SINGLE_EVAL_2(IC_G_DIV_ROUND_UP, n, d)
431 
447 #define IC_G_DIV_ROUND_CLOSEST(n, d) \
448  ((((n) < 0) ^ ((d) < 0)) ? ((n) - ((d) / 2)) / (d) : ((n) + ((d) / 2)) / (d))
449 
467 #define IC_DIV_ROUND_CLOSEST(n, d) _IC_MAKE_SINGLE_EVAL_2(IC_G_DIV_ROUND_CLOSEST, n, d)
468 
477 #define IC_G_MAX(a, b) (((a) > (b)) ? (a) : (b))
478 
489 #define IC_MAX(a, b) _IC_MAKE_SINGLE_EVAL_2(IC_G_MAX, a, b)
490 
491 
500 #define IC_G_MIN(a, b) (((a) < (b)) ? (a) : (b))
501 
512 #define IC_MIN(a, b) _IC_MAKE_SINGLE_EVAL_2(IC_G_MIN, a, b)
513 
523 #define IC_G_CLAMP(val, low, high) (((val) <= (low)) ? (low) : IC_MIN(val, high))
524 
536 #define IC_CLAMP(val, low, high) _IC_MAKE_SINGLE_EVAL_3(IC_G_CLAMP, val, low, high)
537 
548 #define IC_G_IN_RANGE(val, min, max) \
549  ((__typeof__(val)) -1) > 0 ? ((val) <= (max)) : ((val) >= (min) && (val) <= (max))
550 
563 #define IC_IN_RANGE(val, min, max) _IC_MAKE_SINGLE_EVAL_3(IC_G_IN_RANGE, val, min, max)
564 
572 #define IC_G_ILOG2(x) \
573  (sizeof(__typeof__(x)) > 4 ? (64 - __builtin_clzll(x) - 1) : (32 - __builtin_clz(x) - 1))
574 
582 #define IC_ILOG2(x) \
583  __builtin_constant_p(x) ? IC_G_ILOG2(x) : ({ \
584  __auto_type const _ic_z_ilog2_x_ = (IC_Z_REQUIRE_UINT(x)); \
585  _ic_z_ilog2_x_ < 1 ? -1 : IC_G_ILOG2(_ic_z_ilog2_x_); \
586  })
587 
595 #define IC_G_LOG2CEIL(x) (x) < 1 ? 0 : IC_G_ILOG2((x) -1) + 1
596 
604 #define IC_LOG2CEIL(x) _IC_MAKE_SINGLE_EVAL_1(IC_G_LOG2CEIL, x)
605 
615 #define IC_G_NHPOT(x) ((x) < 1 ? 1 : ((x) > (1ULL << 63) ? 0 : 1ULL << IC_G_LOG2CEIL(x)))
616 
629 #define IC_NHPOT(x) _IC_MAKE_SINGLE_EVAL_1(IC_G_NHPOT, x)
630 
637 #define IC_G_POW2_CEIL(x) ((x) <= 2UL ? (x) : (1UL << (8 * sizeof(long) - __builtin_clzl((x) -1))))
638 
645 #define IC_POW2_CEIL(x) _IC_MAKE_SINGLE_EVAL_1(IC_G_POW2_CEIL, x)
646 
653 #define IC_G_IS_POW2(x) (((x) != 0) && (((x) & ((x) -1)) == 0))
654 
661 #define IC_IS_POW2(x) _IC_MAKE_SINGLE_EVAL_1(IC_G_IS_POW2)
662 
664 #define IC_BIT(n) (1UL << (n))
665 
667 #define IC_BIT64(n) (1ULL << (n))
668 
678 #define IC_G_WRITE_BIT(var, bit, set) (set) ? ((var) | IC_BIT(bit)) : ((var) & ~IC_BIT(bit))
679 
689 #define IC_WRITE_BIT(var, bit, set) _IC_MAKE_SINGLE_EVAL_3(IC_G_WRITE_BIT, var, bit, set)
690 
695 #define IC_BIT_MASK(n) (IC_BIT(n) - 1UL)
696 
701 #define IC_BIT64_MASK(n) (IC_BIT64(n) - 1ULL)
702 
711 #define IC_G_IS_SHIFTED_BIT_MASK(m, s) (!(((m) >> (s)) & (((m) >> (s)) + 1U)))
712 
721 #define IC_IS_SHIFTED_BIT_MASK(m, s) _IC_MAKE_SINGLE_EVAL_2(IC_G_IS_SHIFTED_BIT_MASK, m, s)
722 
728 #define IC_G_IS_BIT_MASK(m) IC_G_IS_SHIFTED_BIT_MASK(m, 0)
729 
735 #define IC_IS_BIT_MASK(m) IC_IS_SHIFTED_BIT_MASK(m, 0)
736 
742 #define IC_G_BSWAP24(x) \
743  (((x) >> 16) & 0x0000FF) | (((x) >> 00) & 0x00FF00) | ((((x) & 0x0000FF) << 16))
744 
750 #define IC_BSWAP24(x) _IC_MAKE_SINGLE_EVAL_1(IC_G_BSWAP24, x)
751 
752 #ifdef __cplusplus
753 }
754 #endif