xref: /openbsd/sys/dev/pci/drm/include/linux/bitops.h (revision 1bb76ff1)
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