Message ID | 1445700414-28600-2-git-send-email-festevam@gmail.com |
---|---|
State | Superseded |
Delegated to: | Tom Rini |
Headers | show |
Hi Febio, You replaced __always_inline to inline any specific reason? found __always_inline at some parts of header in code. But my compilation is not-smooth with this. On 24 October 2015 at 20:56, Fabio Estevam <festevam@gmail.com> wrote: > From: Fabio Estevam <fabio.estevam@freescale.com> > > Use the generic bitops header files from the kernel. > > Imported from kernel 4.2.3. > > Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> > Reviewed-by: Tom Rini <trini@konsulko.com> > --- > Changes since v1: > - None > > include/asm-generic/bitops/__ffs.h | 43 ++++++++++++++++++++++++++++++++++++++ > include/asm-generic/bitops/__fls.h | 43 ++++++++++++++++++++++++++++++++++++++ > include/asm-generic/bitops/fls.h | 41 ++++++++++++++++++++++++++++++++++++ > include/asm-generic/bitops/fls64.h | 36 +++++++++++++++++++++++++++++++ > include/linux/bitops.h | 26 +++++++++++++++++++++++ > 5 files changed, 189 insertions(+) > create mode 100644 include/asm-generic/bitops/__ffs.h > create mode 100644 include/asm-generic/bitops/__fls.h > create mode 100644 include/asm-generic/bitops/fls.h > create mode 100644 include/asm-generic/bitops/fls64.h > > diff --git a/include/asm-generic/bitops/__ffs.h b/include/asm-generic/bitops/__ffs.h > new file mode 100644 > index 0000000..9a3274a > --- /dev/null > +++ b/include/asm-generic/bitops/__ffs.h > @@ -0,0 +1,43 @@ > +#ifndef _ASM_GENERIC_BITOPS___FFS_H_ > +#define _ASM_GENERIC_BITOPS___FFS_H_ > + > +#include <asm/types.h> > + > +/** > + * __ffs - find first bit in word. > + * @word: The word to search > + * > + * Undefined if no bit exists, so code should check against 0 first. > + */ > +static inline unsigned long __ffs(unsigned long word) > +{ > + int num = 0; > + > +#if BITS_PER_LONG == 64 > + if ((word & 0xffffffff) == 0) { > + num += 32; > + word >>= 32; > + } > +#endif > + if ((word & 0xffff) == 0) { > + num += 16; > + word >>= 16; > + } > + if ((word & 0xff) == 0) { > + num += 8; > + word >>= 8; > + } > + if ((word & 0xf) == 0) { > + num += 4; > + word >>= 4; > + } > + if ((word & 0x3) == 0) { > + num += 2; > + word >>= 2; > + } > + if ((word & 0x1) == 0) > + num += 1; > + return num; > +} > + > +#endif /* _ASM_GENERIC_BITOPS___FFS_H_ */ > diff --git a/include/asm-generic/bitops/__fls.h b/include/asm-generic/bitops/__fls.h > new file mode 100644 > index 0000000..be24465 > --- /dev/null > +++ b/include/asm-generic/bitops/__fls.h > @@ -0,0 +1,43 @@ > +#ifndef _ASM_GENERIC_BITOPS___FLS_H_ > +#define _ASM_GENERIC_BITOPS___FLS_H_ > + > +#include <asm/types.h> > + > +/** > + * __fls - find last (most-significant) set bit in a long word > + * @word: the word to search > + * > + * Undefined if no set bit exists, so code should check against 0 first. > + */ > +static inline unsigned long __fls(unsigned long word) > +{ > + int num = BITS_PER_LONG - 1; > + > +#if BITS_PER_LONG == 64 > + if (!(word & (~0ul << 32))) { > + num -= 32; > + word <<= 32; > + } > +#endif > + if (!(word & (~0ul << (BITS_PER_LONG-16)))) { > + num -= 16; > + word <<= 16; > + } > + if (!(word & (~0ul << (BITS_PER_LONG-8)))) { > + num -= 8; > + word <<= 8; > + } > + if (!(word & (~0ul << (BITS_PER_LONG-4)))) { > + num -= 4; > + word <<= 4; > + } > + if (!(word & (~0ul << (BITS_PER_LONG-2)))) { > + num -= 2; > + word <<= 2; > + } > + if (!(word & (~0ul << (BITS_PER_LONG-1)))) > + num -= 1; > + return num; > +} > + > +#endif /* _ASM_GENERIC_BITOPS___FLS_H_ */ > diff --git a/include/asm-generic/bitops/fls.h b/include/asm-generic/bitops/fls.h > new file mode 100644 > index 0000000..850859b > --- /dev/null > +++ b/include/asm-generic/bitops/fls.h > @@ -0,0 +1,41 @@ > +#ifndef _ASM_GENERIC_BITOPS_FLS_H_ > +#define _ASM_GENERIC_BITOPS_FLS_H_ > + > +/** > + * fls - find last (most-significant) bit set > + * @x: the word to search > + * > + * This is defined the same way as ffs. > + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. > + */ > + > +static inline int fls(int x) > +{ > + int r = 32; > + > + if (!x) > + return 0; > + if (!(x & 0xffff0000u)) { > + x <<= 16; > + r -= 16; > + } > + if (!(x & 0xff000000u)) { > + x <<= 8; > + r -= 8; > + } > + if (!(x & 0xf0000000u)) { > + x <<= 4; > + r -= 4; > + } > + if (!(x & 0xc0000000u)) { > + x <<= 2; > + r -= 2; > + } > + if (!(x & 0x80000000u)) { > + x <<= 1; > + r -= 1; > + } > + return r; > +} > + > +#endif /* _ASM_GENERIC_BITOPS_FLS_H_ */ > diff --git a/include/asm-generic/bitops/fls64.h b/include/asm-generic/bitops/fls64.h > new file mode 100644 > index 0000000..86d403f > --- /dev/null > +++ b/include/asm-generic/bitops/fls64.h > @@ -0,0 +1,36 @@ > +#ifndef _ASM_GENERIC_BITOPS_FLS64_H_ > +#define _ASM_GENERIC_BITOPS_FLS64_H_ > + > +#include <asm/types.h> > + > +/** > + * fls64 - find last set bit in a 64-bit word > + * @x: the word to search > + * > + * This is defined in a similar way as the libc and compiler builtin > + * ffsll, but returns the position of the most significant set bit. > + * > + * fls64(value) returns 0 if value is 0 or the position of the last > + * set bit if value is nonzero. The last (most significant) bit is > + * at position 64. > + */ > +#if BITS_PER_LONG == 32 > +static inline int fls64(__u64 x) > +{ > + __u32 h = x >> 32; > + if (h) > + return fls(h) + 32; > + return fls(x); > +} > +#elif BITS_PER_LONG == 64 > +static inline int fls64(__u64 x) > +{ > + if (x == 0) > + return 0; > + return __fls(x) + 1; > +} > +#else > +#error BITS_PER_LONG not 32 or 64 > +#endif > + > +#endif /* _ASM_GENERIC_BITOPS_FLS64_H_ */ > diff --git a/include/linux/bitops.h b/include/linux/bitops.h > index 7b4011f..57143ac 100644 > --- a/include/linux/bitops.h > +++ b/include/linux/bitops.h > @@ -139,6 +139,32 @@ static inline unsigned int generic_hweight8(unsigned int w) > # define fls generic_fls > #endif > > +static inline unsigned fls_long(unsigned long l) > +{ > + if (sizeof(l) == 4) > + return fls(l); > + return fls64(l); > +} > + > +/** > + * __ffs64 - find first set bit in a 64 bit word > + * @word: The 64 bit word > + * > + * On 64 bit arches this is a synomyn for __ffs > + * The result is not defined if no bits are set, so check that @word > + * is non-zero before calling this. > + */ > +static inline unsigned long __ffs64(u64 word) > +{ > +#if BITS_PER_LONG == 32 > + if (((u32)word) == 0UL) > + return __ffs((u32)(word >> 32)) + 32; > +#elif BITS_PER_LONG != 64 > +#error BITS_PER_LONG not 32 or 64 > +#endif > + return __ffs((unsigned long)word); > +} > + > /** > * __set_bit - Set a bit in memory > * @nr: the bit to set > -- > 1.9.1 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot
On Sun, Oct 25, 2015 at 4:50 AM, Jagan Teki <jteki@openedev.com> wrote: > Hi Febio, > > You replaced __always_inline to inline any specific reason? found > __always_inline at some parts of header in code. But my compilation is > not-smooth with this. Yes, if I use the original __always_inline I get the following when building for ARM: /home/fabio/denx/u-boot/include/asm-generic/bitops/__ffs.h:12:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘un /home/fabio/denx/u-boot/include/asm-generic/bitops/fls.h:12:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before /home/fabio/denx/u-boot/include/asm-generic/bitops/fls64.h:18:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before make[2]: *** [lib/asm-offsets.s] Error 1 make[2]: *** [arch/arm/lib/asm-offsets.s] Error 1 make[1]: *** [prepare0] Error 2 make: *** [sub-make] Error 2 In file included from /home/fabio/denx/u-boot/arch/arm/include/asm/bitops.h:193:0, from /home/fabio/denx/u-boot/include/linux/bitops.h:122, from /home/fabio/denx/u-boot/include/common.h:20, from /home/fabio/denx/u-boot/lib/asm-offsets.c:15: /home/fabio/denx/u-boot/include/asm-generic/bitops/__fls.h:12:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘unsigned’ In file included from /home/fabio/denx/u-boot/arch/arm/include/asm/bitops.h:194:0, from /home/fabio/denx/u-boot/include/linux/bitops.h:122, from /home/fabio/denx/u-boot/include/common.h:20, from /home/fabio/denx/u-boot/arch/arm/lib/asm-offsets.c:15: /home/fabio/denx/u-boot/include/asm-generic/bitops/__ffs.h:12:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘un igned’ In file included from /home/fabio/denx/u-boot/arch/arm/include/asm/bitops.h:195:0, from /home/fabio/denx/u-boot/include/linux/bitops.h:122, from /home/fabio/denx/u-boot/include/common.h:20, from /home/fabio/denx/u-boot/arch/arm/lib/asm-offsets.c:15: /home/fabio/denx/u-boot/include/asm-generic/bitops/fls.h:12:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ��int’ In file included from /home/fabio/denx/u-boot/arch/arm/include/asm/bitops.h:196:0, from /home/fabio/denx/u-boot/include/linux/bitops.h:122, from /home/fabio/denx/u-boot/include/common.h:20, from /home/fabio/denx/u-boot/arch/arm/lib/asm-offsets.c:15: /home/fabio/denx/u-boot/include/asm-generic/bitops/fls64.h:18:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ��int’ In file included from /home/fabio/denx/u-boot/include/common.h:20:0, from /home/fabio/denx/u-boot/lib/asm-offsets.c:15: /home/fabio/denx/u-boot/include/linux/bitops.h: In function ‘fls_long’: /home/fabio/denx/u-boot/include/linux/bitops.h:146:2: warning: implicit declaration of function ‘fls64’ [-Wimplicit-function-declaration] /home/fabio/denx/u-boot/include/linux/bitops.h: In function ‘__ffs64’: /home/fabio/denx/u-boot/include/linux/bitops.h:161:3: warning: implicit declaration of function ‘__ffs’ [-Wimplicit-function-declaration] make[2]: *** [lib/asm-offsets.s] Error 1 make[2]: *** Waiting for unfinished jobs.... make[2]: *** [arch/arm/lib/asm-offsets.s] Error 1 make[1]: *** [prepare0] Error 2 make: *** [sub-make] Error Then I changed to inline after looking at the barebox source code.
Hi Jagan, On Sun, Oct 25, 2015 at 2:28 PM, Fabio Estevam <festevam@gmail.com> wrote: > On Sun, Oct 25, 2015 at 4:50 AM, Jagan Teki <jteki@openedev.com> wrote: >> Hi Febio, >> >> You replaced __always_inline to inline any specific reason? found >> __always_inline at some parts of header in code. But my compilation is >> not-smooth with this. > > Yes, if I use the original __always_inline I get the following when > building for ARM: Ok, this was caused by a lack of "#include <linux/compiler.h>". Will fix it in v3, thanks.
diff --git a/include/asm-generic/bitops/__ffs.h b/include/asm-generic/bitops/__ffs.h new file mode 100644 index 0000000..9a3274a --- /dev/null +++ b/include/asm-generic/bitops/__ffs.h @@ -0,0 +1,43 @@ +#ifndef _ASM_GENERIC_BITOPS___FFS_H_ +#define _ASM_GENERIC_BITOPS___FFS_H_ + +#include <asm/types.h> + +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + */ +static inline unsigned long __ffs(unsigned long word) +{ + int num = 0; + +#if BITS_PER_LONG == 64 + if ((word & 0xffffffff) == 0) { + num += 32; + word >>= 32; + } +#endif + if ((word & 0xffff) == 0) { + num += 16; + word >>= 16; + } + if ((word & 0xff) == 0) { + num += 8; + word >>= 8; + } + if ((word & 0xf) == 0) { + num += 4; + word >>= 4; + } + if ((word & 0x3) == 0) { + num += 2; + word >>= 2; + } + if ((word & 0x1) == 0) + num += 1; + return num; +} + +#endif /* _ASM_GENERIC_BITOPS___FFS_H_ */ diff --git a/include/asm-generic/bitops/__fls.h b/include/asm-generic/bitops/__fls.h new file mode 100644 index 0000000..be24465 --- /dev/null +++ b/include/asm-generic/bitops/__fls.h @@ -0,0 +1,43 @@ +#ifndef _ASM_GENERIC_BITOPS___FLS_H_ +#define _ASM_GENERIC_BITOPS___FLS_H_ + +#include <asm/types.h> + +/** + * __fls - find last (most-significant) set bit in a long word + * @word: the word to search + * + * Undefined if no set bit exists, so code should check against 0 first. + */ +static inline unsigned long __fls(unsigned long word) +{ + int num = BITS_PER_LONG - 1; + +#if BITS_PER_LONG == 64 + if (!(word & (~0ul << 32))) { + num -= 32; + word <<= 32; + } +#endif + if (!(word & (~0ul << (BITS_PER_LONG-16)))) { + num -= 16; + word <<= 16; + } + if (!(word & (~0ul << (BITS_PER_LONG-8)))) { + num -= 8; + word <<= 8; + } + if (!(word & (~0ul << (BITS_PER_LONG-4)))) { + num -= 4; + word <<= 4; + } + if (!(word & (~0ul << (BITS_PER_LONG-2)))) { + num -= 2; + word <<= 2; + } + if (!(word & (~0ul << (BITS_PER_LONG-1)))) + num -= 1; + return num; +} + +#endif /* _ASM_GENERIC_BITOPS___FLS_H_ */ diff --git a/include/asm-generic/bitops/fls.h b/include/asm-generic/bitops/fls.h new file mode 100644 index 0000000..850859b --- /dev/null +++ b/include/asm-generic/bitops/fls.h @@ -0,0 +1,41 @@ +#ifndef _ASM_GENERIC_BITOPS_FLS_H_ +#define _ASM_GENERIC_BITOPS_FLS_H_ + +/** + * fls - find last (most-significant) bit set + * @x: the word to search + * + * This is defined the same way as ffs. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. + */ + +static inline int fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000u)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xff000000u)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf0000000u)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc0000000u)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000u)) { + x <<= 1; + r -= 1; + } + return r; +} + +#endif /* _ASM_GENERIC_BITOPS_FLS_H_ */ diff --git a/include/asm-generic/bitops/fls64.h b/include/asm-generic/bitops/fls64.h new file mode 100644 index 0000000..86d403f --- /dev/null +++ b/include/asm-generic/bitops/fls64.h @@ -0,0 +1,36 @@ +#ifndef _ASM_GENERIC_BITOPS_FLS64_H_ +#define _ASM_GENERIC_BITOPS_FLS64_H_ + +#include <asm/types.h> + +/** + * fls64 - find last set bit in a 64-bit word + * @x: the word to search + * + * This is defined in a similar way as the libc and compiler builtin + * ffsll, but returns the position of the most significant set bit. + * + * fls64(value) returns 0 if value is 0 or the position of the last + * set bit if value is nonzero. The last (most significant) bit is + * at position 64. + */ +#if BITS_PER_LONG == 32 +static inline int fls64(__u64 x) +{ + __u32 h = x >> 32; + if (h) + return fls(h) + 32; + return fls(x); +} +#elif BITS_PER_LONG == 64 +static inline int fls64(__u64 x) +{ + if (x == 0) + return 0; + return __fls(x) + 1; +} +#else +#error BITS_PER_LONG not 32 or 64 +#endif + +#endif /* _ASM_GENERIC_BITOPS_FLS64_H_ */ diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 7b4011f..57143ac 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -139,6 +139,32 @@ static inline unsigned int generic_hweight8(unsigned int w) # define fls generic_fls #endif +static inline unsigned fls_long(unsigned long l) +{ + if (sizeof(l) == 4) + return fls(l); + return fls64(l); +} + +/** + * __ffs64 - find first set bit in a 64 bit word + * @word: The 64 bit word + * + * On 64 bit arches this is a synomyn for __ffs + * The result is not defined if no bits are set, so check that @word + * is non-zero before calling this. + */ +static inline unsigned long __ffs64(u64 word) +{ +#if BITS_PER_LONG == 32 + if (((u32)word) == 0UL) + return __ffs((u32)(word >> 32)) + 32; +#elif BITS_PER_LONG != 64 +#error BITS_PER_LONG not 32 or 64 +#endif + return __ffs((unsigned long)word); +} + /** * __set_bit - Set a bit in memory * @nr: the bit to set