bits: move bit-arithmetics to separate file
authorMarko Kreen <markokr@gmail.com>
Tue, 21 Sep 2010 04:24:38 +0000 (21:24 -0700)
committerMarko Kreen <markokr@gmail.com>
Tue, 21 Sep 2010 04:24:38 +0000 (21:24 -0700)
12 files changed:
doc/mainpage.dox
test/Makefile
test/test_bits.c [new file with mode: 0644]
test/test_common.c
test/test_common.h
test/test_string.c
usual/bits.h [new file with mode: 0644]
usual/cbtree.c
usual/md5.c
usual/misc.h
usual/sha1.c
usual/string.h

index f04608fb1a242398c95555244723d2301192192b..a5561049245d418038fe8b372a5bb5e2aa3dd227 100644 (file)
@@ -45,6 +45,7 @@
  * <tr><td>  <usual/statlist.h>      </td><td>  List with stats   </td></tr>
  * <tr><td>  <usual/strpool.h>       </td><td>  Refcounted strings   </td></tr>
  * <tr><th colspan=2>  Data Processing  </th></tr>
+ * <tr><td>  <usual/bits.h>          </td><td>  Bit arithmetic   </td></tr>
  * <tr><td>  <usual/cfparser.h>      </td><td>  Config parser   </td></tr>
  * <tr><td>  <usual/crc32.h>         </td><td>  CRC32   </td></tr>
  * <tr><td>  <usual/endian.h>        </td><td>  Endianess conversion   </td></tr>
index 8058911a6a5cd8f93aeaace96ea89b9621795275..9573811e7d81b303feb5ab1d6709c689121d3247 100644 (file)
@@ -12,7 +12,7 @@ override DEFS = -DUSUAL_TEST_CONFIG
 OBJS = test_string.o test_crypto.o test_aatree.o test_heap.o \
        test_common.o test_list.o tinytest.o test_cbtree.o \
        test_utf8.o test_strpool.o test_pgutil.o test_regex.o \
-       test_cxalloc.o
+       test_cxalloc.o test_bits.o
 
 test-all: regtest
 
diff --git a/test/test_bits.c b/test/test_bits.c
new file mode 100644 (file)
index 0000000..2a5f2cc
--- /dev/null
@@ -0,0 +1,129 @@
+
+#include <usual/bits.h>
+
+#include "test_common.h"
+
+/*
+ * is_power_of_2
+ */
+
+static void test_pow2(void *p)
+{
+       int_check(is_power_of_2(0), 0);
+       int_check(is_power_of_2(1), 1);
+       int_check(is_power_of_2(2), 1);
+       int_check(is_power_of_2(3), 0);
+end:;
+}
+
+/*
+ * rol
+ */
+
+static void test_rol(void *p)
+{
+       /* rol16 */
+       int_check(rol16(1, 1), 2);
+       int_check(rol16(1, 15), 32768);
+       int_check(rol16(0x8000, 1), 1);
+
+       /* rol32 */
+       int_check(rol32(1, 1), 2);
+       int_check(rol32(0x80000000, 1), 1);
+
+       /* rol64 */
+       ull_check(rol64(1, 1), 2);
+       ull_check(rol64(1, 63), 0x8000000000000000);
+end:;
+}
+
+/*
+ * ror
+ */
+
+static void test_ror(void *p)
+{
+       /* ror16 */
+       int_check(ror16(1, 1), 0x8000);
+       /* ror32 */
+       int_check(ror32(1, 1), 0x80000000);
+       /* ror64 */
+       int_check(ror64(1, 1), 0x8000000000000000);
+end:;
+}
+
+/*
+ * fls
+ */
+
+static void test_fls(void *p)
+{
+       /* fls */
+       int_check(fls(0), 0);
+       int_check(fls(1), 1);
+       int_check(fls(3), 2);
+       int_check(fls((int)-1), 32);
+
+       /* flsl */
+       int_check(flsl(0), 0);
+       int_check(flsl(1), 1);
+       int_check(flsl(3), 2);
+       if (sizeof(long) == 4)
+               int_check(flsl((long)-1), 32);
+       else
+               int_check(flsl((long)-1), 64);
+
+       /* flsll */
+       int_check(flsll(0), 0);
+       int_check(flsll(1), 1);
+       int_check(flsll(3), 2);
+       int_check(flsll((long long)-1), 64);
+end:;
+}
+
+/*
+ * ffs
+ */
+
+static void test_ffs(void *p)
+{
+       /* ffs */
+       int_check(ffs(0), 0);
+       int_check(ffs(1), 1);
+       int_check(ffs(3), 1);
+       int_check(ffs((int)-1), 1);
+       int_check(ffs(ror32(1,1)), 32);
+
+       /* flsl */
+       int_check(ffsl(0), 0);
+       int_check(ffsl(1), 1);
+       int_check(ffsl(3), 1);
+       int_check(ffsl((long)-1), 1);
+       if (sizeof(long) == 4)
+               int_check(ffsl(ror32(1,1)), 32);
+       else
+               int_check(ffsl(ror64(1,1)), 64);
+
+       /* ffsll */
+       int_check(ffsll(0), 0);
+       int_check(ffsll(1), 1);
+       int_check(ffsll(3), 1);
+       int_check(ffsll((long long)-1), 1);
+       int_check(ffsll(ror64(1,1)), 64);
+end:;
+}
+
+
+/*
+ * Describe
+ */
+
+struct testcase_t bits_tests[] = {
+       { "is_power_of_2", test_pow2 },
+       { "rol", test_rol },
+       { "ror", test_ror },
+       { "ffs", test_ffs },
+       { "fls", test_fls },
+       END_OF_TESTCASES
+};
+
index e3cea2e514d6488db8534e5bc9b773e990ea62da..c176397d9f6cf064a7c705057243056c4cad34c5 100644 (file)
@@ -4,6 +4,7 @@
 
 struct testgroup_t groups[] = {
        { "aatree/", aatree_tests },
+       { "bits/", bits_tests },
        { "cxalloc/", cxalloc_tests },
        { "cbtree/", cbtree_tests },
        { "crypto/", crypto_tests },
index ae48cc278288bf325048636f7114410f8da79c0c..b034319d18cecc925653290ad07c534bd8a96469 100644 (file)
@@ -6,6 +6,7 @@
 
 #define str_check(a, b) tt_str_op(a, ==, b)
 #define int_check(a, b) tt_int_op(a, ==, b)
+#define ull_check(a, b) tt_assert_op_type(a, ==, b, unsigned long long, "%llu")
 
 extern struct testcase_t aatree_tests[];
 extern struct testcase_t cbtree_tests[];
@@ -18,4 +19,5 @@ extern struct testcase_t strpool_tests[];
 extern struct testcase_t pgutil_tests[];
 extern struct testcase_t regex_tests[];
 extern struct testcase_t cxalloc_tests[];
+extern struct testcase_t bits_tests[];
 
index 40fd01d714b483129ca14e14605e9ab865a8b031..dfbf79f423b6ba483293b85cbf1c5f17b93d452e 100644 (file)
@@ -82,40 +82,6 @@ static void test_strerror_r(void *p)
 end:;
 }
 
-/*
- * fls
- */
-
-static void test_fls(void *p)
-{
-       int_check(fls(0), 0);
-       int_check(fls(1), 1);
-       int_check(fls(3), 2);
-       int_check(fls((int)-1), 32);
-end:;
-}
-
-static void test_flsl(void *p)
-{
-       int_check(flsl(0), 0);
-       int_check(flsl(1), 1);
-       int_check(flsl(3), 2);
-       if (sizeof(long) == 4)
-               int_check(flsl((long)-1), 32);
-       else
-               int_check(flsl((long)-1), 64);
-end:;
-}
-
-static void test_flsll(void *p)
-{
-       int_check(flsll(0), 0);
-       int_check(flsll(1), 1);
-       int_check(flsll(3), 2);
-       int_check(flsll((long long)-1), 64);
-end:;
-}
-
 /*
  * memrchr
  */
@@ -203,9 +169,6 @@ struct testcase_t string_tests[] = {
        { "strlcpy", test_strlcpy },
        { "strlcat", test_strlcat },
        { "strerror_r", test_strerror_r },
-       { "fls", test_fls },
-       { "flsl", test_flsl },
-       { "flsll", test_flsll },
        { "memrchr", test_memrchr },
        { "basename", test_basename },
        { "dirname", test_dirname },
diff --git a/usual/bits.h b/usual/bits.h
new file mode 100644 (file)
index 0000000..fd2f3ae
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2009  Marko Kreen
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/** @file
+ * Bit arithmetics.
+ *
+ * - is_power_of_2
+ * - ffs, ffsl, ffsll
+ * - fls, flsl, flsll
+ * - rol16, rol32, rol64
+ * - ror16, ror32, ror64
+ */
+#ifndef _USUAL_MISC_H_
+#define _USUAL_MISC_H_
+
+#include <usual/base.h>
+
+#include <string.h>
+
+/** Checks if integer has only one bit set */
+static inline int is_power_of_2(int n)
+{
+       return (n > 0) && !(n & (n - 1));
+}
+
+/*
+ * Single-eval and type-safe rol/ror
+ */
+
+/** Rotate 16-bit int to left */
+static inline uint16_t rol16(uint16_t v, int s)
+{
+       return (v << s) | (v >> (16 - s));
+}
+/** Rotate 32-bit int to left */
+static inline uint32_t rol32(uint32_t v, int s)
+{
+       return (v << s) | (v >> (32 - s));
+}
+/** Rotate 64-bit int to left */
+static inline uint64_t rol64(uint64_t v, int s)
+{
+       return (v << s) | (v >> (64 - s));
+}
+
+/** Rotate 16-bit int to right */
+static inline uint16_t ror16(uint16_t v, int s) { return rol16(v, 16 - s); }
+
+/** Rotate 32-bit int to right */
+static inline uint32_t ror32(uint32_t v, int s) { return rol32(v, 32 - s); }
+
+/** Rotate 64-bit int to right */
+static inline uint64_t ror64(uint64_t v, int s) { return rol64(v, 64 - s); }
+
+/*
+ * fls(int)
+ * flsl(long)
+ * flsll(long long)
+ *
+ *   find MSB bit set, 1-based ofs, 0 if arg == 0
+ */
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#define _FLS(sfx, type) \
+       return (x == 0) ? 0 : ((8*sizeof(type)) - __builtin_clz ## sfx(x))
+#else
+#define _FLS(sfx, type) \
+       unsigned int bit; \
+       if (x == 0) return 0; \
+       /* count from smallest bit, assuming small values */ \
+       for (bit = 1; x > 1; bit++) x >>= 1; \
+       return bit
+#endif
+
+#ifndef HAVE_FLS
+/** Compat: Find last (MSB) set bit, 1-based ofs, 0 if arg == 0 */
+static inline int fls(int x) { _FLS(, int); }
+#endif
+#ifndef HAVE_FLSL
+/** Compat: Find last (MSB) set bit, 1-based ofs, 0 if arg == 0 */
+static inline int flsl(long x) { _FLS(l, long); }
+#endif
+#ifndef HAVE_FLSLL
+/** Compat: Find last (MSB) set bit, 1-based ofs, 0 if arg == 0 */
+static inline int flsll(long long x) { _FLS(ll, long long); }
+#endif
+#undef _FLS
+
+#endif
+
index c97dfe531763007a5819999b48a819f17bf97682..69cdd5b1bb8174d9eed3c43442c979f922519332 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <usual/cbtree.h>
 
-#include <usual/string.h>
+#include <usual/bits.h>
 
 /*
  * - Childs are either other nodes or user pointers.
index 29f0f61f3495f60fb87ec6d8d4c17b389b5cdfc4..bb3ef4ef7234ab69c299e5f51d2c0ccde5e9ef14 100644 (file)
@@ -19,8 +19,7 @@
 #include <usual/md5.h>
 
 #include <usual/endian.h>
-#include <usual/misc.h>
-#include <string.h>
+#include <usual/bits.h>
 
 /*
  * Support functions.
index 81484d041da73e2f5126e118ded51be4094e0230..b3a81cb6a587483231f53fc77f6d7d8968ef43ca 100644 (file)
         | ((unsigned int)(unsigned char)(d) << 24))
 #endif
 
-/** Checks if integer has only one bit set */
-static inline int is_power_of_2(int n)
-{
-       return (n > 0) && !(n & (n - 1));
-}
-
 #if defined(__i386__) || defined(__x86_64__)
 #define mb()  asm volatile("mfence":::"memory")
 #define rmb() asm volatile("lfence":::"memory")
 #define wmb() asm volatile("sfence":::"memory")
 #endif
 
-/*
- * Single-eval and type-safe rol/ror
- */
-
-/** Rotate 16-bit int to left */
-static inline uint16_t rol16(uint16_t v, int s)
-{
-       return (v << s) | (v >> (16 - s));
-}
-/** Rotate 32-bit int to left */
-static inline uint32_t rol32(uint32_t v, int s)
-{
-       return (v << s) | (v >> (32 - s));
-}
-/** Rotate 64-bit int to left */
-static inline uint64_t rol64(uint64_t v, int s)
-{
-       return (v << s) | (v >> (64 - s));
-}
-/** Rotate 16-bit int to right */
-static inline uint16_t ror16(uint16_t v, int s) { return rol16(v, 16 - s); }
-/** Rotate 32-bit int to right */
-static inline uint32_t ror32(uint32_t v, int s) { return rol32(v, 32 - s); }
-/** Rotate 64-bit int to right */
-static inline uint64_t ror64(uint64_t v, int s) { return rol64(v, 64 - s); }
-
 #endif
 
index 1b0c991bddf88ac052aab0641925a870e09183f5..eea7c8a0b0de101c5b320fea94d96a0f1c40fb2b 100644 (file)
@@ -19,7 +19,7 @@
 #include <usual/sha1.h>
 
 #include <usual/endian.h>
-#include <usual/misc.h>
+#include <usual/bits.h>
 
 #define bufpos(ctx) ((ctx)->nbytes & (SHA1_BLOCK_SIZE - 1))
 
index 03e0e50004fdecab3893d7094cd6fe96bf56c3a4..4137ec8101d97abf4d528b8773b63cc50d0ea03a 100644 (file)
@@ -70,41 +70,6 @@ size_t strlcpy(char *dst, const char *src, size_t n);
 size_t strlcat(char *dst, const char *src, size_t n);
 #endif
 
-/*
- * fls(int)
- * flsl(long)
- * flsll(long long)
- *
- *   find MSB bit set, 1-based ofs, 0 if arg == 0
- */
-
-#if defined(__GNUC__) && (__GNUC__ >= 4)
-#define _FLS(sfx, type) \
-       return (x == 0) ? 0 : ((8*sizeof(type)) - __builtin_clz ## sfx(x))
-#else
-#define _FLS(sfx, type) \
-       unsigned int bit; \
-       if (x == 0) return 0; \
-       /* count from smallest bit, assuming small values */ \
-       for (bit = 1; x > 1; bit++) x >>= 1; \
-       return bit
-#endif
-
-#ifndef HAVE_FLS
-/** Compat: Find last (MSB) set bit, 1-based ofs, 0 if arg == 0 */
-static inline int fls(int x) { _FLS(, int); }
-#endif
-#ifndef HAVE_FLSL
-/** Compat: Find last (MSB) set bit, 1-based ofs, 0 if arg == 0 */
-static inline int flsl(long x) { _FLS(l, long); }
-#endif
-#ifndef HAVE_FLSLL
-/** Compat: Find last (MSB) set bit, 1-based ofs, 0 if arg == 0 */
-static inline int flsll(long long x) { _FLS(ll, long long); }
-#endif
-#undef _FLS
-
-
 #ifndef HAVE_MEMRCHR
 #define memrchr(a,b,c) usual_memrchr(a,b,c)
 /** Compat: find byte in reverse direction */