]>
Commit | Line | Data |
---|---|---|
959ef981 | 1 | // SPDX-License-Identifier: GPL-2.0 |
5e656dbb BN |
2 | #ifndef __BITOPS_H__ |
3 | #define __BITOPS_H__ | |
4 | ||
5 | /* | |
6 | * fls: find last bit set. | |
7 | */ | |
8 | ||
5121281b | 9 | #ifndef HAVE_FLS |
5e656dbb BN |
10 | static inline int fls(int x) |
11 | { | |
12 | int r = 32; | |
13 | ||
14 | if (!x) | |
15 | return 0; | |
16 | if (!(x & 0xffff0000u)) { | |
b0e515d6 | 17 | x = (x & 0xffffu) << 16; |
5e656dbb BN |
18 | r -= 16; |
19 | } | |
20 | if (!(x & 0xff000000u)) { | |
b0e515d6 | 21 | x = (x & 0xffffffu) << 8; |
5e656dbb BN |
22 | r -= 8; |
23 | } | |
24 | if (!(x & 0xf0000000u)) { | |
b0e515d6 | 25 | x = (x & 0xfffffffu) << 4; |
5e656dbb BN |
26 | r -= 4; |
27 | } | |
28 | if (!(x & 0xc0000000u)) { | |
b0e515d6 | 29 | x = (x & 0x3fffffffu) << 2; |
5e656dbb BN |
30 | r -= 2; |
31 | } | |
32 | if (!(x & 0x80000000u)) { | |
5e656dbb BN |
33 | r -= 1; |
34 | } | |
35 | return r; | |
36 | } | |
5121281b | 37 | #endif /* HAVE_FLS */ |
5e656dbb BN |
38 | |
39 | static inline int fls64(__u64 x) | |
40 | { | |
41 | __u32 h = x >> 32; | |
42 | if (h) | |
43 | return fls(h) + 32; | |
44 | return fls(x); | |
45 | } | |
46 | ||
47 | static inline unsigned fls_long(unsigned long l) | |
48 | { | |
49 | if (sizeof(l) == 4) | |
50 | return fls(l); | |
51 | return fls64(l); | |
52 | } | |
53 | ||
4071f725 DC |
54 | /* |
55 | * ffz: find first zero bit. | |
56 | * Result is undefined if no zero bit exists. | |
57 | */ | |
58 | #define ffz(x) ffs(~(x)) | |
59 | ||
1ca68d67 DW |
60 | /* |
61 | * XFS bit manipulation routines. Repeated here so that some programs | |
62 | * don't have to link in all of libxfs just to have bit manipulation. | |
63 | */ | |
64 | ||
65 | /* | |
66 | * masks with n high/low bits set, 64-bit values | |
67 | */ | |
68 | static inline uint64_t mask64hi(int n) | |
69 | { | |
70 | return (uint64_t)-1 << (64 - (n)); | |
71 | } | |
72 | static inline uint32_t mask32lo(int n) | |
73 | { | |
74 | return ((uint32_t)1 << (n)) - 1; | |
75 | } | |
76 | static inline uint64_t mask64lo(int n) | |
77 | { | |
78 | return ((uint64_t)1 << (n)) - 1; | |
79 | } | |
80 | ||
81 | /* Get high bit set out of 32-bit argument, -1 if none set */ | |
82 | static inline int highbit32(uint32_t v) | |
83 | { | |
84 | return fls(v) - 1; | |
85 | } | |
86 | ||
87 | /* Get high bit set out of 64-bit argument, -1 if none set */ | |
88 | static inline int highbit64(uint64_t v) | |
89 | { | |
90 | return fls64(v) - 1; | |
91 | } | |
92 | ||
93 | /* Get low bit set out of 32-bit argument, -1 if none set */ | |
94 | static inline int lowbit32(uint32_t v) | |
95 | { | |
96 | return ffs(v) - 1; | |
97 | } | |
98 | ||
99 | /* Get low bit set out of 64-bit argument, -1 if none set */ | |
100 | static inline int lowbit64(uint64_t v) | |
101 | { | |
102 | uint32_t w = (uint32_t)v; | |
103 | int n = 0; | |
104 | ||
105 | if (w) { /* lower bits */ | |
106 | n = ffs(w); | |
107 | } else { /* upper bits */ | |
108 | w = (uint32_t)(v >> 32); | |
109 | if (w) { | |
110 | n = ffs(w); | |
111 | if (n) | |
112 | n += 32; | |
113 | } | |
114 | } | |
115 | return n - 1; | |
116 | } | |
117 | ||
5e656dbb | 118 | #endif |