From 783b20712ea0155f1881a6bd0bf8e2717a717db5 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 23 Apr 2021 20:52:38 -0700 Subject: [PATCH] arch: implement brute force find_lsb_set() On RISC-V 64-bit, GCC complains about undefined reference to 'ffs' via __builtin_ffs(). So implement a brute force way to do it. Once the toolchain has __builtin_ffs(), this can be reverted. Signed-off-by: Daniel Leung --- arch/Kconfig | 6 ++++++ include/arch/common/ffs.h | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index f61c284f9e2..21d8b0c85ad 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -955,3 +955,9 @@ config BOARD The Board is the first location where we search for a linker.ld file, if not found we look for the linker file in soc/// + +config TOOLCHAIN_HAS_BUILTIN_FFS + bool + default y if !(64BIT && RISCV) + help + Hidden option to signal that toolchain has __builtin_ffs*(). diff --git a/include/arch/common/ffs.h b/include/arch/common/ffs.h index be934c7069c..11f85659c21 100644 --- a/include/arch/common/ffs.h +++ b/include/arch/common/ffs.h @@ -52,7 +52,32 @@ static ALWAYS_INLINE unsigned int find_msb_set(uint32_t op) static ALWAYS_INLINE unsigned int find_lsb_set(uint32_t op) { +#ifdef CONFIG_TOOLCHAIN_HAS_BUILTIN_FFS return __builtin_ffs(op); + +#else + /* + * Toolchain does not have __builtin_ffs(). + * Need to do this manually. + */ + int bit; + + if (op == 0) { + return 0; + } + + for (bit = 0; bit < 32; bit++) { + if ((op & (1 << bit)) != 0) { + return (bit + 1); + } + } + + /* + * This should never happen but we need to keep + * compiler happy. + */ + return 0; +#endif /* CONFIG_TOOLCHAIN_HAS_BUILTIN_FFS */ } #ifdef __cplusplus