Line data Source code
1 0 : /* 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 : 31 1 : 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 : 53 1 : 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(). 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_ */