#ifndef FY_BIT64_H
#define FY_BIT64_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdint.h>
#define FY_BIT64(x) ((uint64_t)1 << (x))
#define FY_BIT64_COUNT(_x) (((_x) + 63) / 64)
#define FY_BIT64_SIZE(_x) ((size_t)((((_x) + 63) / 64) * sizeof(uint64_t)))
#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)
#define FY_BIT64_LOWEST(_x) ((unsigned int)__builtin_ctzll((uint64_t)(_x)))
#define FY_BIT64_HIGHEST(_x) ((unsigned int)__builtin_clzll((uint64_t)(_x)))
#define FY_BIT64_POPCNT(_x) ((unsigned int)__builtin_popcountl((uint64_t)(_x)))
#define FY_BIT64_FFS(_x) ((unsigned int)__builtin_ffsll((uint64_t)(_x)))
static inline unsigned int fy_bit64_lowest(uint64_t x)
{
return FY_BIT64_LOWEST(x);
}
static inline unsigned int fy_bit64_highest(uint64_t x)
{
return FY_BIT64_HIGHEST(x);
}
static inline unsigned int fy_bit64_popcnt(uint64_t x)
{
return FY_BIT64_POPCNT(x);
}
static inline unsigned int fy_bit64_ffs(uint64_t x)
{
return FY_BIT64_FFS(x);
}
#else
static inline unsigned int fy_bit64_lowest(uint64_t x)
{
unsigned int c = 0;
if (!(x & 0x00000000ffffffffULL)) { x >>= 32; c += 32; }
if (!(x & 0x000000000000ffffULL)) { x >>= 16; c += 16; }
if (!(x & 0x00000000000000ffULL)) { x >>= 8; c += 8; }
if (!(x & 0x000000000000000fULL)) { x >>= 4; c += 4; }
if (!(x & 0x0000000000000003ULL)) { x >>= 2; c += 2; }
if (!(x & 0x0000000000000001ULL)) { c += 1; }
return c;
}
static inline unsigned int fy_bit64_highest(uint64_t x)
{
unsigned int c = 0;
if (x & 0xffffffff00000000ULL) { x >>= 32; c += 32; }
if (x & 0x00000000ffff0000ULL) { x >>= 16; c += 16; }
if (x & 0x000000000000ff00ULL) { x >>= 8; c += 8; }
if (x & 0x00000000000000f0ULL) { x >>= 4; c += 4; }
if (x & 0x000000000000000cULL) { x >>= 2; c += 2; }
if (x & 0x0000000000000002ULL) { c += 1; }
return c;
}
static inline unsigned int fy_bit64_popcnt(uint64_t x)
{
unsigned int count;
for (count = 0; x; x &= x - 1)
count++;
return count;
}
static inline unsigned int fy_bit64_ffs(uint64_t x)
{
return x ? (fy_bit64_lowest(x) + 1) : 0;
}
#define FY_BIT64_LOWEST(_x) fy_bit64_lowest(_x)
#define FY_BIT64_HIGEST(_x) fy_bit64_highest(_x)
#define FY_BIT64_POPCNT(_x) fy_bit64_popcnt(_x)
#define FY_BIT64_FFS(_x) fy_bit64_ffs(_x)
#endif
#endif