1 /* 2 * Copyright (c) 2004, 2005 David Young. All rights reserved. 3 * 4 * Programmed for NetBSD by David Young. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of David Young may not be used to endorse or promote 15 * products derived from this software without specific prior 16 * written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 21 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 22 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 24 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 29 * OF SUCH DAMAGE. 30 * 31 * $DragonFly: src/sys/sys/bitops.h,v 1.1 2007/10/14 04:15:17 sephe Exp $ 32 */ 33 34 #ifndef _SYS_BITOPS_H_ 35 #define _SYS_BITOPS_H_ 36 37 /* 38 * __BIT(n): Return a bitmask with bit n set, where the least 39 * significant bit is bit 0. 40 * 41 * __BITS(m, n): Return a bitmask with bits m through n, inclusive, 42 * set. It does not matter whether m>n or m<=n. The 43 * least significant bit is bit 0. 44 * 45 * A "bitfield" is a span of consecutive bits defined by a bitmask, 46 * where 1s select the bits in the bitfield. __SHIFTIN, __SHIFTOUT, 47 * and __SHIFTOUT_MASK help read and write bitfields from device 48 * registers. 49 * 50 * __SHIFTIN(v, mask): Left-shift bits `v' into the bitfield 51 * defined by `mask', and return them. No 52 * side-effects. 53 * 54 * __SHIFTOUT(v, mask): Extract and return the bitfield selected 55 * by `mask' from `v', right-shifting the 56 * bits so that the rightmost selected bit 57 * is at bit 0. No side-effects. 58 * 59 * __SHIFTOUT_MASK(mask): Right-shift the bits in `mask' so that 60 * the rightmost non-zero bit is at bit 61 * 0. This is useful for finding the 62 * greatest unsigned value that a bitfield 63 * can hold. No side-effects. Note that 64 * __SHIFTOUT_MASK(m) = __SHIFTOUT(m, m). 65 */ 66 67 /* __BIT(n): nth bit, where __BIT(0) == 0x1. */ 68 #define __BIT(__n) (((__n) == 32) ? 0 : ((uint32_t)1 << (__n))) 69 #define __BIT64(__n) (((__n) == 64) ? 0 : ((uint64_t)1 << (__n))) 70 71 /* __BITS(m, n): bits m through n, m < n. */ 72 #define __BITS(__m, __n) \ 73 ((__BIT(MAX((__m), (__n)) + 1) - 1) ^ (__BIT(MIN((__m), (__n))) - 1)) 74 75 #define __BITS64(__m, __n) \ 76 ((__BIT64(MAX((__m), (__n)) + 1) - 1) ^ \ 77 (__BIT64(MIN((__m), (__n))) - 1)) 78 79 /* Find least significant bit that is set */ 80 #define __LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) 81 82 #define __SHIFTOUT(__x, __mask) (((__x) & (__mask)) / __LOWEST_SET_BIT(__mask)) 83 #define __SHIFTIN(__x, __mask) ((__x) * __LOWEST_SET_BIT(__mask)) 84 #define __SHIFTOUT_MASK(__mask) __SHIFTOUT((__mask), (__mask)) 85 86 /* 87 * Integer logarithm, returns -1 on error. 88 * Inspired by the linux version written by David Howells. 89 */ 90 #define _ilog2_helper(_n, _x) ((_n) & (1ULL << (_x))) ? _x : 91 #define _ilog2_const(_n) \ 92 ( \ 93 _ilog2_helper(_n, 63) \ 94 _ilog2_helper(_n, 62) \ 95 _ilog2_helper(_n, 61) \ 96 _ilog2_helper(_n, 60) \ 97 _ilog2_helper(_n, 59) \ 98 _ilog2_helper(_n, 58) \ 99 _ilog2_helper(_n, 57) \ 100 _ilog2_helper(_n, 56) \ 101 _ilog2_helper(_n, 55) \ 102 _ilog2_helper(_n, 54) \ 103 _ilog2_helper(_n, 53) \ 104 _ilog2_helper(_n, 52) \ 105 _ilog2_helper(_n, 51) \ 106 _ilog2_helper(_n, 50) \ 107 _ilog2_helper(_n, 49) \ 108 _ilog2_helper(_n, 48) \ 109 _ilog2_helper(_n, 47) \ 110 _ilog2_helper(_n, 46) \ 111 _ilog2_helper(_n, 45) \ 112 _ilog2_helper(_n, 44) \ 113 _ilog2_helper(_n, 43) \ 114 _ilog2_helper(_n, 42) \ 115 _ilog2_helper(_n, 41) \ 116 _ilog2_helper(_n, 40) \ 117 _ilog2_helper(_n, 39) \ 118 _ilog2_helper(_n, 38) \ 119 _ilog2_helper(_n, 37) \ 120 _ilog2_helper(_n, 36) \ 121 _ilog2_helper(_n, 35) \ 122 _ilog2_helper(_n, 34) \ 123 _ilog2_helper(_n, 33) \ 124 _ilog2_helper(_n, 32) \ 125 _ilog2_helper(_n, 31) \ 126 _ilog2_helper(_n, 30) \ 127 _ilog2_helper(_n, 29) \ 128 _ilog2_helper(_n, 28) \ 129 _ilog2_helper(_n, 27) \ 130 _ilog2_helper(_n, 26) \ 131 _ilog2_helper(_n, 25) \ 132 _ilog2_helper(_n, 24) \ 133 _ilog2_helper(_n, 23) \ 134 _ilog2_helper(_n, 22) \ 135 _ilog2_helper(_n, 21) \ 136 _ilog2_helper(_n, 20) \ 137 _ilog2_helper(_n, 19) \ 138 _ilog2_helper(_n, 18) \ 139 _ilog2_helper(_n, 17) \ 140 _ilog2_helper(_n, 16) \ 141 _ilog2_helper(_n, 15) \ 142 _ilog2_helper(_n, 14) \ 143 _ilog2_helper(_n, 13) \ 144 _ilog2_helper(_n, 12) \ 145 _ilog2_helper(_n, 11) \ 146 _ilog2_helper(_n, 10) \ 147 _ilog2_helper(_n, 9) \ 148 _ilog2_helper(_n, 8) \ 149 _ilog2_helper(_n, 7) \ 150 _ilog2_helper(_n, 6) \ 151 _ilog2_helper(_n, 5) \ 152 _ilog2_helper(_n, 4) \ 153 _ilog2_helper(_n, 3) \ 154 _ilog2_helper(_n, 2) \ 155 _ilog2_helper(_n, 1) \ 156 _ilog2_helper(_n, 0) \ 157 -1 \ 158 ) 159 #define ilog2(_n) \ 160 ( \ 161 __builtin_constant_p(_n) ? _ilog2_const(_n) : \ 162 ((sizeof(_n) > 4 ? flsl(_n) : fls(_n)) - 1) \ 163 ) 164 165 #endif /* !_SYS_BITOPS_H_ */ 166