diff --git a/src/bitvector.h b/src/bitvector.h
index 302d85819d5b56c20d308e770245cf0caa85f5da..9f7bda875011600c7f26d6203d3a31b17419df0c 100644
--- a/src/bitvector.h
+++ b/src/bitvector.h
@@ -2,8 +2,6 @@
 #define BITVECTOR_H
 
 #include "machine.h"
-#define MOD_PRIME
-
 #include "pike_int_types.h"
 
 #if defined(HAS__BITSCANFORWARD) || defined(HAS__BITSCANFORWARD64) || defined(HAS__BITSCANREVERSE) || defined(HAS__BITSCANREVERSE64)
@@ -14,255 +12,143 @@
 #include <stdlib.h>
 #endif
 
-#define MASK(type, bits)	(~((~((type)0)) >> (bits)))
-#define BITMASK(type, n)	((type)1 << (type)(sizeof(type)*8 - 1 - (n)))
-#define BITN(type, p, n)	(!!((p) & BITMASK(type, n)))
-
-#define TBITMASK(type, n)	((type)1 << (type)((n)))
-#define TBITN(type, p, n)	(!!((p) & TBITMASK(type, n)))
-
-#if 1
-# define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
+#define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
 static const char logTable[256] = {
     0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
     LT(5), LT(6), LT(6), LT(7), LT(7), LT(7), LT(7),
     LT(8), LT(8), LT(8), LT(8), LT(8), LT(8), LT(8), LT(8)
 };
-# undef LT
-#endif
-
-static const unsigned char LMultiplyDeBruijnBitPosition32[32] =
-{
-    31, 22, 30, 21, 18, 10, 29,  2,
-    20, 17, 15, 13,  9,  6, 28,  1,
-    23, 19, 11,  3, 16, 14,  7, 24,
-    12,  4,  8, 25,  5, 26, 27,  0,
-};
-/* maps 2^n - 1 -> n
- */
-static inline unsigned INT32 leading_bit_pos32(const unsigned INT32 v) {
-    return LMultiplyDeBruijnBitPosition32[(((unsigned INT32)((v) * 0x07C4ACDDU)) >> 27)];
-}
-static inline unsigned INT32 trailing_bit_pos32(const unsigned INT32 v) {
-    return 31 - leading_bit_pos32(v);
-}
-#if SIZEOF_LONG == 8 || SIZEOF_LONG_LONG == 8
-
-static const unsigned char TMultiplyDeBruijnBitPosition64[64] = {
-     0, 63,  5, 62,  4, 16, 10, 61,
-     3, 24, 15, 36,  9, 30, 21, 60,
-     2, 12, 26, 23, 14, 45, 35, 43,
-     8, 33, 29, 52, 20, 49, 41, 59,
-     1,  6, 17, 11, 25, 37, 31, 22,
-    13, 27, 46, 44, 34, 53, 50, 42,
-     7, 18, 38, 32, 28, 47, 54, 51,
-    19, 39, 48, 55, 40, 56, 57, 58
-};
-static inline unsigned INT64 trailing_bit_pos64(const unsigned INT64 v) {
-    return TMultiplyDeBruijnBitPosition64[(((unsigned INT64)((v) * 0x07EDD5E59A4E28C2ULL)) >> 58)];
-}
-
-static inline unsigned INT64 leading_bit_pos64(const unsigned INT64 v) {
-    return 63 - trailing_bit_pos64(v);
-}
-#endif
-
-static inline unsigned INT32 round_up32_(unsigned INT32 v) {
-    v |= v >> 1; /* first round down to one less than a power of 2 */
-    v |= v >> 2;
-    v |= v >> 4;
-    v |= v >> 8;
-    v |= v >> 16;
-    return v;
-}
-
-static inline unsigned INT32 round_up32(const unsigned INT32 v) {
-    return round_up32_(v)+1;
-}
-
-static inline unsigned INT32 round_down32(const unsigned INT32 v) {
-    return round_up32(v-1);
-}
-
-static inline unsigned INT64 round_up64_(unsigned INT64 v) {
-    v |= v >> 1; /* first round down to one less than a power of 2 */
-    v |= v >> 2;
-    v |= v >> 4;
-    v |= v >> 8;
-    v |= v >> 16;
-    v |= v >> 32;
-    return v;
-}
-
-static inline unsigned INT64 round_up64(const unsigned INT64 v) {
-    return round_up64_(v) + 1;
-}
-
-static inline unsigned INT64 round_down64(const unsigned INT64 v) {
-    return round_up64(v-1);
-}
+#undef LT
 
+static INLINE unsigned INT32 clz32(unsigned INT32 i) {
 #ifdef HAS___BUILTIN_CLZ
-# define clz32(i) ((unsigned INT32)(!(i) ? 32 : __builtin_clz((unsigned INT32)i)))
+    return i ? __builtin_clz(i) : 32;
 #elif defined(HAS__BIT_SCAN_REVERSE)
-# define clz32(i) ((unsigned INT32)(!(i) ? 32 : _bit_scan_reverse((int)i)))
+    return i ? _bit_scan_reverse(i) : 32;
 #elif defined(HAS___CNTLZ4)
-# define clz32(i) ((unsigned INT32)__cntlz4(i))
+    return i ? __cntlz4(i) : 32;
 #elif defined(HAS__BITSCANREVERSE)
-static inline unsigned INT32 clz32(const unsigned INT32 i) {
-    static unsigned long index;
+    unsigned long index;
     if (_BitScanReverse(&index, (unsigned long)i))
 	return (unsigned INT32)index;
     return 32;
 }
 #else
-static inline unsigned INT32 clz32(const unsigned INT32 y) {
-#ifdef MOD_PRIME
-    register unsigned INT32 t;
+    unsigned INT32 t;
 
-    if ((t = y >> 24)) {
+    if ((t = i >> 24)) {
 	return 8 - logTable[t];
-    } else if ((t = y >> 16)) {
+    } else if ((t = i >> 16)) {
 	return 16 - logTable[t];
-    } else if ((t = y >> 8)) {
+    } else if ((t = i >> 8)) {
 	return 24 - logTable[t];
     } else {
-	return 32 - logTable[y];
+	return 32 - logTable[i];
     }
-#else
-    return y ? leading_bit_pos32(round_up32_(y)) : 32;
 #endif
 }
-#endif
 
-#define clz16(i) ((unsigned INT32)(!(i) ? 16 : clz32((unsigned INT32)i)-16))
-#define clz8(i) ((char)(!(i) ? 8 : clz32((unsigned INT32)i)-24))
+#define clz16(i) (clz32(i) - 16)
+#define clz8(i) (clz32(i) - 24)
 
+static INLINE unsigned INT32 ctz32(unsigned INT32 i) {
 #ifdef HAS___BUILTIN_CTZ
-# define ctz32(i) ((unsigned INT32)(!(i) ? 32 : __builtin_ctz((unsigned INT32)i)))
+    return i ? __builtin_ctz(i) : 32;
 #elif defined(HAS__BIT_SCAN_FORWARD)
-# define ctz32(i) ((unsigned INT32)(!(i) ? 32 : _bit_scan_forward((int)i)))
+    return i ? _bit_scan_forward(i) : 32;
 #elif defined(HAS___CNTTZ4)
-# define ctz32(i) ((unsigned INT32)__cnttz4(i))
+    return i ? __cnttz4(i) : 32;
 #elif defined(HAS__BITSCANFORWARD)
-static inline unsigned INT32 ctz32(const unsigned INT32 i) {
-    static unsigned long index;
+    unsigned long index;
     if (_BitScanForward(&index, (unsigned long)i))
 	return (unsigned INT32)index;
     return 32;
-}
 #else
-static inline unsigned INT32 ctz32(const unsigned INT32 i) {
-#ifdef MOD_PRIME
     /* this table maps (2^n % 37) to n */
-    static const char ctz32Table[37] = {
+    const char ctz32Table[37] = {
 	32, 0, 1, 26, 2, 23, 27, -1, 3, 16, 24, 30, 28, 11, -1, 13, 4, 7, 17,
 	-1, 25, 22, 31, 15, 29, 10, 12, 6, -1, 21, 14, 9, 5, 20, 8, 19, 18
     };
     return (unsigned INT32)ctz32Table[((unsigned INT32)((int)i & -(int)i))%37];
-#else
-    return i ? trailing_bit_pos32((unsigned INT32)((int)i & -(int)i)) : 32;
 #endif
 }
-#endif
 
-#define ctz16(i) ((unsigned INT32)(!(i) ? 16 : ctz32((unsigned INT32)i)-16))
-#define ctz8(i) ((char)(!(i) ? 8 : ctz32((unsigned INT32)i)-24))
+#define ctz16(i) (i ? ctz32(i) : 16)
+#define ctz8(i) (i ? ctz32(i) : 8)
 
-#if SIZEOF_LONG == 8 || SIZEOF_LONG_LONG == 8
 
+static INLINE unsigned INT32 bswap32(unsigned INT32 x) {
+#ifdef HAS___BUILTIN_BSWAP32
+    return __builtin_bswap32(x);
+#elif defined(HAS__BSWAP)
+    return _bswap(x);
+#elif defined(HAS__BYTESWAP_ULONG)
+    return _byteswap_ulong((unsigned long)x);
+#else
+    return (((x & 0xff000000) >> 24) | ((x & 0x000000ff) << 24)
+            | ((x & 0x00ff0000) >> 8) | ((x & 0x0000ff00) << 8));
+#endif
+}
+
+#ifdef INT64
+
+static INLINE unsigned INT32 clz64(unsigned INT64 i) {
 # if SIZEOF_LONG == 8 && defined(HAS___BUILTIN_CLZL)
-#  define clz64(x)	((unsigned INT32)(!(x) ? 64\
-			       : __builtin_clzl((unsigned long)(x))))
+    return i ? __builtin_clzl(i) : 64;
 # elif SIZEOF_LONG_LONG == 8 && defined(HAS___BUILTIN_CLZLL)
-#  define clz64(x)	((unsigned INT32)(!(x) ? 64\
-			       : __builtin_clzll((unsigned long long)(x))))
+    return i ? __builtin_clzll(i) : 64;
 # elif defined(HAS___CNTLZ8)
-#  define clz64(x)	((unsigned INT32)__cntlz8(x))
+    return i ? __cntlz8(i) : 64;
 # elif defined(HAS__BITSCANREVERSE64)
-static inline unsigned INT32 clz64(const unsigned INT64 i) {
-    static unsigned long index;
-    if (_BitScanReverse64(&index, (__int64)i))
-	return (unsigned INT32)index;
+    unsigned long index;
+    if (_BitScanReverse64(&index, i))
+	return index;
     return 64;
-}
 # else
-static inline unsigned INT32 clz64(const unsigned INT64 y) {
-#ifdef MOD_PRIME
-    register unsigned INT64 t;
+    unsigned INT64 t;
 
-    if ((t = y >> 56)) {
+    if ((t = i >> 56)) {
         return 8 - logTable[t];
-    } else if ((t = y >> 48)) {
+    } else if ((t = i >> 48)) {
         return 16 - logTable[t];
-    } else if ((t = y >> 40)) {
+    } else if ((t = i >> 40)) {
         return 24 - logTable[t];
-    } else if ((t = y >> 32)) {
+    } else if ((t = i >> 32)) {
         return 32 - logTable[t];
-    } else if ((t = y >> 24)) {
+    } else if ((t = i >> 24)) {
         return 40 - logTable[t];
-    } else if ((t = y >> 16)) {
+    } else if ((t = i >> 16)) {
         return 48 - logTable[t];
-    } else if ((t = y >> 8)) {
+    } else if ((t = i >> 8)) {
         return 56 - logTable[t];
     } else {
-        return 64 - logTable[y];
+        return 64 - logTable[i];
     }
-#else
-    /* This code comes from http://graphics.stanford.edu/~seander/bithacks.html */
-    return y ? leading_bit_pos64(round_up64(y)) : 64;
 # endif
 }
-# endif
 
+static INLINE unsigned INT32 ctz64(unsigned INT64 i) {
 # if SIZEOF_LONG == 8 && defined(HAS___BUILTIN_CTZL)
-#  define ctz64(x)	((unsigned INT32)(!(x) ? 64\
-			       : __builtin_ctzl((unsigned long)(x))))
-/* #  warning __builtin_ctzl used */
+    return i ? __builtin_ctzl(i) : 64;
 # elif SIZEOF_LONG_LONG == 8 && defined(HAS___BUILTIN_CTZLL)
-#  define ctz64(x)	((unsigned INT32)(!(x) ? 64\
-			       : __builtin_ctzll((unsigned long long)(x))))
-/* #  warning __builtin_ctzll used */
+    return i ? __builtin_ctzll(i) : 64;
 # elif defined(HAS___CNTTZ8)
-#  define ctz64(x)	((unsigned INT32)__cnttz8(x))
-/* #  warning __cnttz8 used */
+    return i ? __cnttz8(i) : 64;
 # elif defined(HAS__BITSCANFORWARD64)
-static inline unsigned INT32 ctz64(const unsigned INT64 i) {
-    static unsigned long index;
-    if (_BitScanForward64(&index, (__int64)i))
-	return (unsigned INT32)index;
+    unsigned long index;
+    if (_BitScanForward64(&index, i))
+	return index;
     return 64;
-}
 # else
-static inline unsigned INT32 ctz64(const unsigned INT64 i) {
-#ifdef MOD_PRIME
     /* this table maps (2^n % 67) to n */
-    static const char ctz64Table[67] = {
+    const char ctz64Table[67] = {
 	64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54, 4, 63, 13,
 	10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55, 47, 5, 32, 63, 38, 14,
 	22, 11, 58, 18, 53, 63, 9, 61, 27, 29, 50, 43, 46, 31, 37, 21, 57, 52,
 	8, 26, 49, 45, 36, 56, 7, 48, 35, 6, 34, 33
     };
     return (unsigned INT32)ctz64Table[((unsigned INT64)((INT64)i & -(INT64)i))%67];
-#else
-    return i ? trailing_bit_pos64((unsigned INT64)((INT64)i & -(INT64)i)) : 64;
-#endif
-}
 # endif
-
-#endif /* SIZEOF_LONG == 8 || SIZEOF_LONG_LONG == 8 */
-
-static INLINE unsigned INT32 bswap32(unsigned INT32 x) {
-#ifdef HAS___BUILTIN_BSWAP32
-    return __builtin_bswap32(x);
-#elif defined(HAS__BSWAP)
-    return _bswap(x);
-#elif defined(HAS__BYTESWAP_ULONG)
-    return _byteswap_ulong((unsigned long)x);
-#else
-    return (((x & 0xff000000) >> 24) | ((x & 0x000000ff) << 24)
-            | ((x & 0x00ff0000) >> 8) | ((x & 0x0000ff00) << 8));
-#endif
 }
 
 static INLINE unsigned INT64 bswap64(unsigned INT64 x) {
@@ -277,6 +163,49 @@ static INLINE unsigned INT64 bswap64(unsigned INT64 x) {
 #endif
 }
 
+static INLINE unsigned INT64 round_up64(unsigned INT64 v) {
+    unsigned INT64 i;
+
+    if (!v) return 0;
+
+    return (unsigned INT64)1 << (64 - clz64(v));
+}
+
+static INLINE unsigned INT32 ffs64(unsigned INT64 v) {
+    return ctz64(v) + 1;
+}
+
+static INLINE unsigned INT32 fls64(unsigned INT64 v) {
+    return 64 - clz64(v);
+}
+
+/* returns -1 for 0 */
+static INLINE unsigned INT32 log2_u64(unsigned INT64 v) {
+    return fls64(v) - 1;
+}
+#endif /* INT64 */
+
+static INLINE unsigned INT32 round_up32(unsigned INT32 v) {
+    unsigned INT32 i;
+
+    if (!v) return 0;
+
+    return 1U << (32 - clz32(v));
+}
+
+static INLINE unsigned INT32 ffs32(unsigned INT32 v) {
+    return ctz32(v) + 1;
+}
+
+static INLINE unsigned INT32 fls32(unsigned INT32 v) {
+    return 32 - clz32(v);
+}
+
+/* returns -1 for 0 */
+static INLINE unsigned INT32 log2_u32(unsigned INT32 v) {
+    return fls32(v) - 1;
+}
+
 #define bswap16(x)     ((unsigned INT16)bswap32((unsigned INT32)x << 16))
 
 #if PIKE_BYTEORDER == 1234