diff --git a/kos/cpp.hint b/kos/cpp.hint index 8465728b93..b0074466df 100644 --- a/kos/cpp.hint +++ b/kos/cpp.hint @@ -638,6 +638,14 @@ +// +#define __hybrid_bitset_decl(x,n) x[n] +#define __hybrid_bitset_foreach(x,y,z) for(;;) +#define bitset_decl(x,n) x[n] +#define bitset_foreach(x,y,z) for(;;) + + + // #define PRIVATE_FUNCTION(sym) ;int sym(){} #define INTERN_FUNCTION(sym) ;int sym(){} diff --git a/kos/include/hybrid/__bitset.h b/kos/include/hybrid/__bitset.h new file mode 100644 index 0000000000..79d067124d --- /dev/null +++ b/kos/include/hybrid/__bitset.h @@ -0,0 +1,489 @@ +/* Copyright (c) 2019-2024 Griefer@Work * + * * + * This software is provided 'as-is', without any express or implied * + * warranty. In no event will the authors be held liable for any damages * + * arising from the use of this software. * + * * + * Permission is granted to anyone to use this software for any purpose, * + * including commercial applications, and to alter it and redistribute it * + * freely, subject to the following restrictions: * + * * + * 1. The origin of this software must not be misrepresented; you must not * + * claim that you wrote the original software. If you use this software * + * in a product, an acknowledgement (see the following) in the product * + * documentation is required: * + * Portions Copyright (c) 2019-2024 Griefer@Work * + * 2. Altered source versions must be plainly marked as such, and must not be * + * misrepresented as being the original software. * + * 3. This notice may not be removed or altered from any source distribution. * + */ +#ifndef __GUARD_HYBRID___BITSET_H +#define __GUARD_HYBRID___BITSET_H 1 + +#include "../__stdinc.h" +/**/ + +#include "__bit.h" +#include "__string.h" +#include "typecore.h" + +#ifndef __HYBRID_BITSET_WORD_BITS +#define __HYBRID_BITSET_WORD_BITS __CHAR_BIT__ +#endif /* !__HYBRID_BITSET_WORD_BITS */ + +#if __HYBRID_BITSET_WORD_BITS == 8 +#define __hybrid_bitset_t __UINT8_TYPE__ +#define __HYBRID_BITSET_WORD_SIGN __UINT8_C(0x80) +#define __HYBRID_BITSET_WORD_BMAX __UINT8_C(0xff) +#define __HYBRID_BITSET_WORD_BMSK 7 +#define __HYBRID_BITSET_WORD_SHFT 3 +#define __HYBRID_BITSET_WORD_POPCOUNT __hybrid_popcount8 +#define __HYBRID_BITSET_WORD_CTZ __hybrid_ctz8 +#define __HYBRID_BITSET_WORD_CLZ __hybrid_clz8 +#elif __HYBRID_BITSET_WORD_BITS == 16 +#define __hybrid_bitset_t __UINT16_TYPE__ +#define __HYBRID_BITSET_WORD_SIGN __UINT16_C(0x8000) +#define __HYBRID_BITSET_WORD_BMAX __UINT16_C(0xffff) +#define __HYBRID_BITSET_WORD_BMSK 15 +#define __HYBRID_BITSET_WORD_SHFT 4 +#define __HYBRID_BITSET_WORD_POPCOUNT __hybrid_popcount16 +#define __HYBRID_BITSET_WORD_CTZ __hybrid_ctz16 +#define __HYBRID_BITSET_WORD_CLZ __hybrid_clz16 +#elif __HYBRID_BITSET_WORD_BITS == 32 +#define __hybrid_bitset_t __UINT32_TYPE__ +#define __HYBRID_BITSET_WORD_SIGN __UINT32_C(0x80000000) +#define __HYBRID_BITSET_WORD_BMAX __UINT32_C(0xffffffff) +#define __HYBRID_BITSET_WORD_BMSK 31 +#define __HYBRID_BITSET_WORD_SHFT 5 +#define __HYBRID_BITSET_WORD_POPCOUNT __hybrid_popcount32 +#define __HYBRID_BITSET_WORD_CTZ __hybrid_ctz32 +#define __HYBRID_BITSET_WORD_CLZ __hybrid_clz32 +#elif __HYBRID_BITSET_WORD_BITS == 64 +#define __hybrid_bitset_t __UINT64_TYPE__ +#define __HYBRID_BITSET_WORD_SIGN __UINT64_C(0x8000000000000000) +#define __HYBRID_BITSET_WORD_BMAX __UINT64_C(0xffffffffffffffff) +#define __HYBRID_BITSET_WORD_BMSK 63 +#define __HYBRID_BITSET_WORD_SHFT 6 +#define __HYBRID_BITSET_WORD_POPCOUNT __hybrid_popcount64 +#define __HYBRID_BITSET_WORD_CTZ __hybrid_ctz64 +#define __HYBRID_BITSET_WORD_CLZ __hybrid_clz64 +#else /* __HYBRID_BITSET_WORD_BITS == ... */ +#define __hybrid_bitset_t __TYPEFOR_UINTIB() +#define __HYBRID_BITSET_WORD_SIGN (__CCAST(__hybrid_bitset_t)1 << (__HYBRID_BITSET_WORD_BITS - 1)) +#define __HYBRID_BITSET_WORD_BMAX ((__CCAST(__hybrid_bitset_t)1 << __HYBRID_BITSET_WORD_BITS) - 1) +#define __HYBRID_BITSET_WORD_BMSK (__HYBRID_BITSET_WORD_BITS - 1) +#define __HYBRID_BITSET_WORD_SHFT log2(__HYBRID_BITSET_WORD_BITS) +#define __HYBRID_BITSET_WORD_POPCOUNT __hybrid_popcount +#define __HYBRID_BITSET_WORD_CTZ __hybrid_ctz +#define __HYBRID_BITSET_WORD_CLZ __hybrid_clz +#endif /* __HYBRID_BITSET_WORD_BITS != ... */ + +#define __HYBRID_BITSET_BYTE(bitno) ((bitno) >> __HYBRID_BITSET_WORD_SHFT) +#define __HYBRID_BITSET_MASK(bitno) (__CCAST(__hybrid_bitset_t) 1 << ((bitno) & __HYBRID_BITSET_WORD_BMSK)) +#define __HYBRID_BITSET_LENGTHOF(n_bits) (((n_bits) + __HYBRID_BITSET_WORD_BMSK) >> __HYBRID_BITSET_WORD_SHFT) + +#if __HYBRID_BITSET_WORD_BITS == __CHAR_BIT__ +#define __HYBRID_BITSET_WORD_SIZE 1 +#define __HYBRID_BITSET_SIZEOF(n_bits) __HYBRID_BITSET_LENGTHOF(n_bits) +#else /* __HYBRID_BITSET_WORD_BITS == __CHAR_BIT__ */ +#define __HYBRID_BITSET_WORD_SIZE (__HYBRID_BITSET_WORD_BITS / __CHAR_BIT__) +#define __HYBRID_BITSET_SIZEOF(n_bits) (__HYBRID_BITSET_LENGTHOF(n_bits) * __HYBRID_BITSET_WORD_SIZE) +#endif /* __HYBRID_BITSET_WORD_BITS != __CHAR_BIT__ */ + + +#ifdef __CC__ +__DECL_BEGIN + +#define __hybrid_memset_one(p, n) __hybrid_memset(p, __HYBRID_BITSET_WORD_BMAX, n) +#define __hybrid_memset_zero(p, n) __hybrid_bzero(p, n) + +/* >> __hybrid_bitset_t __hybrid_bitset_decl(self, 256); */ +#define __hybrid_bitset_decl(self, nbits) \ + ((self)[__HYBRID_BITSET_LENGTHOF(nbits)]) + +/* >> bool __hybrid_bitset_test(__hybrid_bitset_t const *self, size_t bitno); */ +#define __hybrid_bitset_test(self, bitno) \ + ((self)[__HYBRID_BITSET_BYTE(bitno)] & __HYBRID_BITSET_MASK(bitno)) + +/* >> void __hybrid_bitset_set(__hybrid_bitset_t *self, size_t bitno); */ +#define __hybrid_bitset_set(self, bitno) \ + (void)((self)[__HYBRID_BITSET_BYTE(bitno)] |= __HYBRID_BITSET_MASK(bitno)) + +/* >> void __hybrid_bitset_clear(__hybrid_bitset_t *self, size_t bitno); */ +#define __hybrid_bitset_clear(self, bitno) \ + (void)((self)[__HYBRID_BITSET_BYTE(bitno)] &= ~__HYBRID_BITSET_MASK(bitno)) + +/* >> void __hybrid_bitset_flip(__hybrid_bitset_t *self, size_t bitno); */ +#define __hybrid_bitset_flip(self, bitno) \ + (void)((self)[__HYBRID_BITSET_BYTE(bitno)] ^= __HYBRID_BITSET_MASK(bitno)) + + +/* >> void __hybrid_bitset_setall(__hybrid_bitset_t *self, size_t n_bits); */ +#define __hybrid_bitset_setall(self, n_bits) \ + __hybrid_memset_one(self, __HYBRID_BITSET_SIZEOF(n_bits)) + +/* >> void __hybrid_bitset_clearall(__hybrid_bitset_t *self, size_t n_bits); */ +#define __hybrid_bitset_clearall(self, n_bits) \ + __hybrid_memset_zero(self, __HYBRID_BITSET_SIZEOF(n_bits)) + +/* >> void __hybrid_bitset_flipall(__hybrid_bitset_t *self, size_t n_bits); */ +#define __hybrid_bitset_flipall(self, n_bits) \ + do { \ + __SIZE_TYPE__ __bfa_i; \ + for (__bfa_i = 0; __bfa_i < __HYBRID_BITSET_LENGTHOF(n_bits); ++__bfa_i) \ + (self)[__bfa_i] ^= __HYBRID_BITSET_WORD_BMAX; \ + } __WHILE0 + +/* >> size_t bitno; + * >> __hybrid_bitset_t bitset[__HYBRID_BITSET_LENGTHOF(42)]; + * >> ... + * >> __hybrid_bitset_foreach (bitno, bitset, 42) { + * >> printf("bit is on: %Iu\n", bitno); + * >> } */ +#define __hybrid_bitset_foreach(bitno, self, n_bits) \ + for ((bitno) = 0; (bitno) < (n_bits); ++(bitno)) \ + if (!__hybrid_bitset_test(self, bitno)) \ + ; \ + else + + + +#define __HYBRID_PRIVATE_BITSET_NCLEAR_IMPL(self, minbyte, maxbyte, minbyte_bitno, maxbyte_bitno) \ + if (minbyte >= maxbyte) { \ + self[maxbyte] &= ((__HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BITS - minbyte_bitno)) | \ + (__HYBRID_BITSET_WORD_BMAX << (maxbyte_bitno + 1))); \ + } else { \ + self[minbyte] &= __HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BITS - minbyte_bitno); \ + __hybrid_memset_zero(&self[minbyte + 1], maxbyte - (minbyte + 1)); \ + self[maxbyte] &= __HYBRID_BITSET_WORD_BMAX << (maxbyte_bitno + 1); \ + } +#define __HYBRID_PRIVATE_BITSET_NSET_IMPL(self, minbyte, maxbyte, minbyte_bitno, maxbyte_bitno) \ + if (minbyte >= maxbyte) { \ + self[maxbyte] |= ((__HYBRID_BITSET_WORD_BMAX << minbyte_bitno) | \ + (__HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BMSK - maxbyte_bitno))); \ + } else { \ + self[minbyte] |= __HYBRID_BITSET_WORD_BMAX << minbyte_bitno; \ + __hybrid_memset_one(&self[minbyte + 1], maxbyte - (minbyte + 1)); \ + self[maxbyte] |= __HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BMSK - maxbyte_bitno); \ + } +#define __HYBRID_PRIVATE_BITSET_NCLEAR(self, minbitno, maxbitno) \ + __register __SIZE_TYPE__ __hbs_minbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(minbitno); \ + __register __SIZE_TYPE__ __hbs_maxbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(maxbitno); \ + __HYBRID_PRIVATE_BITSET_NCLEAR_IMPL(self, __hbs_minbyte, __hbs_maxbyte, (minbitno & __HYBRID_BITSET_WORD_BMSK), (maxbitno & __HYBRID_BITSET_WORD_BMSK)) +#define __HYBRID_PRIVATE_BITSET_NSET(self, minbitno, maxbitno) \ + __register __SIZE_TYPE__ __hbs_minbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(minbitno); \ + __register __SIZE_TYPE__ __hbs_maxbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(maxbitno); \ + __HYBRID_PRIVATE_BITSET_NSET_IMPL(self, __hbs_minbyte, __hbs_maxbyte, (minbitno & __HYBRID_BITSET_WORD_BMSK), (maxbitno & __HYBRID_BITSET_WORD_BMSK)) + +/* >> void __hybrid_bitset_nclear(__hybrid_bitset_t *self, size_t minbitno, size_t maxbitno); + * Turn off bits [minbitno, maxbitno] (inclusive) in `self' + * NOTE: When `minbitno > maxbitno', the result is weak undefined behavior, + * in that the way in which `self' is modified is undefined, though the + * function still guaranties that nothing but `self' gets modified. */ +#ifdef __NO_XBLOCK +__LOCAL __ATTR_NONNULL((1)) void +(__hybrid_bitset_nclear)(__hybrid_bitset_t *__restrict __self, + __SIZE_TYPE__ __minbitno, __SIZE_TYPE__ __maxbitno) { + __HYBRID_PRIVATE_BITSET_NCLEAR(__self, __minbitno, __maxbitno); +} +#else /* __NO_XBLOCK */ +#define __hybrid_bitset_nclear(self, minbitno, maxbitno) \ + __XBLOCK({ \ + __register __hybrid_bitset_t *__bcn_self = (self); \ + __register __SIZE_TYPE__ __bnc_minbitno = (__SIZE_TYPE__)(minbitno); \ + __register __SIZE_TYPE__ __bnc_maxbitno = (__SIZE_TYPE__)(maxbitno); \ + __HYBRID_PRIVATE_BITSET_NCLEAR(__bcn_self, __bnc_minbitno, __bnc_maxbitno); \ + (void)0; \ + }) +#endif /* !__NO_XBLOCK */ + +/* >> void __hybrid_bitset_nset(__hybrid_bitset_t *self, size_t minbitno, size_t maxbitno); + * Turn on bits [minbitno, maxbitno] (inclusive) in `self' + * NOTE: When `minbitno > maxbitno', the result is weak undefined behavior, + * in that the way in which `self' is modified is undefined, though the + * function still guaranties that nothing but `self' gets modified. */ +#ifdef __NO_XBLOCK +__LOCAL __ATTR_NONNULL((1)) void +(__hybrid_bitset_nset)(__hybrid_bitset_t *__restrict __self, + __SIZE_TYPE__ __minbitno, __SIZE_TYPE__ __maxbitno) { + __HYBRID_PRIVATE_BITSET_NSET(__self, __minbitno, __maxbitno); +} +#else /* __NO_XBLOCK */ +#define __hybrid_bitset_nset(self, minbitno, maxbitno) \ + __XBLOCK({ \ + __register __hybrid_bitset_t *__bns_self = (self); \ + __register __SIZE_TYPE__ __bns_minbitno = (__SIZE_TYPE__)(minbitno); \ + __register __SIZE_TYPE__ __bns_maxbitno = (__SIZE_TYPE__)(maxbitno); \ + __HYBRID_PRIVATE_BITSET_NSET(__bns_self, __bns_minbitno, __bns_maxbitno); \ + (void)0; \ + }) +#endif /* !__NO_XBLOCK */ + + +#define __HYBRID_PRIVATE_BITSET_FFC_I_IMPL(self, n_bits, result) \ + __register __SIZE_TYPE__ __bffc_bindex, __bffc_maxbyte; \ + __bffc_maxbyte = __HYBRID_BITSET_BYTE(n_bits - 1); \ + result = -1; \ + for (__bffc_bindex = 0; __bffc_bindex <= __bffc_maxbyte; ++__bffc_bindex) { \ + __hybrid_bitset_t __word = self[__bffc_bindex]; \ + if (__word == __HYBRID_BITSET_WORD_BMAX) \ + continue; \ + result = __bffc_bindex << __HYBRID_BITSET_WORD_SHFT; \ + while (__word & 1) { \ + ++result; \ + __word >>= 1; \ + } \ + if __unlikely(result >= nbits) \ + result = -1; \ + break; \ + } +#define __HYBRID_PRIVATE_BITSET_FFS_I_IMPL(self, n_bits, result) \ + __register __SIZE_TYPE__ __bffs_bindex, __bffs_maxbyte; \ + __bffs_maxbyte = __HYBRID_BITSET_BYTE(n_bits - 1); \ + result = -1; \ + for (__bffs_bindex = 0; __bffs_bindex <= __bffs_maxbyte; ++__bffs_bindex) { \ + __hybrid_bitset_t __word = self[__bffs_bindex]; \ + if (__word == 0) \ + continue; \ + result = (__bffs_bindex << __HYBRID_BITSET_WORD_SHFT) + __HYBRID_BITSET_WORD_CTZ(__word); \ + if __unlikely(result >= nbits) \ + result = -1; \ + break; \ + } +#define __HYBRID_PRIVATE_BITSET_FFC_IMPL(self, n_bits, result) \ + __register __SIZE_TYPE__ __bffc_bindex, __bffc_maxbyte; \ + __bffc_maxbyte = __HYBRID_BITSET_BYTE(n_bits - 1); \ + result = (n_bits); \ + for (__bffc_bindex = 0; __bffc_bindex <= __bffc_maxbyte; ++__bffc_bindex) { \ + __hybrid_bitset_t __word = self[__bffc_bindex]; \ + if (__word == __HYBRID_BITSET_WORD_BMAX) \ + continue; \ + result = __bffc_bindex << __HYBRID_BITSET_WORD_SHFT; \ + while (__word & 1) { \ + ++result; \ + __word >>= 1; \ + } \ + break; \ + } +#define __HYBRID_PRIVATE_BITSET_FFS_IMPL(self, n_bits, result) \ + __register __SIZE_TYPE__ __bffs_bindex, __bffs_maxbyte; \ + __bffs_maxbyte = __HYBRID_BITSET_BYTE(n_bits - 1); \ + result = (n_bits); \ + for (__bffs_bindex = 0; __bffs_bindex <= __bffs_maxbyte; ++__bffs_bindex) { \ + __hybrid_bitset_t __word = self[__bffs_bindex]; \ + if (__word == 0) \ + continue; \ + result = (__bffs_bindex << __HYBRID_BITSET_WORD_SHFT) + __HYBRID_BITSET_WORD_CTZ(__word); \ + break; \ + } + + +/* >> void __hybrid_bitset_ffc_i(__hybrid_bitset_t const *self, size_t n_bits, ssize_t *p_value); + * Find the first bitno within [0, n_bits) that is off and store its + * index in `*p_value'. If no such bit exists, write `-1' into `*p_value'. */ +#define __hybrid_bitset_ffc_i(self, n_bits, p_value) \ + do { \ + __register __hybrid_bitset_t const *__bffc_self = (self); \ + __register __SIZE_TYPE__ __bffc_nbits = (nbits); \ + __register __SSIZE_TYPE__ __bffc_result; \ + __HYBRID_PRIVATE_BITSET_FFC_I_IMPL(__bffc_self, __bffc_nbits, __bffc_result); \ + *(p_value) = __bffc_result; \ + } __WHILE0 + +/* >> void __hybrid_bitset_ffs_i(__hybrid_bitset_t const *self, size_t n_bits, ssize_t *p_value); + * Find the first bitno within [0, n_bits) that is on and store its + * index in `*p_value'. If no such bit exists, write `-1' into `*p_value'. */ +#define __hybrid_bitset_ffs_i(self, n_bits, p_value) \ + do { \ + __register __hybrid_bitset_t const *__bffc_self = (self); \ + __register __SIZE_TYPE__ __bffc_nbits = (nbits); \ + __register __SSIZE_TYPE__ __bffc_result; \ + __HYBRID_PRIVATE_BITSET_FFS_I_IMPL(__bffc_self, __bffc_nbits, __bffc_result); \ + *(p_value) = __bffc_result; \ + } __WHILE0 + + +/* Find the first bitno within [0, n_bits) that is off and return + * its index. If no such bit exists, return some value `>= n_bits'. */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ +__NOTHROW_NCX(__hybrid_bitset_ffc)(__hybrid_bitset_t const *__restrict __self, __SIZE_TYPE__ __n_bits) { + __register __SIZE_TYPE__ __result; + __HYBRID_PRIVATE_BITSET_FFC_IMPL(__self, __n_bits, __result); + return __result; +} + +/* Find the first bitno within [0, n_bits) that is on and return + * its index. If no such bit exists, return some value `>= n_bits'. */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ +__NOTHROW_NCX(__hybrid_bitset_ffs)(__hybrid_bitset_t const *__restrict __self, __SIZE_TYPE__ __n_bits) { + __register __SIZE_TYPE__ __result; + __HYBRID_PRIVATE_BITSET_FFS_IMPL(__self, __n_bits, __result); + return __result; +} + + +/* Check if the bitset contains any 1-elements */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL +__NOTHROW_NCX(__hybrid_bitset_anyset)(__hybrid_bitset_t const *__restrict __self, __SIZE_TYPE__ __n_bits) { + __register __SIZE_TYPE__ __i; + for (__i = 0; __i < (__n_bits >> __HYBRID_BITSET_WORD_SHFT); ++__i) { + if (__self[__i] != 0) + return 1; + } + if (__n_bits & __HYBRID_BITSET_WORD_BMSK) { + if (__self[__i] & ((1 << (__n_bits & __HYBRID_BITSET_WORD_BMSK)) - 1)) + return 1; + } + return 0; +} + + +/* Check if the bitset contains only 1-elements */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL +__NOTHROW_NCX(__hybrid_bitset_allset)(__hybrid_bitset_t const *__restrict __self, __SIZE_TYPE__ __n_bits) { + __register __SIZE_TYPE__ __i; + for (__i = 0; __i < (__n_bits >> __HYBRID_BITSET_WORD_SHFT); ++__i) { + if (__self[__i] != __HYBRID_BITSET_WORD_BMAX) + return 0; + } + if (__n_bits & __HYBRID_BITSET_WORD_BMSK) { + __hybrid_bitset_t __mask = ((1 << (__n_bits & __HYBRID_BITSET_WORD_BMSK)) - 1); + if ((__self[__i] & __mask) != __mask) + return 0; + } + return 1; +} + + +/* Check if the bitset contains any 1-elements within the given range */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL +__NOTHROW_NCX(__hybrid_bitset_nanyset)(__hybrid_bitset_t const *__restrict __self, + __SIZE_TYPE__ __minbitno, __SIZE_TYPE__ __maxbitno) { + __register __SIZE_TYPE__ __minbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(__minbitno); + __register __SIZE_TYPE__ __maxbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(__maxbitno); + if (__minbyte >= __maxbyte) { + if (__self[__maxbyte] & ~((__HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BITS - (__minbitno & __HYBRID_BITSET_WORD_BMSK))) | + (__HYBRID_BITSET_WORD_BMAX << ((__maxbitno & __HYBRID_BITSET_WORD_BMSK) + 1)))) + return 1; + } else { + __register __SIZE_TYPE__ __i; + if (__self[__minbyte] & ~(__HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BITS - (__minbitno & __HYBRID_BITSET_WORD_BMSK)))) + return 1; + for (__i = __minbyte + 1; __i < __maxbyte; ++__i) { + if (__self[__i] != 0) + return 1; + } + if (__self[__maxbyte] & ~(__HYBRID_BITSET_WORD_BMAX << ((__maxbitno & __HYBRID_BITSET_WORD_BMSK) + 1))) + return 1; + } + return 0; +} + +/* Check if the bitset contains only 1-elements within the given range */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL +__NOTHROW_NCX(__hybrid_bitset_nallset)(__hybrid_bitset_t const *__restrict __self, + __SIZE_TYPE__ __minbitno, __SIZE_TYPE__ __maxbitno) { + __register __SIZE_TYPE__ __minbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(__minbitno); + __register __SIZE_TYPE__ __maxbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(__maxbitno); + if (__minbyte >= __maxbyte) { + __hybrid_bitset_t __mask = ~((__HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BITS - (__minbitno & __HYBRID_BITSET_WORD_BMSK))) | + (__HYBRID_BITSET_WORD_BMAX << ((__maxbitno & __HYBRID_BITSET_WORD_BMSK) + 1))); + if ((__self[__maxbyte] & __mask) != __mask) + return 0; + } else { + __register __SIZE_TYPE__ __i; + __hybrid_bitset_t __mask; + __mask = ~(__HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BITS - (__minbitno & __HYBRID_BITSET_WORD_BMSK))); + if ((__self[__minbyte] & __mask) != __mask) + return 0; + for (__i = __minbyte + 1; __i < __maxbyte; ++__i) { + if (__self[__i] != __HYBRID_BITSET_WORD_BMAX) + return 0; + } + __mask = ~(__HYBRID_BITSET_WORD_BMAX << ((__maxbitno & __HYBRID_BITSET_WORD_BMSK) + 1)); + if ((__self[__maxbyte] & __mask) != __mask) + return 0; + } + return 1; +} + + +/* Returns the # of 1-bits in `self' */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ +__NOTHROW_NCX(__hybrid_bitset_popcount)(__hybrid_bitset_t const *__restrict __self, __SIZE_TYPE__ __n_bits) { + __SIZE_TYPE__ __i, __result = 0; + for (__i = 0; __i < (__n_bits >> __HYBRID_BITSET_WORD_SHFT); ++__i) + __result += __HYBRID_BITSET_WORD_POPCOUNT(__self[__i]); + if (__n_bits & __HYBRID_BITSET_WORD_BMSK) { + __hybrid_bitset_t __mask = ((1 << (__n_bits & __HYBRID_BITSET_WORD_BMSK)) - 1); + __result += __HYBRID_BITSET_WORD_POPCOUNT(__self[__i] & __mask); + } + return __result; +} + +/* Returns the # of 1-bits within the given range */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ +__NOTHROW_NCX(__hybrid_bitset_npopcount)(__hybrid_bitset_t const *__restrict __self, + __SIZE_TYPE__ __minbitno, __SIZE_TYPE__ __maxbitno) { + __SIZE_TYPE__ __result; + __register __SIZE_TYPE__ __minbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(__minbitno); + __register __SIZE_TYPE__ __maxbyte = (__SIZE_TYPE__)__HYBRID_BITSET_BYTE(__maxbitno); + if (__minbyte >= __maxbyte) { + __result = __HYBRID_BITSET_WORD_POPCOUNT(__self[__maxbyte] & + ~((__HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BITS - (__minbitno & __HYBRID_BITSET_WORD_BMSK))) | + (__HYBRID_BITSET_WORD_BMAX << ((__maxbitno & __HYBRID_BITSET_WORD_BMSK) + 1)))); + } else { + __register __SIZE_TYPE__ __i; + __result = __HYBRID_BITSET_WORD_POPCOUNT(__self[__minbyte] & ~(__HYBRID_BITSET_WORD_BMAX >> (__HYBRID_BITSET_WORD_BITS - (__minbitno & __HYBRID_BITSET_WORD_BMSK)))); + for (__i = __minbyte + 1; __i < __maxbyte; ++__i) + __result += __HYBRID_BITSET_WORD_POPCOUNT(__self[__i]); + __result += __HYBRID_BITSET_WORD_POPCOUNT(__self[__maxbyte] & ~(__HYBRID_BITSET_WORD_BMAX << ((__maxbitno & __HYBRID_BITSET_WORD_BMSK) + 1))); + } + return __result; +} + +/* Count-leading-zeroes (undefined when `self' doesn't contain any set bits) */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ +__NOTHROW_NCX(__hybrid_bitset_clz)(__hybrid_bitset_t const *__restrict __self) { + __SIZE_TYPE__ __result = 0; + for (; *__self == 0; ++__self) + __result += __HYBRID_BITSET_WORD_BITS; + return __result + __HYBRID_BITSET_WORD_CLZ(*__self); +} + +/* Count-trailing-zeroes (undefined when `self' doesn't contain any set bits) */ +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ +__NOTHROW_NCX(__hybrid_bitset_ctz)(__hybrid_bitset_t const *__restrict __self, __SIZE_TYPE__ __n_bits) { + __SIZE_TYPE__ __result = 0; + __SIZE_TYPE__ __byteoff = __n_bits >> __HYBRID_BITSET_WORD_SHFT; + if (__n_bits & __HYBRID_BITSET_WORD_BMSK) { + __hybrid_bitset_t __word = __self[__byteoff]; + __word <<= __HYBRID_BITSET_WORD_BITS - (__n_bits & __HYBRID_BITSET_WORD_BMSK); + if (__word) { + while (!(__word & __HYBRID_BITSET_WORD_SIGN)) { + __word <<= 1; + ++__result; + } + return __result; + } + __result = __n_bits & __HYBRID_BITSET_WORD_BMSK; + } + if (__byteoff) { + __hybrid_bitset_t __word; + --__byteoff; + for (; __self[__byteoff] == 0; --__byteoff) + __result += __HYBRID_BITSET_WORD_BITS; + __word = __self[__byteoff]; + while (!(__word & __HYBRID_BITSET_WORD_SIGN)) { + ++__result; + __word <<= 1; + } + } + return __result; +} + + +__DECL_END +#endif /* __CC__ */ + +#endif /* !__GUARD_HYBRID___BITSET_H */ diff --git a/kos/include/hybrid/__string.h b/kos/include/hybrid/__string.h new file mode 100644 index 0000000000..630b3cafe6 --- /dev/null +++ b/kos/include/hybrid/__string.h @@ -0,0 +1,342 @@ +/* Copyright (byte) 2019-2024 Griefer@Work * + * * + * This software is provided 'as-is', without any express or implied * + * warranty. In no event will the authors be held liable for any damages * + * arising from the use of this software. * + * * + * Permission is granted to anyone to use this software for any purpose, * + * including commercial applications, and to alter it and redistribute it * + * freely, subject to the following restrictions: * + * * + * 1. The origin of this software must not be misrepresented; you must not * + * claim that you wrote the original software. If you use this software * + * in a product, an acknowledgement (see the following) in the product * + * documentation is required: * + * Portions Copyright (byte) 2019-2024 Griefer@Work * + * 2. Altered source versions must be plainly marked as such, and must not be * + * misrepresented as being the original software. * + * 3. This notice may not be removed or altered from any source distribution. * + */ +#ifndef __GUARD_HYBRID___MEMSET_H +#define __GUARD_HYBRID___MEMSET_H 1 + +#include "../__stdinc.h" + +#ifdef __CC__ +#ifdef __INTELLISENSE__ +#include "typecore.h" +__DECL_BEGIN +void __hybrid_memcpy(void *__dst, void const *__src, __SIZE_TYPE__ __num_bytes); +void __hybrid_memset(void *__dst, int __byte, __SIZE_TYPE__ __num_bytes); +__DECL_END +#define __hybrid_memcpy(dst, src, num_bytes) __hybrid_memcpy(dst, src, num_bytes) +#define __hybrid_memset(dst, byte, num_bytes) __hybrid_memset(dst, byte, num_bytes) +#elif defined(__KOS_SYSTEM_HEADERS__) +#include +#define __hybrid_memcpy(dst, src, num_bytes) (void)__libc_memcpy(dst, src, num_bytes) +#define __hybrid_memcpyw(dst, src, num_words) (void)__libc_memcpyw(dst, src, num_words) +#define __hybrid_memcpyl(dst, src, num_dwords) (void)__libc_memcpyl(dst, src, num_dwords) +#define __hybrid_memset(dst, byte, num_bytes) (void)__libc_memset(dst, byte, num_bytes) +#define __hybrid_bzero(dst, num_bytes) __libc_bzero(dst, num_bytes) +#define __hybrid_bzerow(dst, num_words) __libc_bzerow(dst, num_words) +#define __hybrid_bzerol(dst, num_dwords) __libc_bzerol(dst, num_dwords) +#ifdef __UINT64_TYPE__ +#define __hybrid_memcpyq(dst, src, num_qwords) (void)__libc_memcpyq(dst, src, num_qwords) +#define __hybrid_bzeroq(dst, num_qwords) __libc_bzeroq(dst, num_bytes) +#endif /* __UINT64_TYPE__ */ +#else /* __KOS_SYSTEM_HEADERS__ */ + +#if (__has_include() || \ + (defined(__NO_has_include) && \ + !(defined(__STDC_HOSTED__) && (__STDC_HOSTED__ + 0) == 0) && \ + !defined(CONFIG_NO_STRING_H) && \ + !(defined(CONFIG_HAVE_STRING_H) && (-CONFIG_HAVE_STRING_H - 1) != -1) && \ + !defined(CONFIG_NO_INCLUDE_STRING_H) && \ + !(defined(CONFIG_HAVE_INCLUDE_STRING_H) && (-CONFIG_HAVE_INCLUDE_STRING_H - 1) != -1) && \ + !defined(NO_STRING_H) && !defined(NO_HAVE_STRING_H) && \ + !(defined(HAVE_STRING_H) && (-HAVE_STRING_H - 1) != -1) && \ + !defined(NO_INCLUDE_STRING_H) && !defined(NO_HAVE_INCLUDE_STRING_H) && \ + !(defined(HAVE_INCLUDE_STRING_H) && (-HAVE_INCLUDE_STRING_H - 1) != -1))) +#include +#if (!defined(CONFIG_NO_memcpy) && !defined(CONFIG_NO_MEMCPY) && \ + !defined(NO_memcpy) && !defined(NO_MEMCPY) && \ + !(defined(CONFIG_HAVE_memcpy) || (- CONFIG_HAVE_memcpy - 1) != -1) && \ + !(defined(CONFIG_HAVE_MEMCPY) || (- CONFIG_HAVE_MEMCPY - 1) != -1) && \ + !(defined(HAVE_memcpy) || (- HAVE_memcpy - 1) != -1) && \ + !(defined(HAVE_MEMCPY) || (- HAVE_MEMCPY - 1) != -1)) +#define __hybrid_memcpy(dst, src, num_bytes) (void)memcpy(dst, src, num_bytes) +#endif /* ... */ +#if (!defined(CONFIG_NO_memset) && !defined(CONFIG_NO_MEMSET) && \ + !defined(NO_memset) && !defined(NO_MEMSET) && \ + !(defined(CONFIG_HAVE_memset) || (- CONFIG_HAVE_memset - 1) != -1) && \ + !(defined(CONFIG_HAVE_MEMSET) || (- CONFIG_HAVE_MEMSET - 1) != -1) && \ + !(defined(HAVE_memset) || (- HAVE_memset - 1) != -1) && \ + !(defined(HAVE_MEMSET) || (- HAVE_MEMSET - 1) != -1)) +#define __hybrid_memset(dst, byte, num_bytes) (void)memset(dst, byte, num_bytes) +#endif /* ... */ +#endif /* __has_include() || (__NO_has_include && !...) */ + +#if !defined(__hybrid_memcpyq) && defined(_MSC_VER) +#include "host.h" +#ifdef __x86_64__ +__DECL_BEGIN +extern void __movsq(unsigned long long *, unsigned long long const *, unsigned __int64); +#undef memcpyq +#define __hybrid_memcpyq(dst, src, num_qwords) \ + __movsq((unsigned long long *)(void *)(dst), \ + (unsigned long long const *)(void const *)(src), \ + (unsigned __int64)(num_qwords)) +#pragma intrinsic(__movsq) +__DECL_END +#endif /* __x86_64__ */ +#endif /* !__hybrid_memcpyq && _MSC_VER */ + +#if !defined(__hybrid_memcpyl) && defined(_MSC_VER) +#include "host.h" +#if defined(__i386__) || defined(__x86_64__) +__DECL_BEGIN +#ifdef __x86_64__ +extern void __movsd(unsigned long *, unsigned long const *, unsigned __int64); +#define __hybrid_memcpyl(dst, src, num_dwords) \ + __movsd((unsigned long *)(void *)(dst), \ + (unsigned long const *)(void const *)(src), \ + (unsigned __int64)(num_dwords)) +#else /* __x86_64__ */ +extern void __movsd(unsigned long *, unsigned long const *, unsigned int); +#define __hybrid_memcpyl(dst, src, num_dwords) \ + __movsd((unsigned long *)(void *)(dst), \ + (unsigned long const *)(void const *)(src), \ + (unsigned int)(num_dwords)) +#endif /* !__x86_64__ */ +#pragma intrinsic(__movsd) +__DECL_END +#endif /* __i386__ || __x86_64__ */ +#endif /* !__hybrid_memcpyl && _MSC_VER */ + +#if !defined(__hybrid_memcpyw) && defined(_MSC_VER) +#include "host.h" +#if defined(__i386__) || defined(__x86_64__) +__DECL_BEGIN +#ifdef __x86_64__ +extern void __movsw(unsigned short *, unsigned short const *, unsigned __int64); +#define __hybrid_memcpyw(dst, src, num_words) \ + __movsw((unsigned short *)(void *)(dst), \ + (unsigned short const *)(void const *)(src), \ + (unsigned __int64)(num_words)) +#else /* __x86_64__ */ +extern void __movsw(unsigned short *, unsigned short const *, unsigned int); +#define __hybrid_memcpyw(dst, src, num_words) \ + __movsw((unsigned short *)(void *)(dst), \ + (unsigned short const *)(void const *)(src), \ + (unsigned int)(num_words)) +#endif /* !__x86_64__ */ +#pragma intrinsic(__movsw) +__DECL_END +#endif /* __i386__ || __x86_64__ */ +#endif /* !__hybrid_memcpyw && _MSC_VER */ +#endif /* !__KOS_SYSTEM_HEADERS__ */ + + + +#if defined(__hybrid_memcpyw) && defined(__hybrid_memcpyl) && defined(__hybrid_memcpyq) +#define __hybrid_memcpyc(dst, src, elem_count, elem_size) \ + ((elem_size) == 2 \ + ? (void *)__hybrid_memcpyw(dst, src, elem_count) \ + : (elem_size) == 4 \ + ? (void *)__hybrid_memcpyl(dst, src, elem_count) \ + : (elem_size) == 8 \ + ? (void *)__hybrid_memcpyq(dst, src, elem_count) \ + : __hybrid_memcpy(dst, src, (__SIZE_TYPE__)(elem_count) * (__SIZE_TYPE__)(elem_size))) +#elif defined(__hybrid_memcpyw) && defined(__hybrid_memcpyl) +#define __hybrid_memcpyc(dst, src, elem_count, elem_size) \ + ((elem_size) == 2 \ + ? (void *)__hybrid_memcpyw(dst, src, elem_count) \ + : (elem_size) == 4 \ + ? (void *)__hybrid_memcpyl(dst, src, elem_count) \ + : __hybrid_memcpy(dst, src, (__SIZE_TYPE__)(elem_count) * (__SIZE_TYPE__)(elem_size))) +#elif defined(__hybrid_memcpyw) && defined(__hybrid_memcpyq) +#define __hybrid_memcpyc(dst, src, elem_count, elem_size) \ + ((elem_size) == 2 \ + ? (void *)__hybrid_memcpyw(dst, src, elem_count) \ + : (elem_size) == 8 \ + ? (void *)__hybrid_memcpyq(dst, src, elem_count) \ + : __hybrid_memcpy(dst, src, (__SIZE_TYPE__)(elem_count) * (__SIZE_TYPE__)(elem_size))) +#elif defined(__hybrid_memcpyl) && defined(__hybrid_memcpyq) +#define __hybrid_memcpyc(dst, src, elem_count, elem_size) \ + ((elem_size) == 4 \ + ? (void *)__hybrid_memcpyl(dst, src, elem_count) \ + : (elem_size) == 8 \ + ? (void *)__hybrid_memcpyq(dst, src, elem_count) \ + : __hybrid_memcpy(dst, src, (__SIZE_TYPE__)(elem_count) * (__SIZE_TYPE__)(elem_size))) +#elif defined(__hybrid_memcpyq) +#define __hybrid_memcpyc(dst, src, elem_count, elem_size) \ + ((elem_size) == 8 \ + ? (void *)__hybrid_memcpyq(dst, src, elem_count) \ + : __hybrid_memcpy(dst, src, (__SIZE_TYPE__)(elem_count) * (__SIZE_TYPE__)(elem_size))) +#elif defined(__hybrid_memcpyl) +#define __hybrid_memcpyc(dst, src, elem_count, elem_size) \ + ((elem_size) == 4 \ + ? (void *)__hybrid_memcpyl(dst, src, elem_count) \ + : __hybrid_memcpy(dst, src, (__SIZE_TYPE__)(elem_count) * (__SIZE_TYPE__)(elem_size))) +#elif defined(__hybrid_memcpyw) +#define __hybrid_memcpyc(dst, src, elem_count, elem_size) \ + ((elem_size) == 2 \ + ? (void *)__hybrid_memcpyw(dst, src, elem_count) \ + : __hybrid_memcpy(dst, src, (__SIZE_TYPE__)(elem_count) * (__SIZE_TYPE__)(elem_size))) +#else /* ... */ +#define __hybrid_memcpyc(dst, src, elem_count, elem_size) \ + __hybrid_memcpy(dst, src, (__SIZE_TYPE__)(elem_count) * (__SIZE_TYPE__)(elem_size)) +#endif /* !... */ + + + +#ifndef __hybrid_memcpyq +#ifdef __hybrid_memcpyl +#define __hybrid_memcpyq(dst, src, num_qwords) __hybrid_memcpyl(dst, src, (__SIZE_TYPE__)(num_qwords) << 1) +#elif defined(__hybrid_memcpyw) +#define __hybrid_memcpyq(dst, src, num_qwords) __hybrid_memcpyw(dst, src, (__SIZE_TYPE__)(num_qwords) << 2) +#elif defined(__hybrid_memcpy) +#define __hybrid_memcpyq(dst, src, num_qwords) __hybrid_memcpy(dst, src, (__SIZE_TYPE__)(num_qwords) << 3) +#else /* ... */ +#include "typecore.h" +#if (__SIZEOF_BUSINT__ >= 8) && defined(__UINT64_TYPE__) +#define __hybrid_memcpyq(dst, src, num_qwords) \ + do { \ + __UINT64_TYPE__ *__hmc_d = (__UINT64_TYPE__ *)(void *)(dst); \ + __UINT64_TYPE__ const *__hmc_s = (__UINT64_TYPE__ const *)(void const *)(src); \ + __SIZE_TYPE__ __hmc_n = (__SIZE_TYPE__)(num_qwords); \ + while (__hmc_n) { \ + *__hmc_d = *__hmc_s; \ + --__hmc_n; \ + ++__hmc_s; \ + ++__hmc_d; \ + } \ + } __WHILE0 +#else /* __SIZEOF_BUSINT__ >= 8 && __UINT64_TYPE__ */ +#define __hybrid_memcpyq(dst, src, num_qwords) \ + do { \ + __UINT32_TYPE__ *__hmc_d = (__UINT32_TYPE__ *)(void *)(dst); \ + __UINT32_TYPE__ const *__hmc_s = (__UINT32_TYPE__ const *)(void const *)(src); \ + __SIZE_TYPE__ __hmc_n = (__SIZE_TYPE__)(num_qwords) << 1; \ + while (__hmc_n) { \ + *__hmc_d = *__hmc_s; \ + --__hmc_n; \ + ++__hmc_s; \ + ++__hmc_d; \ + } \ + } __WHILE0 +#endif /* __SIZEOF_BUSINT__ < 8 || !__UINT64_TYPE__ */ +#endif /* !... */ +#endif /* !__hybrid_memcpyq */ + +#ifndef __hybrid_memcpyl +#ifdef __hybrid_memcpyw +#define __hybrid_memcpyl(dst, src, num_dwords) __hybrid_memcpyw(dst, src, (num_dwords) << 1) +#elif defined(__hybrid_memcpy) +#define __hybrid_memcpyl(dst, src, num_dwords) __hybrid_memcpy(dst, src, (num_dwords) << 2) +#else /* ... */ +#include "typecore.h" +#define __hybrid_memcpyl(dst, src, num_dwords) \ + do { \ + __UINT32_TYPE__ *__hmc_d = (__UINT32_TYPE__ *)(void *)(dst); \ + __UINT32_TYPE__ const *__hmc_s = (__UINT32_TYPE__ const *)(void const *)(src); \ + __SIZE_TYPE__ __hmc_n = (__SIZE_TYPE__)(num_dwords); \ + while (__hmc_n) { \ + *__hmc_d = *__hmc_s; \ + --__hmc_n; \ + ++__hmc_s; \ + ++__hmc_d; \ + } \ + } __WHILE0 +#endif /* !... */ +#endif /* !__hybrid_memcpyl */ + +#ifndef __hybrid_memcpyw +#ifdef __hybrid_memcpy +#define __hybrid_memcpyw(dst, src, num_words) __hybrid_memcpy(dst, src, (num_words) << 1) +#else /* __hybrid_memcpy */ +#include "typecore.h" +#define __hybrid_memcpyw(dst, src, num_words) \ + do { \ + __UINT16_TYPE__ *__hmc_d = (__UINT16_TYPE__ *)(void *)(dst); \ + __UINT16_TYPE__ const *__hmc_s = (__UINT16_TYPE__ const *)(void const *)(src); \ + __SIZE_TYPE__ __hmc_n = (__SIZE_TYPE__)(num_words); \ + while (__hmc_n) { \ + *__hmc_d = *__hmc_s; \ + --__hmc_n; \ + ++__hmc_s; \ + ++__hmc_d; \ + } \ + } __WHILE0 +#endif /* !__hybrid_memcpy */ +#endif /* !__hybrid_memcpyw */ + +#ifndef __hybrid_memcpy +#include "typecore.h" +#define __hybrid_memcpy(dst, src, num_bytes) \ + do { \ + __BYTE_TYPE__ *__hmc_d = (__BYTE_TYPE__ *)(void *)(dst); \ + __BYTE_TYPE__ const *__hmc_s = (__BYTE_TYPE__ const *)(void const *)(src); \ + __SIZE_TYPE__ __hmc_n = (__SIZE_TYPE__)(num_bytes); \ + while (__hmc_n) { \ + *__hmc_d = *__hmc_s; \ + --__hmc_n; \ + ++__hmc_s; \ + ++__hmc_d; \ + } \ + } __WHILE0 +#endif /* !__hybrid_memcpy */ + +#ifndef __hybrid_memset +#include "typecore.h" +#define __hybrid_memset(dst, byte, num_bytes) \ + do { \ + __BYTE_TYPE__ *__hms_p = (__BYTE_TYPE__ *)(void *)(dst); \ + __BYTE_TYPE__ __hms_c = (__BYTE_TYPE__)(unsigned int)(int)(byte); \ + __SIZE_TYPE__ __hms_n = (__SIZE_TYPE__)(num_bytes); \ + while (__hms_n) { \ + *__hms_p = __hms_c; \ + --__hms_n; \ + ++__hms_p; \ + } \ + } __WHILE0 +#define __hybrid_bzero(dst, num_bytes) \ + do { \ + __BYTE_TYPE__ *__hbz_p = (__BYTE_TYPE__ *)(dst); \ + __SIZE_TYPE__ __hbz_n = (__SIZE_TYPE__)(num_bytes); \ + while (__hbz_n) { \ + *__hbz_p = 0; \ + --__hbz_n; \ + ++__hbz_p; \ + } \ + } __WHILE0 +#endif /* !__hybrid_memset */ + +#ifndef __hybrid_bzeroq +#ifdef __hybrid_bzerol +#define __hybrid_bzeroq(dst, num_qwords) __hybrid_bzerol(dst, (__SIZE_TYPE__)(num_qwords) << 1) +#elif defined(__hybrid_bzerow) +#define __hybrid_bzeroq(dst, num_qwords) __hybrid_bzerow(dst, (__SIZE_TYPE__)(num_qwords) << 2) +#else /* ... */ +#define __hybrid_bzeroq(dst, num_qwords) __hybrid_bzero(dst, (__SIZE_TYPE__)(num_qwords) << 3) +#endif /* !... */ +#endif /* !__hybrid_bzeroq */ + +#ifndef __hybrid_bzerol +#ifdef __hybrid_bzerow +#define __hybrid_bzerol(dst, num_dwords) __hybrid_bzerow(dst, (__SIZE_TYPE__)(num_dwords) << 1) +#else /* __hybrid_bzerow */ +#define __hybrid_bzerol(dst, num_dwords) __hybrid_bzero(dst, (__SIZE_TYPE__)(num_dwords) << 2) +#endif /* !__hybrid_bzerow */ +#endif /* !__hybrid_bzerol */ + +#ifndef __hybrid_bzerow +#define __hybrid_bzerow(dst, num_words) __hybrid_bzero(dst, (__SIZE_TYPE__)(num_words) << 1) +#endif /* !__hybrid_bzerow */ + +#ifndef __hybrid_bzero +#define __hybrid_bzero(dst, num_bytes) __hybrid_memset(dst, 0, num_bytes) +#endif /* !__hybrid_bzero */ +#endif /* __CC__ */ + +#endif /* !__GUARD_HYBRID___MEMSET_H */ diff --git a/kos/include/hybrid/bitset.h b/kos/include/hybrid/bitset.h new file mode 100644 index 0000000000..0f92cdf7b8 --- /dev/null +++ b/kos/include/hybrid/bitset.h @@ -0,0 +1,148 @@ +/* Copyright (c) 2019-2024 Griefer@Work * + * * + * This software is provided 'as-is', without any express or implied * + * warranty. In no event will the authors be held liable for any damages * + * arising from the use of this software. * + * * + * Permission is granted to anyone to use this software for any purpose, * + * including commercial applications, and to alter it and redistribute it * + * freely, subject to the following restrictions: * + * * + * 1. The origin of this software must not be misrepresented; you must not * + * claim that you wrote the original software. If you use this software * + * in a product, an acknowledgement (see the following) in the product * + * documentation is required: * + * Portions Copyright (c) 2019-2024 Griefer@Work * + * 2. Altered source versions must be plainly marked as such, and must not be * + * misrepresented as being the original software. * + * 3. This notice may not be removed or altered from any source distribution. * + */ +#ifndef __GUARD_HYBRID_BIT_H +#define __GUARD_HYBRID_BIT_H 1 + +#include "__bitset.h" + +#ifdef __CC__ +__DECL_BEGIN + +#define _BITSET_WORD_BMAX __HYBRID_BITSET_WORD_BMAX /* 0xff: bitset_t-word with all bits set */ +#define _BITSET_WORD_BITS __HYBRID_BITSET_WORD_BITS /* 8: # of bits in a bitset_t-word */ +#define _BITSET_WORD_BMSK __HYBRID_BITSET_WORD_BMSK /* 7: # of bits in a bitset_t-word minus 1 */ +#define _BITSET_WORD_SHFT __HYBRID_BITSET_WORD_SHFT /* 3: log2(_BITSET_BITS) */ +#define _BITSET_BYTE(bitno) __HYBRID_BITSET_BYTE(bitno) /* Index of `bitno' in `bitset_t[]' */ +#define _BITSET_MASK(bitno) __HYBRID_BITSET_MASK(bitno) /* Mask for `bitno' in `bitset_t[]' */ +#define BITSET_LENGTHOF(n_bits) __HYBRID_BITSET_LENGTHOF(n_bits) /* Length of `bitset_t[]' for `n_bits' bits */ +#define BITSET_SIZEOF(n_bits) __HYBRID_BITSET_SIZEOF(n_bits) /* Size (in bytes) of `bitset_t[]' for `n_bits' bits */ + +/* >> bitset_t bitset_decl(self, 256); */ +#define bitset_decl(self, nbits) __hybrid_bitset_decl(self, nbits) + + +#ifdef __INTELLISENSE__ +/* >> bitset_t bitset_decl(bitset, 42); + * >> bitset_clearall(bitset, 42); + * >> ... */ +typedef __hybrid_bitset_t bitset_t; + +/* Check if a given "bitset" is set. */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL bitset_test(bitset_t const *self, __SIZE_TYPE__ bitno); + +/* Change the state of a single "bitno". */ +__ATTR_NONNULL((1)) void bitset_set(bitset_t *self, __SIZE_TYPE__ bitno); +__ATTR_NONNULL((1)) void bitset_clear(bitset_t *self, __SIZE_TYPE__ bitno); +__ATTR_NONNULL((1)) void bitset_flip(bitset_t *self, __SIZE_TYPE__ bitno); + +/* Change the state of the first "n_bits". */ +__ATTR_NONNULL((1)) void bitset_setall(bitset_t *self, __SIZE_TYPE__ n_bits); +__ATTR_NONNULL((1)) void bitset_clearall(bitset_t *self, __SIZE_TYPE__ n_bits); +__ATTR_NONNULL((1)) void bitset_flipall(bitset_t *self, __SIZE_TYPE__ n_bits); + +/* Turn off bits [minbitno, maxbitno] (inclusive) in `self' + * NOTE: When `minbitno > maxbitno', the result is weak undefined behavior, + * in that the way in which `self' is modified is undefined, though the + * function still guaranties that nothing but `self' gets modified. */ +__ATTR_NONNULL((1)) void bitset_nclear(bitset_t *self, __SIZE_TYPE__ minbitno, __SIZE_TYPE__ maxbitno); + +/* Turn on bits [minbitno, maxbitno] (inclusive) in `self' + * NOTE: When `minbitno > maxbitno', the result is weak undefined behavior, + * in that the way in which `self' is modified is undefined, though the + * function still guaranties that nothing but `self' gets modified. */ +__ATTR_NONNULL((1)) void bitset_nset(bitset_t *self, __SIZE_TYPE__ minbitno, __SIZE_TYPE__ maxbitno); + +/* Find the first bitno within [0, n_bits) that is off and store its + * index in `*p_value'. If no such bit exists, write `-1' into `*p_value'. */ +__ATTR_PURE __ATTR_NONNULL((1)) void bitset_ffc_i(bitset_t const *self, __SIZE_TYPE__ n_bits, __SSIZE_TYPE__ *p_value); + +/* Find the first bitno within [0, n_bits) that is on and store its + * index in `*p_value'. If no such bit exists, write `-1' into `*p_value'. */ +__ATTR_PURE __ATTR_NONNULL((1)) void bitset_ffs_i(bitset_t const *self, __SIZE_TYPE__ n_bits, __SSIZE_TYPE__ *p_value); + +/* Find the first bitno within [0, n_bits) that is off and return + * its index. If no such bit exists, return some value `>= n_bits'. */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ bitset_ffc(bitset_t const *self, __SIZE_TYPE__ n_bits); + +/* Find the first bitno within [0, n_bits) that is on and return + * its index. If no such bit exists, return some value `>= n_bits'. */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ bitset_ffs(bitset_t const *self, __SIZE_TYPE__ n_bits); + +/* Check if the bitset contains any 1-elements */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL bitset_anyset(bitset_t const *self, __SIZE_TYPE__ n_bits); + +/* Check if the bitset contains only 1-elements */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL bitset_allset(bitset_t const *self, __SIZE_TYPE__ n_bits); + +/* Check if the bitset contains any 1-elements within the given range */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL bitset_nanyset(bitset_t const *self, __SIZE_TYPE__ minbitno, __SIZE_TYPE__ maxbitno); + +/* Check if the bitset contains only 1-elements within the given range */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL bitset_nallset(bitset_t const *self, __SIZE_TYPE__ minbitno, __SIZE_TYPE__ maxbitno); + +/* Returns the # of 1-bits in `self' */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ bitset_popcount(bitset_t const *__restrict self, __SIZE_TYPE__ n_bits); + +/* Returns the # of 1-bits within the given range */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ bitset_npopcount(bitset_t const *self, __SIZE_TYPE__ minbitno, __SIZE_TYPE__ maxbitno); + +/* Count-leading-zeroes (undefined when `self' doesn't contain any set bits) */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ bitset_clz(bitset_t const *__restrict self); + +/* Count-trailing-zeroes (undefined when `self' doesn't contain any set bits) */ +__ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __SIZE_TYPE__ bitset_ctz(bitset_t const *__restrict self, __SIZE_TYPE__ n_bits); +#else /* __INTELLISENSE__ */ +#define bitset_t __hybrid_bitset_t +#define bitset_test(self, bitno) __hybrid_bitset_test(self, bitno) +#define bitset_set(self, bitno) __hybrid_bitset_set(self, bitno) +#define bitset_clear(self, bitno) __hybrid_bitset_clear(self, bitno) +#define bitset_flip(self, bitno) __hybrid_bitset_flip(self, bitno) +#define bitset_setall(self, n_bits) __hybrid_bitset_setall(self, n_bits) +#define bitset_clearall(self, n_bits) __hybrid_bitset_clearall(self, n_bits) +#define bitset_flipall(self, n_bits) __hybrid_bitset_flipall(self, n_bits) +#define bitset_nclear(self, minbitno, maxbitno) __hybrid_bitset_nclear(self, minbitno, maxbitno) +#define bitset_nset(self, minbitno, maxbitno) __hybrid_bitset_nset(self, minbitno, maxbitno) +#define bitset_ffc_i(self, n_bits, p_value) __hybrid_bitset_ffc_i(self, n_bits, p_value) +#define bitset_ffs_i(self, n_bits, p_value) __hybrid_bitset_ffs_i(self, n_bits, p_value) +#define bitset_ffc(self, n_bits) __hybrid_bitset_ffc(self, n_bits) +#define bitset_ffs(self, n_bits) __hybrid_bitset_ffs(self, n_bits) +#define bitset_anyset(self, n_bits) __hybrid_bitset_anyset(self, n_bits) +#define bitset_allset(self, n_bits) __hybrid_bitset_allset(self, n_bits) +#define bitset_nanyset(self, minbitno, maxbitno) __hybrid_bitset_nanyset(self, minbitno, maxbitno) +#define bitset_nallset(self, minbitno, maxbitno) __hybrid_bitset_nallset(self, minbitno, maxbitno) +#define bitset_popcount(self, n_bits) __hybrid_bitset_popcount(self, n_bits) +#define bitset_npopcount(self, minbitno, maxbitno) __hybrid_bitset_npopcount(self, minbitno, maxbitno) +#define bitset_clz(self) __hybrid_bitset_clz(self) +#define bitset_ctz(self, n_bits) __hybrid_bitset_ctz(self, n_bits) +#endif /* !__INTELLISENSE__ */ + +/* >> size_t bitno; + * >> bitset_t bitset[_BITSET_LENGTHOF(42)]; + * >> ... + * >> bitset_foreach (bitno, bitset, 42) { + * >> printf("bit is on: %Iu\n", bitno); + * >> } */ +#define bitset_foreach(bitno, self, n_bits) \ + __hybrid_bitset_foreach(bitno, self, n_bits) + +__DECL_END +#endif /* __CC__ */ + +#endif /* !__GUARD_HYBRID_BIT_H */ diff --git a/kos/include/hybrid/sequence/bitset.h b/kos/include/hybrid/sequence/bitset.h index 8101f4fc60..c0bc62111b 100644 --- a/kos/include/hybrid/sequence/bitset.h +++ b/kos/include/hybrid/sequence/bitset.h @@ -23,7 +23,15 @@ #include "../../__stdinc.h" #include "../__atomic.h" -/* TODO: Get rid of this API and replace it with `' */ +/* !!!!!! DEPRECATED API !!!!!! */ +/* !!!!!! DEPRECATED API !!!!!! */ +/* !!!!!! DEPRECATED API !!!!!! */ +/* !!!!!! !!!!!! */ +/* !!!!!! USE INSTEAD !!!!!! */ +/* !!!!!! !!!!!! */ +/* !!!!!! DEPRECATED API !!!!!! */ +/* !!!!!! DEPRECATED API !!!!!! */ +/* !!!!!! DEPRECATED API !!!!!! */ #ifdef __CC__ diff --git a/kos/include/sys/bitstring.h b/kos/include/sys/bitstring.h index 4977f739b8..9cbd80ba9e 100644 --- a/kos/include/sys/bitstring.h +++ b/kos/include/sys/bitstring.h @@ -24,23 +24,19 @@ #define _SYS_BITSTRING_H 1 #include <__stdinc.h> - -#include -#include - +#include #include -#include -#define _bit_byte(bitno) ((bitno) >> 3) /* bitno / 8 */ -#define _bit_mask(bitno) (__UINT8_C(1) << ((bitno)&7)) /* 1 << (bitno % 8) */ +#define _bit_byte(bitno) __HYBRID_BITSET_BYTE(bitno) /* bitno / 8 */ +#define _bit_mask(bitno) __HYBRID_BITSET_MASK(bitno) /* 1 << (bitno % 8) */ /* Return the # of bytes needed to represent `nbits' bits */ -#define bitstr_size(nbits) (((nbits) + 7) >> 3) /* CEILDIV(nbits, 8) */ +#define bitstr_size(nbits) __HYBRID_BITSET_SIZEOF(nbits) /* CEILDIV(nbits, 8) */ #ifdef __CC__ __DECL_BEGIN -typedef unsigned char bitstr_t; +typedef __hybrid_bitset_t bitstr_t; /* Allocate a zero-initialized bitstring on the heap. * If the allocation fails, then this function returns `NULL' */ @@ -53,7 +49,7 @@ __ATTR_MALLOC __ATTR_WUNUSED bitstr_t *(bit_alloc)(int nbits); /* Declare a bitstring variable `self' that can hold at least `nbits' bits: * >> bitstr_t bit_decl(mybitstr, 42); // `mybitstr' can hold at least `42' bits */ #define bit_decl(self, nbits) \ - ((self)[bitstr_size(nbits)]) + ((self)[__HYBRID_BITSET_LENGTHOF(nbits)]) #ifdef __USE_KOS #ifdef __INTELLISENSE__ @@ -61,41 +57,32 @@ __ATTR_NONNULL((1)) void (bit_setall)(bitstr_t *self, int nbits); __ATTR_NONNULL((1)) void (bit_clearall)(bitstr_t *self, int nbits); __ATTR_NONNULL((1)) void (bit_flipall)(bitstr_t *self, int nbits); #else /* __INTELLISENSE__ */ -#define bit_setall(self, nbits) __libc_memset(self, 0xff, bitstr_size(nbits) * sizeof(bitstr_t)) -#define bit_clearall(self, nbits) __libc_bzero(self, bitstr_size(nbits) * sizeof(bitstr_t)) -#define bit_flipall(self, nbits) \ - do { \ - __SIZE_TYPE__ __bfa_i; \ - for (__bfa_i = 0; __bfa_i < bitstr_size(nbits); ++__bfa_i) \ - (self)[__bfa_i] ^= 0xff; \ - } __WHILE0 +#define bit_setall(self, nbits) __hybrid_bitset_setall(self, nbits) +#define bit_clearall(self, nbits) __hybrid_bitset_clearall(self, nbits) +#define bit_flipall(self, nbits) __hybrid_bitset_flipall(self, nbits) #endif /* !__INTELLISENSE__ */ -#define bit_foreach(bitno, self, nbits) \ - for ((bitno) = 0; (bitno) < (nbits); ++(bitno)) \ - if (!bit_test(self, bitno)) \ - ; \ - else +#define bit_foreach(bitno, self, nbits) __hybrid_bitset_foreach(bitno, self, nbits) #endif /* __USE_KOS */ /* Check if `bitno' of `self' set */ #ifdef __INTELLISENSE__ __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL (bit_test)(bitstr_t const *self, int bitno); #else /* __INTELLISENSE__ */ -#define bit_test(self, bitno) ((self)[_bit_byte(bitno)] & _bit_mask(bitno)) +#define bit_test(self, bitno) __hybrid_bitset_test(self, bitno) #endif /* !__INTELLISENSE__ */ /* Turn on `bitno' of `self' */ #ifdef __INTELLISENSE__ __ATTR_NONNULL((1)) void (bit_set)(bitstr_t *__restrict self, int bitno); #else /* __INTELLISENSE__ */ -#define bit_set(self, bitno) (void)((self)[_bit_byte(bitno)] |= _bit_mask(bitno)) +#define bit_set(self, bitno) __hybrid_bitset_set(self, bitno) #endif /* !__INTELLISENSE__ */ /* Turn off `bitno' of `self' */ #ifdef __INTELLISENSE__ __ATTR_NONNULL((1)) void (bit_clear)(bitstr_t *__restrict self, int bitno); #else /* __INTELLISENSE__ */ -#define bit_clear(self, bitno) (void)((self)[_bit_byte(bitno)] &= ~_bit_mask(bitno)) +#define bit_clear(self, bitno) __hybrid_bitset_clear(self, bitno) #endif /* !__INTELLISENSE__ */ #ifdef __USE_KOS @@ -103,34 +90,10 @@ __ATTR_NONNULL((1)) void (bit_clear)(bitstr_t *__restrict self, int bitno); #ifdef __INTELLISENSE__ __ATTR_NONNULL((1)) void (bit_flip)(bitstr_t *__restrict self, int bitno); #else /* __INTELLISENSE__ */ -#define bit_flip(self, bitno) (void)((self)[_bit_byte(bitno)] ^= _bit_mask(bitno)) +#define bit_flip(self, bitno) __hybrid_bitset_flip(self, bitno) #endif /* !__INTELLISENSE__ */ #endif /* __USE_KOS */ -#define __PRIVATE_bit_nclear_impl(self, minbyte, maxbyte, minbyte_bitno, maxbyte_bitno) \ - ((minbyte >= maxbyte) \ - ? (self[maxbyte] &= ((0xff >> (8 - minbyte_bitno)) | \ - (0xff << (maxbyte_bitno + 1)))) \ - : (self[minbyte] &= 0xff >> (8 - minbyte_bitno), \ - __libc_bzero(&self[minbyte + 1], maxbyte - (minbyte + 1)), \ - self[maxbyte] &= 0xff << (maxbyte_bitno + 1))) -#define __PRIVATE_bit_nset_impl(self, minbyte, maxbyte, minbyte_bitno, maxbyte_bitno) \ - ((minbyte >= maxbyte) \ - ? (self[maxbyte] |= ((0xff << minbyte_bitno) | \ - (0xff >> (7 - maxbyte_bitno)))) \ - : (self[minbyte] |= 0xff << minbyte_bitno, \ - __libc_memset(&self[minbyte + 1], 0xff, maxbyte - (minbyte + 1)), \ - self[maxbyte] |= 0xff >> (7 - maxbyte_bitno))) -#define __PRIVATE_bit_nclear(self, minbitno, maxbitno) \ - __register __size_t __minbyte = (__size_t)_bit_byte(minbitno); \ - __register __size_t __maxbyte = (__size_t)_bit_byte(maxbitno); \ - __PRIVATE_bit_nclear_impl(self, __minbyte, __maxbyte, (minbitno & 7), (maxbitno & 7)) -#define __PRIVATE_bit_nset(self, minbitno, maxbitno) \ - __register __size_t __minbyte = (__size_t)_bit_byte(minbitno); \ - __register __size_t __maxbyte = (__size_t)_bit_byte(maxbitno); \ - __PRIVATE_bit_nset_impl(self, __minbyte, __maxbyte, (minbitno & 7), (maxbitno & 7)) - - #ifdef __INTELLISENSE__ /* Turn off bits [minbitno, maxbitno] (inclusive) in `self' * NOTE: When `minbitno > maxbitno', the result is weak undefined behavior, @@ -143,67 +106,10 @@ __ATTR_NONNULL((1)) void (bit_nclear)(bitstr_t *__restrict self, int minbitno, i * in that the way in which `self' is modified is undefined, though the * function still guaranties that nothing but `self' gets modified. */ __ATTR_NONNULL((1)) void (bit_nset)(bitstr_t *__restrict self, int minbitno, int maxbitno); -#elif !defined(__NO_XBLOCK) -#define bit_nclear(self, minbitno, maxbitno) \ - __XBLOCK({ \ - __register bitstr_t *__bcn_self = (self); \ - __register int __bnc_minbitno = (minbitno); \ - __register int __bnc_maxbitno = (maxbitno); \ - __PRIVATE_bit_nclear(__bcn_self, __bnc_minbitno, __bnc_maxbitno); \ - (void)0; \ - }) -#define bit_nset(self, minbitno, maxbitno) \ - __XBLOCK({ \ - __register bitstr_t *__bns_self = (self); \ - __register int __bns_minbitno = (minbitno); \ - __register int __bns_maxbitno = (maxbitno); \ - __PRIVATE_bit_nset(__bns_self, __bns_minbitno, __bns_maxbitno); \ - (void)0; \ - }) -#else /* ... */ -__LOCAL __ATTR_NONNULL((1)) void -(bit_nclear)(bitstr_t *__restrict __self, int __minbitno, int __maxbitno) { - __PRIVATE_bit_nclear(__self, __minbitno, __maxbitno); -} -__LOCAL __ATTR_NONNULL((1)) void -(bit_nset)(bitstr_t *__restrict __self, int __minbitno, int __maxbitno) { - __PRIVATE_bit_nset(__self, __minbitno, __maxbitno); -} -#endif /* !... */ - - - -#define __PRIVATE_bit_ffc_impl(self, nbits, result) \ - __register int __bffc_bindex, __bffc_maxbyte; \ - __bffc_maxbyte = _bit_byte(nbits - 1); \ - result = -1; \ - for (__bffc_bindex = 0; __bffc_bindex <= __bffc_maxbyte; ++__bffc_bindex) { \ - bitstr_t __byte = self[__bffc_bindex]; \ - if (__byte == 0xff) \ - continue; \ - result = __bffc_bindex << 3; \ - while (__byte & 1) { \ - ++result; \ - __byte >>= 1; \ - } \ - break; \ - } \ - if __unlikely(result >= nbits) \ - result = -1; - -#define __PRIVATE_bit_ffs_impl(self, nbits, result) \ - __register int __bffs_bindex, __bffs_maxbyte; \ - __bffs_maxbyte = _bit_byte(nbits - 1); \ - result = -1; \ - for (__bffs_bindex = 0; __bffs_bindex <= __bffs_maxbyte; ++__bffs_bindex) { \ - bitstr_t __byte = self[__bffs_bindex]; \ - if (__byte == 0) \ - continue; \ - result = (__bffs_bindex << 3) + __hybrid_ctz8(__byte); \ - break; \ - } \ - if __unlikely(result >= nbits) \ - result = -1 +#else /* __INTELLISENSE__ */ +#define bit_nclear(self, minbitno, maxbitno) __hybrid_bitset_nclear(self, minbitno, maxbitno) +#define bit_nset(self, minbitno, maxbitno) __hybrid_bitset_nset(self, minbitno, maxbitno) +#endif /* !__INTELLISENSE__ */ #ifdef __INTELLISENSE__ /* Find the first bitno within [0, nbits) that is off and store its @@ -213,151 +119,39 @@ __ATTR_NONNULL((1, 3)) void (bit_ffc)(bitstr_t const *__restrict self, int nbits * index in `*value'. If no such bit exists, write `-1' into `*value'. */ __ATTR_NONNULL((1, 3)) void (bit_ffs)(bitstr_t const *__restrict self, int nbits, int *value); #elif !defined(__NO_XBLOCK) -#define bit_ffc(self, nbits, value) \ - __XBLOCK({ \ - __register bitstr_t const *__bffc_self = (self); \ - __register int __bffc_result, __bffc_nbits = (nbits); \ - __PRIVATE_bit_ffc_impl(__bffc_self, __bffc_nbits, __bffc_result); \ - *(value) = __bffc_result; \ - (void)0; \ - }) -#define bit_ffs(self, nbits, value) \ - __XBLOCK({ \ - __register bitstr_t const *__bffs_self = (self); \ - __register int __bffs_result, __bffs_nbits = (nbits); \ - __PRIVATE_bit_ffs_impl(__bffs_self, __bffs_nbits, __bffs_result); \ - *(value) = __bffs_result; \ - (void)0; \ - }) +#define bit_ffc(self, nbits, value) __XBLOCK({ __SSIZE_TYPE__ __bs_ffc_res; __hybrid_bitset_ffc_i(self, nbits, &__bs_ffc_res); *(value) = (int)__bs_ffc_res; (void)0; }) +#define bit_ffs(self, nbits, value) __XBLOCK({ __SSIZE_TYPE__ __bs_ffs_res; __hybrid_bitset_ffs_i(self, nbits, &__bs_ffs_res); *(value) = (int)__bs_ffs_res; (void)0; }) #else /* ... */ -#define bit_ffc(self, nbits, value) (void)(*(value) = __PRIVATE_bit_ffc(self, nbits)) -#define bit_ffs(self, nbits, value) (void)(*(value) = __PRIVATE_bit_ffs(self, nbits)) -__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1, 3)) int -__NOTHROW_NCX(__PRIVATE_bit_ffc)(bitstr_t const *__restrict __self, int __nbits) { - __register int __result; - __PRIVATE_bit_ffc_impl(__self, __nbits, __result); +#define bit_ffc(self, nbits, value) (void)(*(value) = (int)__PRIVATE_bit_ffc(self, nbits)) +#define bit_ffs(self, nbits, value) (void)(*(value) = (int)__PRIVATE_bit_ffs(self, nbits)) +__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1, 3)) __SSIZE_TYPE__ +__NOTHROW_NCX(__PRIVATE_bit_ffc)(bitstr_t const *__restrict __self, __SIZE_TYPE__ __nbits) { + __register __SSIZE_TYPE__ __result; + __hybrid_bitset_ffc_i(__self, __nbits, &__result); return __result; } __LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1, 3)) int -__NOTHROW_NCX(__PRIVATE_bit_ffs)(bitstr_t const *__restrict __self, int __nbits) { - __register int __result; - __PRIVATE_bit_ffs_impl(__self, __nbits, __result); +__NOTHROW_NCX(__PRIVATE_bit_ffs)(bitstr_t const *__restrict __self, __SIZE_TYPE__ __nbits) { + __register __SSIZE_TYPE__ __result; + __hybrid_bitset_ffs_i(__self, __nbits, &__result); return __result; } #endif /* !... */ #ifdef __USE_KOS -#define bit_noneset(self, nbits) (!bit_anyset(self, nbits)) -__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL -__NOTHROW_NCX(bit_anyset)(bitstr_t const *__restrict __self, unsigned int __nbits) { - unsigned int __i; - for (__i = 0; __i < (__nbits >> 3); ++__i) { - if (__self[__i] != 0) - return 1; - } - if (__nbits & 7) { - if (__self[__i] & ((1 << (__nbits & 7)) - 1)) - return 1; - } - return 0; -} -__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL -__NOTHROW_NCX(bit_allset)(bitstr_t const *__restrict __self, unsigned int __nbits) { - unsigned int __i; - for (__i = 0; __i < (__nbits >> 3); ++__i) { - if (__self[__i] != 0xff) - return 0; - } - if (__nbits & 7) { - bitstr_t __mask = ((1 << (__nbits & 7)) - 1); - if ((__self[__i] & __mask) != __mask) - return 0; - } - return 1; -} -__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) __BOOL -__NOTHROW_NCX(bit_nanyset)(bitstr_t const *__restrict __self, unsigned int __minbitno, unsigned int __maxbitno) { - __register __size_t __minbyte = (__size_t)_bit_byte(__minbitno); - __register __size_t __maxbyte = (__size_t)_bit_byte(__maxbitno); - if (__minbyte >= __maxbyte) { - if (__self[__maxbyte] & ~((0xff >> (8 - (__minbitno & 7))) | - (0xff << ((__maxbitno & 7) + 1)))) - return 1; - } else { - __register __size_t __i; - if (__self[__minbyte] & ~(0xff >> (8 - (__minbitno & 7)))) - return 1; - for (__i = __minbyte + 1; __i < __maxbyte; ++__i) { - if (__self[__i] != 0) - return 1; - } - if (__self[__maxbyte] & ~(0xff << ((__maxbitno & 7) + 1))) - return 1; - } - return 0; -} -__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) unsigned int -__NOTHROW_NCX(bit_popcount)(bitstr_t const *__restrict __self, unsigned int __nbits) { - unsigned int __result = 0; - unsigned int __i; - for (__i = 0; __i < (__nbits >> 3); ++__i) { - __result += __hybrid_popcount8(__self[__i]); - } - if (__nbits & 7) { - bitstr_t __mask = ((1 << (__nbits & 7)) - 1); - __result += __hybrid_popcount8(__self[__i] & __mask); - } - return __result; -} +#define bit_noneset(self, nbits) (!bit_anyset(self, nbits)) +#define bit_anyset(self, nbits) __hybrid_bitset_anyset(self, nbits) +#define bit_allset(self, nbits) __hybrid_bitset_allset(self, nbits) +#define bit_nanyset(self, minbitno, maxbitno) __hybrid_bitset_nanyset(self, minbitno, maxbitno) +#define bit_popcount(self, nbits) __hybrid_bitset_popcount(self, nbits) /* Count-leading-zeroes (undefined when `self' doesn't contain any set bits) */ -__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) unsigned int -__NOTHROW_NCX(bit_clz)(bitstr_t const *__restrict __self) { - bitstr_t __word; - unsigned int __result = 0; - for (; *__self == 0; ++__self) - __result += 8; - __word = *__self; - while (!(__word & 1)) { - ++__result; - __word >>= 1; - } - return __result; -} +#define bit_clz(self) (unsigned int)__hybrid_bitset_clz(self) /* Count-trailing-zeroes (undefined when `self' doesn't contain any set bits) */ -__LOCAL __ATTR_PURE __ATTR_WUNUSED __ATTR_NONNULL((1)) unsigned int -__NOTHROW_NCX(bit_ctz)(bitstr_t const *__restrict __self, unsigned int __nbits) { - bitstr_t __word; - unsigned int __result = 0; - unsigned int __byteoff = __nbits >> 3; - if (__nbits & 7) { - __word = __self[__byteoff]; - __word <<= 8 - (__nbits & 7); - if (__word) { - while (!(__word & 0x80)) { - __word <<= 1; - ++__result; - } - return __result; - } - __result = __nbits & 7; - } - if (__byteoff) { - --__byteoff; - for (; __self[__byteoff] == 0; --__byteoff) - __result += 8; - __word = __self[__byteoff]; - while (!(__word & 0x80)) { - ++__result; - __word <<= 1; - } - } - return __result; -} +#define bit_ctz(self, nbits) (unsigned int)__hybrid_bitset_ctz(self, nbits) #endif /* __USE_KOS */ - __DECL_END #endif /* __CC__ */ diff --git a/kos/src/libregex b/kos/src/libregex index 819588aef1..48178c22ab 160000 --- a/kos/src/libregex +++ b/kos/src/libregex @@ -1 +1 @@ -Subproject commit 819588aef17d4dfe08e93e9dec66066fb1693416 +Subproject commit 48178c22abb2df0066496d3cbd9eb2f7af97f57b