1 /*
2  * Copyright (c) 2015, Wind River Systems, Inc.
3  * Copyright (c) 2017, Oticon A/S
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #ifndef ZEPHYR_INCLUDE_ARCH_COMMON_FFS_H_
9 #define ZEPHYR_INCLUDE_ARCH_COMMON_FFS_H_
10 
11 #ifndef _ASMLANGUAGE
12 
13 #include <zephyr/types.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  *
21  * @brief find most significant bit set in a 32-bit word
22  *
23  * This routine finds the first bit set starting from the most significant bit
24  * in the argument passed in and returns the index of that bit.  Bits are
25  * numbered starting at 1 from the least significant bit.  A return value of
26  * zero indicates that the value passed is zero.
27  *
28  * @return most significant bit set, 0 if @a op is 0
29  */
30 
find_msb_set(uint32_t op)31 static ALWAYS_INLINE unsigned int find_msb_set(uint32_t op)
32 {
33 	if (op == 0) {
34 		return 0;
35 	}
36 
37 	return 32 - __builtin_clz(op);
38 }
39 
40 
41 /**
42  *
43  * @brief find least significant bit set in a 32-bit word
44  *
45  * This routine finds the first bit set starting from the least significant bit
46  * in the argument passed in and returns the index of that bit.  Bits are
47  * numbered starting at 1 from the least significant bit.  A return value of
48  * zero indicates that the value passed is zero.
49  *
50  * @return least significant bit set, 0 if @a op is 0
51  */
52 
find_lsb_set(uint32_t op)53 static ALWAYS_INLINE unsigned int find_lsb_set(uint32_t op)
54 {
55 #ifdef CONFIG_TOOLCHAIN_HAS_BUILTIN_FFS
56 	return __builtin_ffs(op);
57 
58 #else
59 	/*
60 	 * Toolchain does not have __builtin_ffs().
61 	 * Need to do this manually.
62 	 */
63 	int bit;
64 
65 	if (op == 0) {
66 		return 0;
67 	}
68 
69 	for (bit = 0; bit < 32; bit++) {
70 		if ((op & (1 << bit)) != 0) {
71 			return (bit + 1);
72 		}
73 	}
74 
75 	/*
76 	 * This should never happen but we need to keep
77 	 * compiler happy.
78 	 */
79 	return 0;
80 #endif /* CONFIG_TOOLCHAIN_HAS_BUILTIN_FFS */
81 }
82 
83 #ifdef __cplusplus
84 }
85 #endif
86 
87 #endif /* _ASMLANGUAGE */
88 
89 #endif /* ZEPHYR_INCLUDE_ARCH_COMMON_FFS_H_ */
90