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