Home | History | Annotate | Line # | Download | only in linux
bitops.h revision 1.15
      1 /*	$NetBSD: bitops.h,v 1.15 2021/12/19 09:49:47 riastradh Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2013 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Taylor R. Campbell.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #ifndef _LINUX_BITOPS_H_
     33 #define _LINUX_BITOPS_H_
     34 
     35 #include <sys/cdefs.h>
     36 #include <sys/types.h>
     37 #include <sys/param.h>
     38 #include <sys/atomic.h>
     39 #include <sys/bitops.h>
     40 
     41 #include <machine/limits.h>
     42 
     43 #include <lib/libkern/libkern.h>
     44 #include <linux/bits.h>
     45 
     46 /*
     47  * Linux __ffs/__ffs64 is zero-based; zero input is undefined.  Our
     48  * ffs/ffs64 is one-based; zero input yields zero.
     49  */
     50 static inline unsigned long
     51 __ffs(unsigned long x)
     52 {
     53 
     54 	KASSERT(x != 0);
     55 	return ffs64(x) - 1;
     56 }
     57 
     58 static inline unsigned long
     59 __ffs64(uint64_t x)
     60 {
     61 
     62 	KASSERT(x != 0);
     63 	return ffs64(x) - 1;
     64 }
     65 
     66 /*
     67  * Linux fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32, so it matches
     68  * our fls semantics.
     69  */
     70 static inline int
     71 fls(int x)
     72 {
     73 	return fls32(x);
     74 }
     75 
     76 static inline unsigned int
     77 hweight8(uint8_t w)
     78 {
     79 	return popcount(w & 0xff);
     80 }
     81 
     82 static inline unsigned int
     83 hweight16(uint16_t n)
     84 {
     85 	return popcount32(n);
     86 }
     87 
     88 static inline unsigned int
     89 hweight32(uint32_t n)
     90 {
     91 	return popcount32(n);
     92 }
     93 
     94 static inline unsigned int
     95 hweight64(uint64_t n)
     96 {
     97 	return popcount64(n);
     98 }
     99 
    100 static inline int64_t
    101 sign_extend64(uint64_t x, unsigned n)
    102 {
    103 	return (int64_t)(x << (63 - n)) >> (63 - n);
    104 }
    105 
    106 #define	BITS_TO_LONGS(n)						\
    107 	roundup2((n), (sizeof(unsigned long) * CHAR_BIT))
    108 
    109 #define	BITS_PER_TYPE(type)	(sizeof(type) * NBBY)
    110 #define	BITS_PER_BYTE		NBBY
    111 #define	BITS_PER_LONG		(__SIZEOF_LONG__ * CHAR_BIT)
    112 
    113 #define	BIT(n)		((unsigned long)__BIT(n))
    114 #define	BIT_ULL(n)	((unsigned long long)__BIT(n))
    115 #define	GENMASK(h,l)	((unsigned long)__BITS(h,l))
    116 #define	GENMASK_ULL(h,l)((unsigned long long)__BITS(h,l))
    117 
    118 static inline int
    119 test_bit(unsigned int n, const volatile unsigned long *p)
    120 {
    121 	const unsigned units = (sizeof(unsigned long) * CHAR_BIT);
    122 
    123 	return ((p[n / units] & (1UL << (n % units))) != 0);
    124 }
    125 
    126 static inline void
    127 __set_bit(unsigned int n, volatile unsigned long *p)
    128 {
    129 	const unsigned units = (sizeof(unsigned long) * CHAR_BIT);
    130 
    131 	p[n / units] |= (1UL << (n % units));
    132 }
    133 
    134 static inline void
    135 __clear_bit(unsigned int n, volatile unsigned long *p)
    136 {
    137 	const unsigned units = (sizeof(unsigned long) * CHAR_BIT);
    138 
    139 	p[n / units] &= ~(1UL << (n % units));
    140 }
    141 
    142 static inline void
    143 __change_bit(unsigned int n, volatile unsigned long *p)
    144 {
    145 	const unsigned units = (sizeof(unsigned long) * CHAR_BIT);
    146 
    147 	p[n / units] ^= (1UL << (n % units));
    148 }
    149 
    150 static inline unsigned long
    151 __test_and_set_bit(unsigned int bit, volatile unsigned long *ptr)
    152 {
    153 	const unsigned int units = (sizeof(*ptr) * CHAR_BIT);
    154 	volatile unsigned long *const p = &ptr[bit / units];
    155 	const unsigned long mask = (1UL << (bit % units));
    156 	unsigned long v;
    157 
    158 	v = *p;
    159 	*p |= mask;
    160 
    161 	return ((v & mask) != 0);
    162 }
    163 
    164 static inline unsigned long
    165 __test_and_clear_bit(unsigned int bit, volatile unsigned long *ptr)
    166 {
    167 	const unsigned int units = (sizeof(*ptr) * CHAR_BIT);
    168 	volatile unsigned long *const p = &ptr[bit / units];
    169 	const unsigned long mask = (1UL << (bit % units));
    170 	unsigned long v;
    171 
    172 	v = *p;
    173 	*p &= ~mask;
    174 
    175 	return ((v & mask) != 0);
    176 }
    177 
    178 static inline unsigned long
    179 __test_and_change_bit(unsigned int bit, volatile unsigned long *ptr)
    180 {
    181 	const unsigned int units = (sizeof(*ptr) * CHAR_BIT);
    182 	volatile unsigned long *const p = &ptr[bit / units];
    183 	const unsigned long mask = (1UL << (bit % units));
    184 	unsigned long v;
    185 
    186 	v = *p;
    187 	*p ^= mask;
    188 
    189 	return ((v & mask) != 0);
    190 }
    191 
    192 static inline unsigned long
    193 __find_next_bit(const unsigned long *ptr, unsigned long nbits,
    194     unsigned long startbit, unsigned long toggle)
    195 {
    196 	const size_t bpl = (CHAR_BIT * sizeof(*ptr));
    197 	const unsigned long *p = ptr + startbit/bpl;
    198 	size_t n = howmany(nbits, bpl);
    199 	unsigned long result;
    200 	uint64_t word;
    201 
    202 	/*
    203 	 * We use ffs64 because NetBSD doesn't have a handy ffsl that
    204 	 * works on unsigned long.  This is a waste on 32-bit systems
    205 	 * but I'd rather not maintain multiple copies of this -- the
    206 	 * first version had enough bugs already.
    207 	 */
    208 
    209 	/* Do we need to examine a partial starting word?  */
    210 	if (startbit % bpl) {
    211 		/* Toggle the bits and convert to 64 bits for ffs64.  */
    212 		word = *p ^ toggle;
    213 
    214 		/* Clear the low startbit%bpl bits.  */
    215 		word &= (~0UL << (startbit % bpl));
    216 
    217 		/* Are any of these bits set now?  */
    218 		if (word)
    219 			goto out;
    220 
    221 		/* Move past it.  */
    222 		p++;
    223 		n--;
    224 	}
    225 
    226 	/* Find the first word with any bits set.  */
    227 	for (; n --> 0; p++) {
    228 		/* Toggle the bits and convert to 64 bits for ffs64. */
    229 		word = *p ^ toggle;
    230 
    231 		/* Are any of these bits set now?  */
    232 		if (word)
    233 			goto out;
    234 	}
    235 
    236 	/* Nada.  */
    237 	return nbits;
    238 
    239 out:
    240 	/* Count how many words we've skipped.  */
    241 	result = bpl*(p - ptr);
    242 
    243 	/* Find the first set bit in this word, zero-based.  */
    244 	result += ffs64(word) - 1;
    245 
    246 	/* We may have overshot, so clamp down to at most nbits.  */
    247 	return MIN(result, nbits);
    248 }
    249 
    250 static inline unsigned long
    251 find_next_bit(const unsigned long *ptr, unsigned long nbits,
    252     unsigned long startbit)
    253 {
    254 	return __find_next_bit(ptr, nbits, startbit, 0);
    255 }
    256 
    257 static inline unsigned long
    258 find_first_bit(const unsigned long *ptr, unsigned long nbits)
    259 {
    260 	return find_next_bit(ptr, nbits, 0);
    261 }
    262 
    263 static inline unsigned long
    264 find_next_zero_bit(const unsigned long *ptr, unsigned long nbits,
    265     unsigned long startbit)
    266 {
    267 	return __find_next_bit(ptr, nbits, startbit, ~0UL);
    268 }
    269 
    270 static inline unsigned long
    271 find_first_zero_bit(const unsigned long *ptr, unsigned long nbits)
    272 {
    273 	return find_next_zero_bit(ptr, nbits, 0);
    274 }
    275 
    276 #define	for_each_set_bit(BIT, PTR, NBITS)				      \
    277 	for ((BIT) = find_first_bit((PTR), (NBITS));			      \
    278 	     (BIT) < (NBITS);						      \
    279 	     (BIT) = find_next_bit((PTR), (NBITS), (BIT) + 1))
    280 
    281 #define	for_each_clear_bit(BIT, PTR, NBITS)				      \
    282 	for ((BIT) = find_first_zero_bit((PTR), (NBITS));		      \
    283 	     (BIT) < (NBITS);						      \
    284 	     (BIT) = find_next_zero_bit((PTR), (NBITS), (BIT) + 1))
    285 
    286 #endif  /* _LINUX_BITOPS_H_ */
    287