Line data Source code
1 1 : /*
2 : * Copyright (c) 2021 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_MATH_ILOG2_H_
8 : #define ZEPHYR_INCLUDE_MATH_ILOG2_H_
9 :
10 : #include <stdint.h>
11 :
12 : #include <zephyr/toolchain.h>
13 : #include <zephyr/arch/common/ffs.h>
14 : #include <zephyr/sys/util.h>
15 :
16 : /**
17 : * @file
18 : * @brief Provide ilog2() function
19 : */
20 :
21 : /**
22 : * @defgroup math_ilog2 Math Ilog2 Functions
23 : * @ingroup utilities
24 : * @brief Integer log2 utilities for mathematical operations
25 : * @{
26 : */
27 :
28 : /**
29 : *
30 : * @brief Calculate the floor of log2 for compile time constant
31 : *
32 : * This calculates the floor of log2 (integer log2) for 32-bit
33 : * unsigned integer.
34 : *
35 : * @note This should only be used for compile time constant
36 : * when value is known during preprocessing stage.
37 : * DO NOT USE for runtime code due to the big tree of
38 : * nested if-else blocks.
39 : *
40 : * @warning Will return 0 if input value is 0, which is
41 : * invalid for log2.
42 : *
43 : * @param n Input value
44 : * @return Integer log2 of @n
45 : */
46 1 : #define ilog2_compile_time_const_u32(n) \
47 : ( \
48 : ((n) < 2) ? 0 : \
49 : (((n) & BIT(31)) == BIT(31)) ? 31 : \
50 : (((n) & BIT(30)) == BIT(30)) ? 30 : \
51 : (((n) & BIT(29)) == BIT(29)) ? 29 : \
52 : (((n) & BIT(28)) == BIT(28)) ? 28 : \
53 : (((n) & BIT(27)) == BIT(27)) ? 27 : \
54 : (((n) & BIT(26)) == BIT(26)) ? 26 : \
55 : (((n) & BIT(25)) == BIT(25)) ? 25 : \
56 : (((n) & BIT(24)) == BIT(24)) ? 24 : \
57 : (((n) & BIT(23)) == BIT(23)) ? 23 : \
58 : (((n) & BIT(22)) == BIT(22)) ? 22 : \
59 : (((n) & BIT(21)) == BIT(21)) ? 21 : \
60 : (((n) & BIT(20)) == BIT(20)) ? 20 : \
61 : (((n) & BIT(19)) == BIT(19)) ? 19 : \
62 : (((n) & BIT(18)) == BIT(18)) ? 18 : \
63 : (((n) & BIT(17)) == BIT(17)) ? 17 : \
64 : (((n) & BIT(16)) == BIT(16)) ? 16 : \
65 : (((n) & BIT(15)) == BIT(15)) ? 15 : \
66 : (((n) & BIT(14)) == BIT(14)) ? 14 : \
67 : (((n) & BIT(13)) == BIT(13)) ? 13 : \
68 : (((n) & BIT(12)) == BIT(12)) ? 12 : \
69 : (((n) & BIT(11)) == BIT(11)) ? 11 : \
70 : (((n) & BIT(10)) == BIT(10)) ? 10 : \
71 : (((n) & BIT(9)) == BIT(9)) ? 9 : \
72 : (((n) & BIT(8)) == BIT(8)) ? 8 : \
73 : (((n) & BIT(7)) == BIT(7)) ? 7 : \
74 : (((n) & BIT(6)) == BIT(6)) ? 6 : \
75 : (((n) & BIT(5)) == BIT(5)) ? 5 : \
76 : (((n) & BIT(4)) == BIT(4)) ? 4 : \
77 : (((n) & BIT(3)) == BIT(3)) ? 3 : \
78 : (((n) & BIT(2)) == BIT(2)) ? 2 : \
79 : 1 \
80 : )
81 :
82 : /**
83 : *
84 : * @brief Calculate integer log2
85 : *
86 : * This calculates the floor of log2 (integer of log2).
87 : *
88 : * @warning Will return 0 if input value is 0, which is
89 : * invalid for log2.
90 : *
91 : * @param n Input value
92 : * @return Integer log2 of @p n
93 : */
94 : /*
95 : * This is in #define form as this needs to also work on
96 : * compile time constants. Doing this as a static inline
97 : * function will result in compiler complaining with
98 : * "initializer element is not constant".
99 : */
100 1 : #define ilog2(n) \
101 : ( \
102 : __builtin_constant_p(n) ? \
103 : ilog2_compile_time_const_u32(n) : \
104 : find_msb_set(n) - 1 \
105 : )
106 :
107 : /**
108 : * @}
109 : */
110 :
111 : #endif /* ZEPHYR_INCLUDE_MATH_ILOG2_H_ */
|