1 /* $OpenBSD: bitops.h,v 1.5 2023/01/01 01:34:58 jsg Exp $ */
2 /*
3 * Copyright (c) 2013, 2014, 2015 Mark Kettenis
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #ifndef _LINUX_BITOPS_H
19 #define _LINUX_BITOPS_H
20
21 #include <sys/types.h>
22 #include <sys/param.h>
23 #include <lib/libkern/libkern.h>
24
25 #include <asm/bitsperlong.h>
26 #include <linux/atomic.h>
27
28 #define BIT(x) (1UL << (x))
29 #define BIT_ULL(x) (1ULL << (x))
30 #define BIT_MASK(x) (1UL << ((x) % BITS_PER_LONG))
31 #define BITS_PER_BYTE 8
32
33 #define GENMASK(h, l) (((~0UL) >> (BITS_PER_LONG - (h) - 1)) & ((~0UL) << (l)))
34 #define GENMASK_ULL(h, l) (((~0ULL) >> (BITS_PER_LONG_LONG - (h) - 1)) & ((~0ULL) << (l)))
35
36 #define BITS_PER_TYPE(x) (8 * sizeof(x))
37 #define BITS_TO_LONGS(x) howmany((x), 8 * sizeof(long))
38
39 /* despite the name these are really ctz */
40 #define __ffs(x) __builtin_ctzl(x)
41 #define __ffs64(x) __builtin_ctzll(x)
42 #define ffz(x) __ffs(~(x))
43
44 static inline uint8_t
hweight8(uint32_t x)45 hweight8(uint32_t x)
46 {
47 x = (x & 0x55) + ((x & 0xaa) >> 1);
48 x = (x & 0x33) + ((x & 0xcc) >> 2);
49 x = (x + (x >> 4)) & 0x0f;
50 return (x);
51 }
52
53 static inline uint16_t
hweight16(uint32_t x)54 hweight16(uint32_t x)
55 {
56 x = (x & 0x5555) + ((x & 0xaaaa) >> 1);
57 x = (x & 0x3333) + ((x & 0xcccc) >> 2);
58 x = (x + (x >> 4)) & 0x0f0f;
59 x = (x + (x >> 8)) & 0x00ff;
60 return (x);
61 }
62
63 static inline uint32_t
hweight32(uint32_t x)64 hweight32(uint32_t x)
65 {
66 x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
67 x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
68 x = (x + (x >> 4)) & 0x0f0f0f0f;
69 x = (x + (x >> 8));
70 x = (x + (x >> 16)) & 0x000000ff;
71 return x;
72 }
73
74 static inline uint32_t
hweight64(uint64_t x)75 hweight64(uint64_t x)
76 {
77 x = (x & 0x5555555555555555ULL) + ((x & 0xaaaaaaaaaaaaaaaaULL) >> 1);
78 x = (x & 0x3333333333333333ULL) + ((x & 0xccccccccccccccccULL) >> 2);
79 x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
80 x = (x + (x >> 8));
81 x = (x + (x >> 16));
82 x = (x + (x >> 32)) & 0x000000ff;
83 return x;
84 }
85
86 static inline unsigned long
hweight_long(unsigned long x)87 hweight_long(unsigned long x)
88 {
89 #ifdef __LP64__
90 return hweight64(x);
91 #else
92 return hweight32(x);
93 #endif
94 }
95
96 static inline int64_t
sign_extend64(uint64_t value,int index)97 sign_extend64(uint64_t value, int index)
98 {
99 uint8_t shift = 63 - index;
100 return (int64_t)(value << shift) >> shift;
101 }
102
103 static inline int
fls64(long long mask)104 fls64(long long mask)
105 {
106 int bit;
107
108 if (mask == 0)
109 return (0);
110 for (bit = 1; mask != 1; bit++)
111 mask = (unsigned long long)mask >> 1;
112 return (bit);
113 }
114
115 static inline int
__fls(long mask)116 __fls(long mask)
117 {
118 return (flsl(mask) - 1);
119 }
120
121 static inline uint32_t
ror32(uint32_t word,unsigned int shift)122 ror32(uint32_t word, unsigned int shift)
123 {
124 return (word >> shift) | (word << (32 - shift));
125 }
126
127 #endif
128