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