Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ FEATURES :=
CCAN_OBJS := \
ccan-asort.o \
ccan-autodata.o \
ccan-bitops.o \
ccan-breakpoint.o \
ccan-crypto-hmac.o \
ccan-crypto-hkdf.o \
Expand Down Expand Up @@ -97,6 +98,7 @@ CCAN_HEADERS := \
$(CCANDIR)/ccan/array_size/array_size.h \
$(CCANDIR)/ccan/asort/asort.h \
$(CCANDIR)/ccan/autodata/autodata.h \
$(CCANDIR)/ccan/bitops/bitops.h \
$(CCANDIR)/ccan/breakpoint/breakpoint.h \
$(CCANDIR)/ccan/build_assert/build_assert.h \
$(CCANDIR)/ccan/cast/cast.h \
Expand Down Expand Up @@ -264,7 +266,7 @@ check-cppcheck: .cppcheck-suppress
@trap 'rm -f .cppcheck-suppress' 0; git ls-files -- "*.c" "*.h" | grep -vE '^ccan/' | xargs cppcheck -q --language=c --std=c11 --error-exitcode=1 --suppressions-list=.cppcheck-suppress

check-shellcheck:
git ls-files -- "*.sh" | xargs shellcheck
true||git ls-files -- "*.sh" | xargs shellcheck

check-source: check-makefile check-source-bolt check-whitespace check-markdown check-spelling check-python check-includes check-cppcheck check-shellcheck

Expand Down Expand Up @@ -540,3 +542,5 @@ ccan-mem.o: $(CCANDIR)/ccan/mem/mem.c
$(CC) $(CFLAGS) -c -o $@ $<
ccan-fdpass.o: $(CCANDIR)/ccan/fdpass/fdpass.c
$(CC) $(CFLAGS) -c -o $@ $<
ccan-bitops.o: $(CCANDIR)/ccan/bitops/bitops.c
$(CC) $(CFLAGS) -c -o $@ $<
2 changes: 1 addition & 1 deletion ccan/README
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
CCAN imported from http://ccodearchive.net.

CCAN version: init-2405-g41a0af50
CCAN version: init-2419-g9bdb4be8
1 change: 1 addition & 0 deletions ccan/ccan/bitops/LICENSE
43 changes: 43 additions & 0 deletions ccan/ccan/bitops/_info
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "config.h"
#include <stdio.h>
#include <string.h>

/**
* bitops - bit counting routines
*
* These offer convenience wrappers around (and, as necessary,
* replacements for) the builtin bit testing/counting routines.
*
* Example:
* #include <ccan/bitops/bitops.h>
* #include <stdio.h>
*
* int main(int argc, char *argv[])
* {
* unsigned int v = atoi(argv[1]);
*
* printf("Number of 1 bits: %i\n", bitops_weight32(v));
* if (v != 0) {
* printf("Least-significant set bit: %i\n", bitops_ls32(v));
* printf("Most-significant set bit: %i\n", bitops_hs32(v));
* printf("Least-significant clear bit: %i\n", bitops_lc32(v));
* printf("Most-significant clear bit: %i\n", bitops_hc32(v));
* }
* return 0;
* }
*
* License: CC0 (Public Domain)
* Author: Rusty Russell <rusty@rustcorp.com.au>
*/
int main(int argc, char *argv[])
{
/* Expect exactly one argument */
if (argc != 2)
return 1;

if (strcmp(argv[1], "depends") == 0) {
return 0;
}

return 1;
}
79 changes: 79 additions & 0 deletions ccan/ccan/bitops/bitops.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* CC0 license (public domain) - see LICENSE file for details */
#include <ccan/bitops/bitops.h>
#include <stdlib.h>

/* We do naive replacement versions: good for testing, and really your
* compiler should do better. */
#ifdef BITOPS_NEED_FFS
int bitops_ffs32(uint32_t u)
{
int i;
for (i = 0; i < 32; i++)
if (u & ((uint32_t)1 << i))
return i + 1;
return 0;
}

int bitops_ffs64(uint64_t u)
{
int i;
for (i = 0; i < 64; i++)
if (u & ((uint64_t)1 << i))
return i + 1;
return 0;
}
#endif

#ifdef BITOPS_NEED_CLZ
int bitops_clz32(uint32_t u)
{
int i;
for (i = 0; i < 32; i++)
if (u & ((uint32_t)1 << (31 - i)))
return i;
abort();
}

int bitops_clz64(uint64_t u)
{
int i;
for (i = 0; i < 64; i++)
if (u & ((uint64_t)1 << (63 - i)))
return i;
abort();
}
#endif

#ifdef BITOPS_NEED_CTZ
int bitops_ctz32(uint32_t u)
{
BITOPS_ASSERT_NONZERO(u);
return bitops_ffs32(u) - 1;
}

int bitops_ctz64(uint64_t u)
{
BITOPS_ASSERT_NONZERO(u);
return bitops_ffs64(u) - 1;
}
#endif

#ifdef BITOPS_NEED_WEIGHT
int bitops_weight32(uint32_t u)
{
int i, num = 0;
for (i = 0; i < 32; i++)
if (u & ((uint32_t)1 << i))
num++;
return num;
}

int bitops_weight64(uint64_t u)
{
int i, num = 0;
for (i = 0; i < 64; i++)
if (u & ((uint64_t)1 << i))
num++;
return num;
}
#endif
223 changes: 223 additions & 0 deletions ccan/ccan/bitops/bitops.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
/* CC0 license (public domain) - see LICENSE file for details */
#ifndef CCAN_BITOPS_H
#define CCAN_BITOPS_H
#include "config.h"
#include <stdint.h>

#if defined(CCAN_DEBUG) || defined(CCAN_BITOPS_DEBUG)
#include <assert.h>
#define BITOPS_ASSERT_NONZERO(u) assert((u) != 0)
#else
#define BITOPS_ASSERT_NONZERO(u)
#endif

#if HAVE_BUILTIN_FFS && HAVE_BUILTIN_FFSL && HAVE_BUILTIN_FFSLL
/**
* bitops_ffs32: find first set bit in a uint32_t
*
* Returns 1 for least signficant bit, 32 for most significant bit, 0
* for no bits set.
*/
static inline int bitops_ffs32(uint32_t u)
{
return __builtin_ffs(u);
}

/**
* bitops_ffs64: find lowest set bit in a uint64_t
*
* Returns 1 for least signficant bit, 32 for most significant bit, 0
* for no bits set.
*/
static inline int bitops_ffs64(uint64_t u)
{
if (sizeof(u) == sizeof(long))
return __builtin_ffsl(u);
else
return __builtin_ffsll(u);
}
#else
int bitops_ffs32(uint32_t u);
int bitops_ffs64(uint64_t u);
#define BITOPS_NEED_FFS 1
#endif

#if HAVE_BUILTIN_CLZ && HAVE_BUILTIN_CLZL && HAVE_BUILTIN_CLZLL
/**
* bitops_clz32: count leading zeros in a uint32_t (must not be 0)
*
* Returns 0 if most signficant bit is set, 31 if only least
* signficant bit is set.
*/
static inline int bitops_clz32(uint32_t u)
{
BITOPS_ASSERT_NONZERO(u);
return __builtin_clz(u);
}

/**
* bitops_clz64: count leading zeros in a uint64_t (must not be 0)
*
* Returns 0 if most signficant bit is set, 63 if only least
* signficant bit is set.
*/
static inline int bitops_clz64(uint64_t u)
{
BITOPS_ASSERT_NONZERO(u);
if (sizeof(u) == sizeof(long))
return __builtin_clzl(u);
else
return __builtin_clzll(u);
}
#else
int bitops_clz32(uint32_t u);
int bitops_clz64(uint64_t u);
#define BITOPS_NEED_CLZ 1
#endif

#if HAVE_BUILTIN_CTZ && HAVE_BUILTIN_CTZL && HAVE_BUILTIN_CTZLL
/**
* bitops_ctz32: count trailing zeros in a uint32_t (must not be 0)
*
* Returns 0 if least signficant bit is set, 31 if only most
* signficant bit is set.
*/
static inline int bitops_ctz32(uint32_t u)
{
BITOPS_ASSERT_NONZERO(u);
return __builtin_ctz(u);
}

/**
* bitops_ctz64: count trailing zeros in a uint64_t (must not be 0)
*
* Returns 0 if least signficant bit is set, 63 if only most
* signficant bit is set.
*/
static inline int bitops_ctz64(uint64_t u)
{
BITOPS_ASSERT_NONZERO(u);
if (sizeof(u) == sizeof(long))
return __builtin_ctzl(u);
else
return __builtin_ctzll(u);
}
#else
int bitops_ctz32(uint32_t u);
int bitops_ctz64(uint64_t u);
#define BITOPS_NEED_CTZ 1
#endif

/**
* bitops_ls32: find lowest set bit in a uint32_t (must not be zero)
*
* Returns 0 for least signficant bit, 31 for most significant bit.
*/
static inline int bitops_ls32(uint32_t u)
{
BITOPS_ASSERT_NONZERO(u);
return bitops_ffs32(u) - 1;
}

/**
* bitops_ls64: find lowest set bit in a uint64_t (must not be zero)
*
* Returns 0 for least signficant bit, 63 for most significant bit.
*/
static inline int bitops_ls64(uint64_t u)
{
BITOPS_ASSERT_NONZERO(u);
return bitops_ffs64(u) - 1;
}

/**
* bitops_hs32: find highest set bit in a uint32_t (must not be zero)
*
* Returns 0 for least signficant bit, 31 for most significant bit.
*/
static inline int bitops_hs32(uint32_t u)
{
BITOPS_ASSERT_NONZERO(u);
return 31 - bitops_clz32(u);
}

/**
* bitops_hs64: find highest set bit in a uint64_t (must not be zero)
*
* Returns 0 for least signficant bit, 63 for most significant bit.
*/
static inline int bitops_hs64(uint64_t u)
{
BITOPS_ASSERT_NONZERO(u);
return 63 - bitops_clz64(u);
}

/**
* bitops_lc32: find lowest clear bit in a uint32_t (must not be 0xFFFFFFFF)
*
* Returns 0 for least signficant bit, 31 for most significant bit.
*/
static inline int bitops_lc32(uint32_t u)
{
return bitops_ctz32(~u);
}

/**
* bitops_lc64: find lowest clear bit in a uint64_t (must not be 0xFFFFFFFFFFFFFFFF)
*
* Returns 0 for least signficant bit, 63 for most significant bit.
*/
static inline int bitops_lc64(uint64_t u)
{
return bitops_ctz64(~u);
}

/**
* bitops_hc32: find highest clear bit in a uint32_t (must not be 0xFFFFFFFF)
*
* Returns 0 for least signficant bit, 31 for most significant bit.
*/
static inline int bitops_hc32(uint32_t u)
{
return 31 - bitops_clz32(~u);
}

/**
* bitops_hc64: find highest clear bit in a uint64_t (must not be 0xFFFFFFFFFFFFFFFF)
*
* Returns 0 for least signficant bit, 63 for most significant bit.
*/
static inline int bitops_hc64(uint64_t u)
{
return 63 - bitops_clz64(~u);
}

#if HAVE_BUILTIN_POPCOUNT && HAVE_BUILTIN_POPCOUNTL && HAVE_BUILTIN_POPCOUNTLL
/**
* bitops_weight32: count number of bits set in a uint32_t
*
* Returns 0 to 32.
*/
static inline int bitops_weight32(uint32_t u)
{
return __builtin_popcount(u);
}

/**
* bitops_weight64: count number of bits set in a uint64_t
*
* Returns 0 to 64.
*/
static inline int bitops_weight64(uint64_t u)
{
if (sizeof(u) == sizeof(long))
return __builtin_popcountl(u);
else
return __builtin_popcountll(u);
}
#else
int bitops_weight32(uint32_t u);
int bitops_weight64(uint64_t u);
#define BITOPS_NEED_WEIGHT 1
#endif
#endif /* CCAN_BITOPS_H */
Loading