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)31static 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)53static 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(). Leverage find_lsb_set() 61 * by first clearing all but the lowest set bit. 62 */ 63 64 op = op ^ (op & (op - 1)); 65 66 return find_msb_set(op); 67 #endif /* CONFIG_TOOLCHAIN_HAS_BUILTIN_FFS */ 68 } 69 70 #ifdef __cplusplus 71 } 72 #endif 73 74 #endif /* _ASMLANGUAGE */ 75 76 #endif /* ZEPHYR_INCLUDE_ARCH_COMMON_FFS_H_ */ 77