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