Add ffs, fls and integer log function.

ToDo: Add a <machine/bitops.h> include for architecture optimized overrides.
This commit is contained in:
christos 2007-11-02 21:01:29 +00:00
parent b9a4fe408b
commit cf1c3898fb
2 changed files with 268 additions and 2 deletions

View File

@ -1,11 +1,11 @@
# $NetBSD: Makefile,v 1.98 2007/09/23 11:45:11 kiyohara Exp $
# $NetBSD: Makefile,v 1.99 2007/11/02 21:01:29 christos Exp $
.include <bsd.sys.mk>
INCSDIR= /usr/include/sys
INCS= acct.h agpio.h aio.h ansi.h ataio.h audioio.h \
bootblock.h bswap.h buf.h \
bitops.h bootblock.h bswap.h buf.h \
callout.h cdefs.h cdefs_aout.h \
cdefs_elf.h cdio.h chio.h clockctl.h condvar.h conf.h core.h \
cpuio.h device.h dir.h dirent.h disk.h disklabel.h disklabel_acorn.h \

266
sys/sys/bitops.h Normal file
View File

@ -0,0 +1,266 @@
/* $NetBSD: bitops.h,v 1.1 2007/11/02 21:01:29 christos Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SYS_BITOPS_H_
#define _SYS_BITOPS_H_
/*
* Find First Set functions
*/
#ifndef ffs32
static __inline int __unused
ffs32(uint32_t _n)
{
int _v;
if (!_n)
return 0;
_v = 1;
if ((_n & 0x0000FFFFU) == 0) {
_n >>= 16;
_v += 16;
}
if ((_n & 0x000000FFU) == 0) {
_n >>= 8;
_v += 8;
}
if ((_n & 0x0000000FU) == 0) {
_n >>= 4;
_v += 4;
}
if ((_n & 0x00000003U) == 0) {
_n >>= 2;
_v += 2;
}
if ((_n & 0x00000001U) == 0) {
_n >>= 1;
_v += 1;
}
return _v;
}
#endif
#ifndef ffs64
static __inline int __unused
ffs64(uint64_t _n)
{
int _v;
if (!_n)
return 0;
_v = 1;
if ((_n & 0x00000000FFFFFFFFULL) == 0) {
_n >>= 32;
_v += 32;
}
if ((_n & 0x000000000000FFFFULL) == 0) {
_n >>= 16;
_v += 16;
}
if ((_n & 0x00000000000000FFULL) == 0) {
_n >>= 8;
_v += 8;
}
if ((_n & 0x000000000000000FULL) == 0) {
_n >>= 4;
_v += 4;
}
if ((_n & 0x0000000000000003ULL) == 0) {
_n >>= 2;
_v += 2;
}
if ((_n & 0x0000000000000001ULL) == 0) {
_n >>= 1;
_v += 1;
}
return _v;
}
#endif
/*
* Find Last Set functions
*/
#ifndef fls32
static __inline int __unused
fls32(uint32_t _n)
{
int _v;
if (!_n)
return 0;
_v = 32;
if ((_n & 0xFFFF0000U) == 0) {
_n <<= 16;
_v -= 16;
}
if ((_n & 0xFF000000U) == 0) {
_n <<= 8;
_v -= 8;
}
if ((_n & 0xF0000000U) == 0) {
_n <<= 4;
_v -= 4;
}
if ((_n & 0xC0000000U) == 0) {
_n <<= 2;
_v -= 2;
}
if ((_n & 0x80000000U) == 0) {
_n <<= 1;
_v -= 1;
}
return _v;
}
#endif
#ifndef fls64
static __inline int __unused
fls64(uint64_t _n)
{
int _v;
if (!_n)
return 0;
_v = 64;
if ((_n & 0xFFFFFFFF00000000ULL) == 0) {
_n <<= 32;
_v -= 32;
}
if ((_n & 0xFFFF000000000000ULL) == 0) {
_n <<= 16;
_v -= 16;
}
if ((_n & 0xFF00000000000000ULL) == 0) {
_n <<= 8;
_v -= 8;
}
if ((_n & 0xF000000000000000ULL) == 0) {
_n <<= 4;
_v -= 4;
}
if ((_n & 0xC000000000000000ULL) == 0) {
_n <<= 2;
_v -= 2;
}
if ((_n & 0x8000000000000000ULL) == 0) {
_n <<= 1;
_v -= 1;
}
return _v;
}
#endif
/*
* Integer logarithm, returns -1 on error. Inspired by the linux
* version written by David Howells.
*/
#define _ilog2_helper(_n, _x) ((_n) & (1ULL << (_x))) ? _x :
#define ilog2(_n) \
( \
__builtin_constant_p(_n) ? ( \
_ilog2_helper(_n, 63) \
_ilog2_helper(_n, 62) \
_ilog2_helper(_n, 61) \
_ilog2_helper(_n, 60) \
_ilog2_helper(_n, 59) \
_ilog2_helper(_n, 58) \
_ilog2_helper(_n, 57) \
_ilog2_helper(_n, 56) \
_ilog2_helper(_n, 55) \
_ilog2_helper(_n, 54) \
_ilog2_helper(_n, 53) \
_ilog2_helper(_n, 52) \
_ilog2_helper(_n, 51) \
_ilog2_helper(_n, 50) \
_ilog2_helper(_n, 49) \
_ilog2_helper(_n, 48) \
_ilog2_helper(_n, 47) \
_ilog2_helper(_n, 46) \
_ilog2_helper(_n, 45) \
_ilog2_helper(_n, 44) \
_ilog2_helper(_n, 43) \
_ilog2_helper(_n, 42) \
_ilog2_helper(_n, 41) \
_ilog2_helper(_n, 40) \
_ilog2_helper(_n, 39) \
_ilog2_helper(_n, 38) \
_ilog2_helper(_n, 37) \
_ilog2_helper(_n, 36) \
_ilog2_helper(_n, 35) \
_ilog2_helper(_n, 34) \
_ilog2_helper(_n, 33) \
_ilog2_helper(_n, 32) \
_ilog2_helper(_n, 31) \
_ilog2_helper(_n, 30) \
_ilog2_helper(_n, 29) \
_ilog2_helper(_n, 28) \
_ilog2_helper(_n, 27) \
_ilog2_helper(_n, 26) \
_ilog2_helper(_n, 25) \
_ilog2_helper(_n, 24) \
_ilog2_helper(_n, 23) \
_ilog2_helper(_n, 22) \
_ilog2_helper(_n, 21) \
_ilog2_helper(_n, 20) \
_ilog2_helper(_n, 19) \
_ilog2_helper(_n, 18) \
_ilog2_helper(_n, 17) \
_ilog2_helper(_n, 16) \
_ilog2_helper(_n, 15) \
_ilog2_helper(_n, 14) \
_ilog2_helper(_n, 13) \
_ilog2_helper(_n, 12) \
_ilog2_helper(_n, 11) \
_ilog2_helper(_n, 10) \
_ilog2_helper(_n, 9) \
_ilog2_helper(_n, 8) \
_ilog2_helper(_n, 7) \
_ilog2_helper(_n, 6) \
_ilog2_helper(_n, 5) \
_ilog2_helper(_n, 4) \
_ilog2_helper(_n, 3) \
_ilog2_helper(_n, 2) \
_ilog2_helper(_n, 1) \
_ilog2_helper(_n, 0) \
-1) : ((sizeof(_n) >= 4 ? fls64(_n) : fls32(_n)) - 1) \
)
#endif /* _SYS_BITOPS_H_ */