xref: /openbsd-src/sys/dev/pci/drm/include/linux/bitops.h (revision 4b70baf6e17fc8b27fc1f7fa7929335753fa94c3)
1 /*	$OpenBSD: bitops.h,v 1.1 2019/04/14 10:14:53 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 <asm/bitsperlong.h>
24 #include <linux/atomic.h>
25 
26 #define BIT(x)		(1UL << (x))
27 #define BIT_ULL(x)	(1ULL << (x))
28 #define BITS_PER_BYTE	8
29 
30 #define GENMASK(h, l)		(((~0UL) >> (BITS_PER_LONG - (h) - 1)) & ((~0UL) << (l)))
31 #define GENMASK_ULL(h, l)	(((~0ULL) >> (BITS_PER_LONG_LONG - (h) - 1)) & ((~0ULL) << (l)))
32 
33 #define BITS_TO_LONGS(x)	howmany((x), 8 * sizeof(long))
34 
35 static inline uint8_t
36 hweight8(uint32_t x)
37 {
38 	x = (x & 0x55) + ((x & 0xaa) >> 1);
39 	x = (x & 0x33) + ((x & 0xcc) >> 2);
40 	x = (x + (x >> 4)) & 0x0f;
41 	return (x);
42 }
43 
44 static inline uint16_t
45 hweight16(uint32_t x)
46 {
47 	x = (x & 0x5555) + ((x & 0xaaaa) >> 1);
48 	x = (x & 0x3333) + ((x & 0xcccc) >> 2);
49 	x = (x + (x >> 4)) & 0x0f0f;
50 	x = (x + (x >> 8)) & 0x00ff;
51 	return (x);
52 }
53 
54 static inline uint32_t
55 hweight32(uint32_t x)
56 {
57 	x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
58 	x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
59 	x = (x + (x >> 4)) & 0x0f0f0f0f;
60 	x = (x + (x >> 8));
61 	x = (x + (x >> 16)) & 0x000000ff;
62 	return x;
63 }
64 
65 static inline uint32_t
66 hweight64(uint64_t x)
67 {
68 	x = (x & 0x5555555555555555ULL) + ((x & 0xaaaaaaaaaaaaaaaaULL) >> 1);
69 	x = (x & 0x3333333333333333ULL) + ((x & 0xccccccccccccccccULL) >> 2);
70 	x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
71 	x = (x + (x >> 8));
72 	x = (x + (x >> 16));
73 	x = (x + (x >> 32)) & 0x000000ff;
74 	return x;
75 }
76 
77 static inline uint64_t
78 sign_extend64(uint64_t value, int index)
79 {
80 	uint8_t shift = 63 - index;
81 	return ((int64_t)(value << shift) >> shift);
82 }
83 
84 static inline int
85 fls64(long long mask)
86 {
87 	int bit;
88 
89 	if (mask == 0)
90 		return (0);
91 	for (bit = 1; mask != 1; bit++)
92 		mask = (unsigned long long)mask >> 1;
93 	return (bit);
94 }
95 
96 static inline uint32_t
97 ror32(uint32_t word, unsigned int shift)
98 {
99 	return (word >> shift) | (word << (32 - shift));
100 }
101 
102 #endif
103