add missing include and improve comments

- Since uint32_t and uint64_t are used, stdint.h needs to be included.
- Improve comments about GCC/LLVM internals.

Co-authored-by: Matthew Brecknell <matthew@brecknell.net>
Signed-off-by: Axel Heider <axelheider@gmx.de>
This commit is contained in:
Axel Heider 2021-09-29 23:35:00 +02:00 committed by Gerwin Klein
parent afc27201d6
commit e542a2a0ea

View file

@ -135,10 +135,28 @@ int PURE strncmp(const char *s1, const char *s2, int n);
long CONST char_to_long(char c);
long PURE str_to_long(const char *str);
// Library functions for counting leading/trailing zeros.
// GCC's builtins will emit calls to these functions when the platform
// does not provide suitable inline assembly.
// We only emit function definitions if CONFIG_CLZL_IMPL etc are set.
/* Library functions for counting leading/trailing zeros.
*
* GCC/LLVM provides builtin function like __builtin_clzl() for this, which
* either get translated to machine specific instructions or calls helper
* functions like __clzsi2() that a compiler library is expected to implement.
* At the time of writing this comment, the GCC documentation about the compiler
* library (https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html)
* is not very detailed and the signatures given for these helper functions
* appear incorrect. For example, is says "int __clzsi2(unsigned int a)", but
* both the GCC and LLVM libraries implement it in a way that is independent of
* the implementation choices for the sizes of `unsigned int`. Instead, it
* appears that `si` always signifies a 32-bit argument and `di` always
* signifies a 64-bit argument. Tests with __builtin_clzl() on RISC-V have shown
* that if 'unsigned long' is 32 bits __builtin_clzl() uses __clzsi2() and if
* the type is 64 bits __builtin_clzl() uses __clzdi2(). Thus using the types
* uint32_t and uint64_t from stdint.h in the signatures below is considered the
* semantically correct way.
* Note that we only emit actual function implementations for these functions if
* CONFIG_CLZ_32 etc. are set. Otherwise, the compiler's internal implementation
* may get used or compilation fails if there is no machine instruction.
*/
#include <stdint.h>
CONST int __clzsi2(uint32_t x);
CONST int __clzdi2(uint64_t x);
CONST int __ctzsi2(uint32_t x);