]> mj.ucw.cz Git - libucw.git/commitdiff
Implemented ffs() and unified it with fls() to bitops.h.
authorMartin Mares <mj@ucw.cz>
Thu, 22 Sep 2005 20:44:51 +0000 (20:44 +0000)
committerMartin Mares <mj@ucw.cz>
Thu, 22 Sep 2005 20:44:51 +0000 (20:44 +0000)
lib/Makefile
lib/bit-ffs.c [new file with mode: 0644]
lib/bit-fls.c [new file with mode: 0644]
lib/bitops.h [new file with mode: 0644]
lib/bitops.t [new file with mode: 0644]
lib/log2.c [deleted file]

index 734ef01a2301cfe4d1bed28bfdeb402c54acf9ca..73501c7b55a80c791881fb4959ada6c0e07510de 100644 (file)
@@ -17,7 +17,8 @@ LIBUCW_MODS= \
        fb-file carefulio fb-mem fb-temp fb-mmap fb-limfd fb-buffer \
        str_ctype str_upper str_lower unicode-utf8 stkstring \
        wildmatch wordsplit ctmatch patimatch patmatch regex \
-       prime random timer log2 randomkey \
+       prime random timer randomkey \
+       bit-ffs bit-fls \
        db \
        url \
        mainloop exitstatus runcmd sighandler \
@@ -81,6 +82,7 @@ $(o)/lib/unicode-utf8.test: $(o)/lib/unicode-utf8-t
 $(o)/lib/hash-test.test: $(o)/lib/hash-test
 $(o)/lib/mempool.test: $(o)/lib/mempool-fmt-t $(o)/lib/mempool-str-t
 $(o)/lib/stkstring.test: $(o)/lib/stkstring-t
+$(o)/lib/bitops.test: $(o)/lib/bit-ffs-t $(o)/lib/bit-fls-t
 
 INCLUDES+=$(o)/lib/.include-stamp
 $(o)/lib/.include-stamp: $(addprefix $(s)/lib/,$(LIBUCW_INCLUDES))
diff --git a/lib/bit-ffs.c b/lib/bit-ffs.c
new file mode 100644 (file)
index 0000000..8a9198d
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *     UCW Library -- Find Lowest Set Bit
+ *
+ *     (c) 2005 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#include "lib/lib.h"
+#include "lib/bitops.h"
+
+/* Just a table, the rest is in bitops.h */
+
+const byte ffs_table[] = {
+  0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int main(void)
+{
+  uns i;
+  while (scanf("%x", &i) == 1)
+    printf("%d\n", bit_ffs(i));
+  return 0;
+}
+
+#endif
diff --git a/lib/bit-fls.c b/lib/bit-fls.c
new file mode 100644 (file)
index 0000000..6a6227d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *     UCW Library -- Find Highest Set Bit
+ *
+ *     (c) 1997-2005 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#include "lib/lib.h"
+#include "lib/bitops.h"
+
+int
+bit_fls(u32 x)
+{
+  uns l;
+
+  if (!x)
+       return -1;
+
+  l = 0;
+  if (x & 0xffff0000) { l += 16; x &= 0xffff0000; }
+  if (x & 0xff00ff00) { l += 8;  x &= 0xff00ff00; }
+  if (x & 0xf0f0f0f0) { l += 4;  x &= 0xf0f0f0f0; }
+  if (x & 0xcccccccc) { l += 2;  x &= 0xcccccccc; }
+  if (x & 0xaaaaaaaa) l++;
+  return l;
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int main(void)
+{
+  uns i;
+  while (scanf("%x", &i) == 1)
+    printf("%d\n", bit_fls(i));
+  return 0;
+}
+
+#endif
diff --git a/lib/bitops.h b/lib/bitops.h
new file mode 100644 (file)
index 0000000..c1e6371
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *     UCW Library -- Bit Operations
+ *
+ *     (c) 2005 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#ifndef _UCW_BITOPS_H
+#define _UCW_BITOPS_H
+
+/* Find highest bit set (i.e., the floor of the binary logarithm) (bit-fls.c) */
+
+int bit_fls(u32 x);            /* bit_fls(0)=-1 */
+
+/* Find lowest bit set, undefined for zero argument (bit-ffs.c) */
+
+extern const byte ffs_table[256];
+
+#ifdef __pentium4              /* On other ia32 machines, the C version is faster */
+
+static inline uns bit_ffs(uns w)
+{
+  asm("bsfl %1,%0" :"=r" (w) :"rm" (w));
+  return w;
+}
+
+#else
+
+static inline uns bit_ffs(uns w)
+{
+  uns b = (w & 0xffff) ? 0 : 16;
+  b += ((w >> b) & 0xff) ? 0 : 8;
+  return b + ffs_table[(w >> b) & 0xff];
+}
+
+#endif
+
+#endif
diff --git a/lib/bitops.t b/lib/bitops.t
new file mode 100644 (file)
index 0000000..abf350e
--- /dev/null
@@ -0,0 +1,53 @@
+# Tests for bitops modules
+
+Run:   obj/lib/bit-ffs-t
+In:    1
+       2
+       3
+       4
+       5
+       6
+       12345678
+       23030300
+       23030000
+       23000000
+       40000000
+       80000000
+Out:   0
+       1
+       0
+       2
+       0
+       1
+       3
+       8
+       16
+       24
+       30
+       31
+
+Run:   obj/lib/bit-fls-t
+In:    1
+       2
+       3
+       4
+       5
+       6
+       12345678
+       23030303
+       03030303
+       00030303
+       00000303
+       0fedcba9
+Out:   0
+       1
+       1
+       2
+       2
+       2
+       28
+       29
+       25
+       17
+       9
+       27
diff --git a/lib/log2.c b/lib/log2.c
deleted file mode 100644 (file)
index 8fedaf6..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *     UCW Library -- Binary Logarithm
- *
- *     (c) 1997 Martin Mares <mj@ucw.cz>
- *
- *     This software may be freely distributed and used according to the terms
- *     of the GNU Lesser General Public License.
- */
-
-#include "lib/lib.h"
-
-int
-fls(u32 x)
-{
-  uns l;
-
-  if (!x)
-       return 0;
-
-  l = 0;
-  if (x & 0xffff0000) { l += 16; x &= 0xffff0000; }
-  if (x & 0xff00ff00) { l += 8;  x &= 0xff00ff00; }
-  if (x & 0xf0f0f0f0) { l += 4;  x &= 0xf0f0f0f0; }
-  if (x & 0xcccccccc) { l += 2;  x &= 0xcccccccc; }
-  if (x & 0xaaaaaaaa) l++;
-  return l;
-}