xref: /openbsd-src/sys/dev/pci/drm/include/linux/bitops.h (revision f84b1df5a16cdd762c93854218de246e79975d3b)
1 /*	$OpenBSD: bitops.h,v 1.4 2022/01/14 06:53:14 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 
43 static inline uint8_t
44 hweight8(uint32_t x)
45 {
46 	x = (x & 0x55) + ((x & 0xaa) >> 1);
47 	x = (x & 0x33) + ((x & 0xcc) >> 2);
48 	x = (x + (x >> 4)) & 0x0f;
49 	return (x);
50 }
51 
52 static inline uint16_t
53 hweight16(uint32_t x)
54 {
55 	x = (x & 0x5555) + ((x & 0xaaaa) >> 1);
56 	x = (x & 0x3333) + ((x & 0xcccc) >> 2);
57 	x = (x + (x >> 4)) & 0x0f0f;
58 	x = (x + (x >> 8)) & 0x00ff;
59 	return (x);
60 }
61 
62 static inline uint32_t
63 hweight32(uint32_t x)
64 {
65 	x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
66 	x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
67 	x = (x + (x >> 4)) & 0x0f0f0f0f;
68 	x = (x + (x >> 8));
69 	x = (x + (x >> 16)) & 0x000000ff;
70 	return x;
71 }
72 
73 static inline uint32_t
74 hweight64(uint64_t x)
75 {
76 	x = (x & 0x5555555555555555ULL) + ((x & 0xaaaaaaaaaaaaaaaaULL) >> 1);
77 	x = (x & 0x3333333333333333ULL) + ((x & 0xccccccccccccccccULL) >> 2);
78 	x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
79 	x = (x + (x >> 8));
80 	x = (x + (x >> 16));
81 	x = (x + (x >> 32)) & 0x000000ff;
82 	return x;
83 }
84 
85 static inline unsigned long
86 hweight_long(unsigned long x)
87 {
88 #ifdef __LP64__
89 	return hweight64(x);
90 #else
91 	return hweight32(x);
92 #endif
93 }
94 
95 static inline int64_t
96 sign_extend64(uint64_t value, int index)
97 {
98 	uint8_t shift = 63 - index;
99 	return (int64_t)(value << shift) >> shift;
100 }
101 
102 static inline int
103 fls64(long long mask)
104 {
105 	int bit;
106 
107 	if (mask == 0)
108 		return (0);
109 	for (bit = 1; mask != 1; bit++)
110 		mask = (unsigned long long)mask >> 1;
111 	return (bit);
112 }
113 
114 static inline int
115 __fls(long mask)
116 {
117 	return (flsl(mask) - 1);
118 }
119 
120 static inline uint32_t
121 ror32(uint32_t word, unsigned int shift)
122 {
123 	return (word >> shift) | (word << (32 - shift));
124 }
125 
126 #endif
127