162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _ASM_GENERIC_BITOPS_FLS64_H_
362306a36Sopenharmony_ci#define _ASM_GENERIC_BITOPS_FLS64_H_
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <asm/types.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci/**
862306a36Sopenharmony_ci * fls64 - find last set bit in a 64-bit word
962306a36Sopenharmony_ci * @x: the word to search
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * This is defined in a similar way as the libc and compiler builtin
1262306a36Sopenharmony_ci * ffsll, but returns the position of the most significant set bit.
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci * fls64(value) returns 0 if value is 0 or the position of the last
1562306a36Sopenharmony_ci * set bit if value is nonzero. The last (most significant) bit is
1662306a36Sopenharmony_ci * at position 64.
1762306a36Sopenharmony_ci */
1862306a36Sopenharmony_ci#if BITS_PER_LONG == 32
1962306a36Sopenharmony_cistatic __always_inline int fls64(__u64 x)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	__u32 h = x >> 32;
2262306a36Sopenharmony_ci	if (h)
2362306a36Sopenharmony_ci		return fls(h) + 32;
2462306a36Sopenharmony_ci	return fls(x);
2562306a36Sopenharmony_ci}
2662306a36Sopenharmony_ci#elif BITS_PER_LONG == 64
2762306a36Sopenharmony_cistatic __always_inline int fls64(__u64 x)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	if (x == 0)
3062306a36Sopenharmony_ci		return 0;
3162306a36Sopenharmony_ci	return __fls(x) + 1;
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci#else
3462306a36Sopenharmony_ci#error BITS_PER_LONG not 32 or 64
3562306a36Sopenharmony_ci#endif
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#endif /* _ASM_GENERIC_BITOPS_FLS64_H_ */
38