| // SPDX-License-Identifier: GPL-2.0 |
| #ifndef __BITOPS_H__ |
| #define __BITOPS_H__ |
| |
| /* |
| * fls: find last bit set. |
| */ |
| |
| #ifndef HAVE_FLS |
| static inline int fls(int x) |
| { |
| int r = 32; |
| |
| if (!x) |
| return 0; |
| if (!(x & 0xffff0000u)) { |
| x = (x & 0xffffu) << 16; |
| r -= 16; |
| } |
| if (!(x & 0xff000000u)) { |
| x = (x & 0xffffffu) << 8; |
| r -= 8; |
| } |
| if (!(x & 0xf0000000u)) { |
| x = (x & 0xfffffffu) << 4; |
| r -= 4; |
| } |
| if (!(x & 0xc0000000u)) { |
| x = (x & 0x3fffffffu) << 2; |
| r -= 2; |
| } |
| if (!(x & 0x80000000u)) { |
| r -= 1; |
| } |
| return r; |
| } |
| #endif /* HAVE_FLS */ |
| |
| static inline int fls64(__u64 x) |
| { |
| __u32 h = x >> 32; |
| if (h) |
| return fls(h) + 32; |
| return fls(x); |
| } |
| |
| static inline unsigned fls_long(unsigned long l) |
| { |
| if (sizeof(l) == 4) |
| return fls(l); |
| return fls64(l); |
| } |
| |
| /* |
| * ffz: find first zero bit. |
| * Result is undefined if no zero bit exists. |
| */ |
| #define ffz(x) ffs(~(x)) |
| |
| /* |
| * XFS bit manipulation routines. Repeated here so that some programs |
| * don't have to link in all of libxfs just to have bit manipulation. |
| */ |
| |
| /* |
| * masks with n high/low bits set, 64-bit values |
| */ |
| static inline uint64_t mask64hi(int n) |
| { |
| return (uint64_t)-1 << (64 - (n)); |
| } |
| static inline uint32_t mask32lo(int n) |
| { |
| return ((uint32_t)1 << (n)) - 1; |
| } |
| static inline uint64_t mask64lo(int n) |
| { |
| return ((uint64_t)1 << (n)) - 1; |
| } |
| |
| /* Get high bit set out of 32-bit argument, -1 if none set */ |
| static inline int highbit32(uint32_t v) |
| { |
| return fls(v) - 1; |
| } |
| |
| /* Get high bit set out of 64-bit argument, -1 if none set */ |
| static inline int highbit64(uint64_t v) |
| { |
| return fls64(v) - 1; |
| } |
| |
| /* Get low bit set out of 32-bit argument, -1 if none set */ |
| static inline int lowbit32(uint32_t v) |
| { |
| return ffs(v) - 1; |
| } |
| |
| /* Get low bit set out of 64-bit argument, -1 if none set */ |
| static inline int lowbit64(uint64_t v) |
| { |
| uint32_t w = (uint32_t)v; |
| int n = 0; |
| |
| if (w) { /* lower bits */ |
| n = ffs(w); |
| } else { /* upper bits */ |
| w = (uint32_t)(v >> 32); |
| if (w) { |
| n = ffs(w); |
| if (n) |
| n += 32; |
| } |
| } |
| return n - 1; |
| } |
| |
| #endif |