#include <stdbit.h>
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <sys/debug.h>
#include <sys/sysmacros.h>
typedef enum {
STDBIT_TEST_U8 = 1 << 0,
STDBIT_TEST_U16 = 1 << 1,
STDBIT_TEST_U32 = 1 << 2,
STDBIT_TEST_U64 = 1 << 3
} stdbit_test_type_t;
#define STDBIT_TEST_64P (STDBIT_TEST_U64)
#define STDBIT_TEST_32P (STDBIT_TEST_U32 | STDBIT_TEST_64P)
#define STDBIT_TEST_16P (STDBIT_TEST_U16 | STDBIT_TEST_32P)
#define STDBIT_TEST_ALL (STDBIT_TEST_U8 | STDBIT_TEST_16P)
typedef struct {
const char *so_name;
unsigned int (*so_uc)(unsigned char);
unsigned int (*so_us)(unsigned short);
unsigned int (*so_ui)(unsigned int);
unsigned int (*so_ul)(unsigned long);
unsigned int (*so_ull)(unsigned long long);
int32_t so_delta[3];
} stdbit_ops_t;
typedef struct {
stdbit_test_type_t st_types;
uint64_t st_val;
uint64_t st_res;
} stdbit_test_t;
static const stdbit_ops_t stdbit_clz_ops = {
.so_name = "Count Leading Zeros",
.so_uc = stdc_leading_zeros_uc,
.so_us = stdc_leading_zeros_us,
.so_ui = stdc_leading_zeros_ui,
.so_ul = stdc_leading_zeros_ul,
.so_ull = stdc_leading_zeros_ull,
.so_delta = { 8, 16, 32 }
};
static const stdbit_test_t stdbit_clz_tests[] = { {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = 8
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = UINT8_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x42,
.st_res = 1
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 1,
.st_res = 7
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT16_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x7777,
.st_res = 1
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x800,
.st_res = 4
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x080,
.st_res = 8
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x008,
.st_res = 12
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT32_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x23000000,
.st_res = 2
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x23000032,
.st_res = 2
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x400000000,
.st_res = 29
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT64_MAX,
.st_res = 0
} };
static const stdbit_ops_t stdbit_clo_ops = {
.so_name = "Count Leading Ones",
.so_uc = stdc_leading_ones_uc,
.so_us = stdc_leading_ones_us,
.so_ui = stdc_leading_ones_ui,
.so_ul = stdc_leading_ones_ul,
.so_ull = stdc_leading_ones_ull,
};
static const stdbit_test_t stdbit_clo_tests[] = { {
.st_types = STDBIT_TEST_U8,
.st_val = UINT8_MAX,
.st_res = 8
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x42,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U8,
.st_val = 0xe0,
.st_res = 3
}, {
.st_types = STDBIT_TEST_U8,
.st_val = 0xfc,
.st_res = 6
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT8_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x142,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U16,
.st_val = UINT16_MAX,
.st_res = 16
}, {
.st_types = STDBIT_TEST_U16,
.st_val = 0xc0ff,
.st_res = 2
}, {
.st_types = STDBIT_TEST_U16,
.st_val = 0xf88f,
.st_res = 5
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0x12345678,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U32,
.st_val = UINT32_MAX,
.st_res = 32
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0x87654321,
.st_res = 1
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0xff7ff7ff,
.st_res = 8
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0xfffffeee,
.st_res = 23
}, {
.st_types = STDBIT_TEST_U64,
.st_val = UINT64_MAX,
.st_res = 64
}, {
.st_types = STDBIT_TEST_U64,
.st_val = 0x8000000000000000,
.st_res = 1
}, {
.st_types = STDBIT_TEST_U64,
.st_val = 0xffffffff80000000,
.st_res = 33
}, {
.st_types = STDBIT_TEST_U64,
.st_val = 0xffffffffffff9999,
.st_res = 49
} };
static const stdbit_ops_t stdbit_ctz_ops = {
.so_name = "Count Trailing Zeros",
.so_uc = stdc_trailing_zeros_uc,
.so_us = stdc_trailing_zeros_us,
.so_ui = stdc_trailing_zeros_ui,
.so_ul = stdc_trailing_zeros_ul,
.so_ull = stdc_trailing_zeros_ull,
};
static const stdbit_test_t stdbit_ctz_tests[] = { {
.st_types = STDBIT_TEST_U8,
.st_val = 0,
.st_res = 8
}, {
.st_types = STDBIT_TEST_U16,
.st_val = 0,
.st_res = 16
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0,
.st_res = 32
}, {
.st_types = STDBIT_TEST_U64,
.st_val = 0,
.st_res = 64
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = UINT8_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x1,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x4,
.st_res = 2
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x80,
.st_res = 7
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0xff60,
.st_res = 5
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x8ad0,
.st_res = 4
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x2300,
.st_res = 8
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x42000000,
.st_res = 25
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x99887700,
.st_res = 8
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT32_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0xaa00000000000000,
.st_res = 57
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0xbadcaf0000000000,
.st_res = 40
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT64_MAX,
.st_res = 0
} };
static const stdbit_ops_t stdbit_cto_ops = {
.so_name = "Count Trailing Ones",
.so_uc = stdc_trailing_ones_uc,
.so_us = stdc_trailing_ones_us,
.so_ui = stdc_trailing_ones_ui,
.so_ul = stdc_trailing_ones_ul,
.so_ull = stdc_trailing_ones_ull,
};
static const stdbit_test_t stdbit_cto_tests[] = { {
.st_types = STDBIT_TEST_ALL,
.st_val = UINT8_MAX,
.st_res = 8
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 3,
.st_res = 2
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x7e,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x7f,
.st_res = 7
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT16_MAX,
.st_res = 16
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x8765,
.st_res = 1
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0xcdef,
.st_res = 4
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x9fff,
.st_res = 13
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT32_MAX,
.st_res = 32
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x85ab91ff,
.st_res = 9
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x7fffffff,
.st_res = 31
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT64_MAX,
.st_res = 64
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x1bffffffffffffff,
.st_res = 58
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x9abe83cff6ff7ff8,
.st_res = 0
} };
static const stdbit_ops_t stdbit_flz_ops = {
.so_name = "First Leading Zero",
.so_uc = stdc_first_leading_zero_uc,
.so_us = stdc_first_leading_zero_us,
.so_ui = stdc_first_leading_zero_ui,
.so_ul = stdc_first_leading_zero_ul,
.so_ull = stdc_first_leading_zero_ull,
};
static const stdbit_test_t stdbit_flz_tests[] = { {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = 1
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x3,
.st_res = 1
}, {
.st_types = STDBIT_TEST_U8,
.st_val = 0xf0,
.st_res = 5
}, {
.st_types = STDBIT_TEST_U8,
.st_val = 0xef,
.st_res = 4
}, {
.st_types = STDBIT_TEST_U8,
.st_val = 0xc4,
.st_res = 3
}, {
.st_types = STDBIT_TEST_U8,
.st_val = UINT8_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT8_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_U16,
.st_val = UINT16_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U16,
.st_val = 0xfabc,
.st_res = 6
}, {
.st_types = STDBIT_TEST_U16,
.st_val = 0xcbaf,
.st_res = 3
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT16_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_U32,
.st_val = UINT32_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0xff7ff623,
.st_res = 9
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0xfffff623,
.st_res = 21
}, {
. st_types = STDBIT_TEST_U32,
.st_val = 0xffffff95,
.st_res = 26
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT32_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_U64,
.st_val = UINT64_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U64,
.st_val = 0xfffffffffffffffe,
.st_res = 64
}, {
.st_types = STDBIT_TEST_U64,
.st_val = 0xffff2b9542fffffe,
.st_res = 17
} };
static const stdbit_ops_t stdbit_flo_ops = {
.so_name = "First Leading One",
.so_uc = stdc_first_leading_one_uc,
.so_us = stdc_first_leading_one_us,
.so_ui = stdc_first_leading_one_ui,
.so_ul = stdc_first_leading_one_ul,
.so_ull = stdc_first_leading_one_ull,
.so_delta = { 8, 16, 32 }
};
static const stdbit_test_t stdbit_flo_tests[] = { {
.st_types = STDBIT_TEST_U8,
.st_val = 0,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U16,
.st_val = 0,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U64,
.st_val = 0,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x1,
.st_res = 8
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0xf,
.st_res = 5
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0xfe,
.st_res = 1
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x7f,
.st_res = 2
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = UINT8_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT16_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0xfeed,
.st_res = 1
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x1aff,
.st_res = 4
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x02b0,
.st_res = 7
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT32_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x00001234,
.st_res = 20
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x2bb22bb2,
.st_res = 3
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x00420000,
.st_res = 10
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT64_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x000000000c000000,
.st_res = 37
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x000fedcba9abcdef,
.st_res = 13
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x000001992aa3bb4c,
.st_res = 24
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x0706050403020100,
.st_res = 6
} };
static const stdbit_ops_t stdbit_ftz_ops = {
.so_name = "First Trailing Zero",
.so_uc = stdc_first_trailing_zero_uc,
.so_us = stdc_first_trailing_zero_us,
.so_ui = stdc_first_trailing_zero_ui,
.so_ul = stdc_first_trailing_zero_ul,
.so_ull = stdc_first_trailing_zero_ull,
};
static const stdbit_test_t stdbit_ftz_tests[] = { {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = 1
}, {
.st_types = STDBIT_TEST_U8,
.st_val = UINT8_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U8,
.st_val = 0xfe,
.st_res = 1
}, {
.st_types = STDBIT_TEST_U8,
.st_val = 0xef,
.st_res = 5
}, {
.st_types = STDBIT_TEST_U8,
.st_val = 0x7f,
.st_res = 8
}, {
.st_types = STDBIT_TEST_U16,
.st_val = UINT8_MAX,
.st_res = 9
}, {
.st_types = STDBIT_TEST_U16,
.st_val = UINT16_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U16,
.st_val = 0xfffe,
.st_res = 1
}, {
.st_types = STDBIT_TEST_U16,
.st_val = 0xefff,
.st_res = 13
}, {
.st_types = STDBIT_TEST_U16,
.st_val = 0x07ff,
.st_res = 12
}, {
.st_types = STDBIT_TEST_U32,
.st_val = UINT16_MAX,
.st_res = 17
}, {
.st_types = STDBIT_TEST_U32,
.st_val = UINT32_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0xcaffffff,
.st_res = 25
}, {
.st_types = STDBIT_TEST_U32,
.st_val = 0xcabfffff,
.st_res = 23
}, {
.st_types = STDBIT_TEST_U64,
.st_val = UINT32_MAX,
.st_res = 33
}, {
.st_types = STDBIT_TEST_U64,
.st_val = UINT64_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_U64,
.st_val = 0xface2bface95a2ff,
.st_res = 9
}, {
.st_types = STDBIT_TEST_U64,
.st_val = 0x7777777777777777,
.st_res = 4
} };
static const stdbit_ops_t stdbit_fto_ops = {
.so_name = "First Trailing One",
.so_uc = stdc_first_trailing_one_uc,
.so_us = stdc_first_trailing_one_us,
.so_ui = stdc_first_trailing_one_ui,
.so_ul = stdc_first_trailing_one_ul,
.so_ull = stdc_first_trailing_one_ull,
};
static const stdbit_test_t stdbit_fto_tests[] = { {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = UINT8_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0xf7,
.st_res = 1
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0xf8,
.st_res = 4
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x6d,
.st_res = 1
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0xd6,
.st_res = 2
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x40,
.st_res = 7
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT16_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0xf840,
.st_res = 7
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x0a00,
.st_res = 10
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x8000,
.st_res = 16
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT32_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0xb0000000,
.st_res = 29
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0xf9c00000,
.st_res = 23
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0xfed81500,
.st_res = 9
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT64_MAX,
.st_res = 1
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0xfed80d0000000000,
.st_res = 41
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0xff70000000000000,
.st_res = 53
} };
static const stdbit_ops_t stdbit_cz_ops = {
.so_name = "Count Zeros",
.so_uc = stdc_count_zeros_uc,
.so_us = stdc_count_zeros_us,
.so_ui = stdc_count_zeros_ui,
.so_ul = stdc_count_zeros_ul,
.so_ull = stdc_count_zeros_ull,
.so_delta = { 8, 16, 32 }
};
static const stdbit_test_t stdbit_cz_tests[] = { {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = 8
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = UINT8_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x77,
.st_res = 2
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x88,
.st_res = 6
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x5,
.st_res = 6
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x1f,
.st_res = 3
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT16_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x1234,
.st_res = 11
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x4321,
.st_res = 11
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x2ba2,
.st_res = 9
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT32_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0xdeadbeef,
.st_res = 8
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x12345678,
.st_res = 19
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT64_MAX,
.st_res = 0
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0xabbabccbcddcdeed,
.st_res = 22
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x1221244248848008,
.st_res = 50
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0xfffffffeefffffff,
.st_res = 2
} };
static const stdbit_ops_t stdbit_co_ops = {
.so_name = "Count Ones",
.so_uc = stdc_count_ones_uc,
.so_us = stdc_count_ones_us,
.so_ui = stdc_count_ones_ui,
.so_ul = stdc_count_ones_ul,
.so_ull = stdc_count_ones_ull,
};
static const stdbit_test_t stdbit_co_tests[] = { {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = UINT8_MAX,
.st_res = 8
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x77,
.st_res = 6
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x88,
.st_res = 2
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x5,
.st_res = 2
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x1f,
.st_res = 5
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT16_MAX,
.st_res = 16
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x1234,
.st_res = 5
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x4321,
.st_res = 5
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x2ba2,
.st_res = 7
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT32_MAX,
.st_res = 32
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0xdeadbeef,
.st_res = 24
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x12345678,
.st_res = 13
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT64_MAX,
.st_res = 64
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0xabbabccbcddcdeed,
.st_res = 42
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x1221244248848008,
.st_res = 14
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0xfffffffeefffffff,
.st_res = 62
} };
static const stdbit_ops_t stdbit_bw_ops = {
.so_name = "Bit Width",
.so_uc = stdc_bit_width_uc,
.so_us = stdc_bit_width_us,
.so_ui = stdc_bit_width_ui,
.so_ul = stdc_bit_width_ul,
.so_ull = stdc_bit_width_ull,
};
static const stdbit_test_t stdbit_bw_tests[] = { {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = 0
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = UINT8_MAX,
.st_res = 8
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x80,
.st_res = 8
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x08,
.st_res = 4
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x17,
.st_res = 5
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT16_MAX,
.st_res = 16
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x7777,
.st_res = 15
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x2bb2,
.st_res = 14
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x0230,
.st_res = 10
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT32_MAX,
.st_res = 32
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0xfedc4000,
.st_res = 32
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x0004cedf,
.st_res = 19
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x001ee100,
.st_res = 21
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x8000000000000000,
.st_res = 64
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x00ff11ee22dd33cc,
.st_res = 56
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT64_MAX,
.st_res = 64
} };
static void
stdbit_print_pass(stdbit_test_type_t types, uint64_t val, const char *cat)
{
bool first = true;
(void) printf("TEST PASSED: %s (0x%" PRIx64 ") [", cat, val);
if ((types & STDBIT_TEST_U8) != 0) {
(void) printf("8");
first = false;
}
if ((types & STDBIT_TEST_U16) != 0) {
(void) printf("%s16", first ? "" : ",");
first = false;
}
if ((types & STDBIT_TEST_U32) != 0) {
(void) printf("%s32", first ? "" : ",");
first = false;
}
if ((types & STDBIT_TEST_U64) != 0) {
(void) printf("%s64", first ? "" : ",");
first = false;
}
(void) printf("]\n");
}
static bool
stdbit_test_one(const stdbit_test_t *test, const stdbit_ops_t *ops)
{
bool ret = true;
uint64_t comp = test->st_res;
VERIFY3U(test->st_types, !=, 0);
if ((test->st_types & STDBIT_TEST_U8) != 0) {
unsigned res = ops->so_uc(test->st_val);
if (res != comp) {
warnx("TEST FAILED: %s (0x%" PRIx64 ") 8-bit (uchar) "
"returned 0x%x, expected 0x%" PRIx64,
ops->so_name, test->st_val, res, comp);
ret = false;
}
comp += ops->so_delta[0];
}
if ((test->st_types & STDBIT_TEST_U16) != 0) {
unsigned res = ops->so_us(test->st_val);
if (res != comp) {
warnx("TEST FAILED: %s (0x%" PRIx64 ") 16-bit (ushort) "
"returned 0x%x, expected 0x%" PRIx64,
ops->so_name, test->st_val, res, comp);
ret = false;
}
comp += ops->so_delta[1];
}
if ((test->st_types & STDBIT_TEST_U32) != 0) {
unsigned res = ops->so_ui(test->st_val);
if (res != comp) {
warnx("TEST FAILED: %s (0x%" PRIx64 ") 32-bit (uint) "
"returned 0x%x, expected 0x%" PRIx64,
ops->so_name, test->st_val, res, comp);
ret = false;
}
#ifdef _ILP32
res = ops->so_ul(test->st_val);
if (res != comp) {
warnx("TEST FAILED: %s (0x%" PRIx64 ") 32-bit (ulong) "
"returned 0x%x, expected 0x%" PRIx64,
ops->so_name, test->st_val, res, comp);
ret = false;
}
#endif
comp += ops->so_delta[2];
}
if ((test->st_types & STDBIT_TEST_U64) != 0) {
unsigned res;
#ifdef _LP64
res = ops->so_ul(test->st_val);
if (res != comp) {
warnx("TEST FAILED: %s (0x%" PRIx64 ") 64-bit (ulong) "
"returned 0x%x, expected 0x%" PRIx64,
ops->so_name, test->st_val, res, comp);
ret = false;
}
#endif
res = ops->so_ull(test->st_val);
if (res != comp) {
warnx("TEST FAILED: %s (0x%" PRIx64 ") 64-bit (ulong "
"long) returned 0x%x, expected 0x%" PRIx64,
ops->so_name, test->st_val, res, comp);
ret = false;
}
}
if (ret) {
stdbit_print_pass(test->st_types, test->st_val, ops->so_name);
}
return (ret);
}
typedef struct {
const stdbit_ops_t *sg_ops;
const stdbit_test_t *sg_tests;
size_t sg_ntests;
} stdbit_std_group_t;
static const stdbit_std_group_t stdbit_groups[] = {
{ &stdbit_clz_ops, stdbit_clz_tests, ARRAY_SIZE(stdbit_clz_tests) },
{ &stdbit_clo_ops, stdbit_clo_tests, ARRAY_SIZE(stdbit_clo_tests) },
{ &stdbit_ctz_ops, stdbit_ctz_tests, ARRAY_SIZE(stdbit_ctz_tests) },
{ &stdbit_cto_ops, stdbit_cto_tests, ARRAY_SIZE(stdbit_cto_tests) },
{ &stdbit_flz_ops, stdbit_flz_tests, ARRAY_SIZE(stdbit_flz_tests) },
{ &stdbit_flo_ops, stdbit_flo_tests, ARRAY_SIZE(stdbit_flo_tests) },
{ &stdbit_ftz_ops, stdbit_ftz_tests, ARRAY_SIZE(stdbit_ftz_tests) },
{ &stdbit_fto_ops, stdbit_fto_tests, ARRAY_SIZE(stdbit_fto_tests) },
{ &stdbit_cz_ops, stdbit_cz_tests, ARRAY_SIZE(stdbit_cz_tests) },
{ &stdbit_co_ops, stdbit_co_tests, ARRAY_SIZE(stdbit_co_tests) },
{ &stdbit_bw_ops, stdbit_bw_tests, ARRAY_SIZE(stdbit_bw_tests) },
};
static const stdbit_test_t stdbit_1b_tests[] = { {
.st_types = STDBIT_TEST_ALL,
.st_val = 0,
.st_res = false
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = UINT8_MAX,
.st_res = false
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x40,
.st_res = true
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x23,
.st_res = false
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x81,
.st_res = false
}, {
.st_types = STDBIT_TEST_ALL,
.st_val = 0x08,
.st_res = true
}, {
.st_types = STDBIT_TEST_16P,
.st_val = UINT16_MAX,
.st_res = false
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x0100,
.st_res = true
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x7777,
.st_res = false
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x8000,
.st_res = true
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x0400,
.st_res = true
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x0020,
.st_res = true
}, {
.st_types = STDBIT_TEST_16P,
.st_val = 0x0001,
.st_res = true
}, {
.st_types = STDBIT_TEST_32P,
.st_val = UINT32_MAX,
.st_res = false
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x00200000,
.st_res = true
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0xbaddcafe,
.st_res = false
}, {
.st_types = STDBIT_TEST_32P,
.st_val = 0x80000000,
.st_res = true
}, {
.st_types = STDBIT_TEST_64P,
.st_val = UINT64_MAX,
.st_res = false
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x8000000000000000,
.st_res = true
}, {
.st_types = STDBIT_TEST_64P,
.st_val = 0x0010000000000000,
.st_res = true
} };
static bool
stdbit_1b_test_one(const stdbit_test_t *test)
{
bool ret = true, comp;
VERIFY(test->st_res == 0 || test->st_res == 1);
comp = (bool)test->st_res;
VERIFY3U(test->st_types, !=, 0);
if ((test->st_types & STDBIT_TEST_U8) != 0) {
bool res = stdc_has_single_bit_uc(test->st_val);
if (res != comp) {
warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 8-bit "
"(uchar) returned %s, expected %s", test->st_val,
res ? "true" : "false", comp ? "true" : "false");
ret = false;
}
}
if ((test->st_types & STDBIT_TEST_U16) != 0) {
bool res = stdc_has_single_bit_us(test->st_val);
if (res != comp) {
warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 16-bit "
"(ushort) returned %s, expected %s", test->st_val,
res ? "true" : "false", comp ? "true" : "false");
ret = false;
}
}
if ((test->st_types & STDBIT_TEST_U32) != 0) {
bool res = stdc_has_single_bit_ui(test->st_val);
if (res != comp) {
warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 32-bit "
"(uint) returned %s, expected %s", test->st_val,
res ? "true" : "false", comp ? "true" : "false");
ret = false;
}
#ifdef _ILP32
res = stdc_has_single_bit_ul(test->st_val);
if (res != comp) {
warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 32-bit "
"(ulong) returned %s, expected %s", test->st_val,
res ? "true" : "false", comp ? "true" : "false");
ret = false;
}
#endif
}
if ((test->st_types & STDBIT_TEST_U64) != 0) {
bool res;
#ifdef _LP64
res = stdc_has_single_bit_ul(test->st_val);
if (res != comp) {
warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 64-bit "
"(ulong) returned %s, expected %s", test->st_val,
res ? "true" : "false", comp ? "true" : "false");
ret = false;
}
#endif
res = stdc_has_single_bit_ull(test->st_val);
if (res != comp) {
warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 64-bit "
"(ulong long) returned %s, expected %s",
test->st_val, res ? "true" : "false",
comp ? "true" : "false");
ret = false;
}
}
if (ret) {
stdbit_print_pass(test->st_types, test->st_val, "Single-bit");
}
return (ret);
}
typedef struct {
stdbit_test_type_t sfc_types;
uint64_t sfc_val;
uint64_t sfc_floor;
uint64_t sfc_ceil;
} stdbit_fc_test_t;
static const stdbit_fc_test_t stdbit_fc_tests[] = { {
.sfc_types = STDBIT_TEST_ALL,
.sfc_val = 0,
.sfc_floor = 0,
.sfc_ceil = 1
}, {
.sfc_types = STDBIT_TEST_U8,
.sfc_val = UINT8_MAX,
.sfc_floor = 1ULL << 7,
.sfc_ceil = 0
}, {
.sfc_types = STDBIT_TEST_ALL,
.sfc_val = 0x23,
.sfc_floor = 1ULL << 5,
.sfc_ceil = 1ULL << 6
}, {
.sfc_types = STDBIT_TEST_ALL,
.sfc_val = 0x06,
.sfc_floor = 1ULL << 2,
.sfc_ceil = 1ULL << 3
}, {
.sfc_types = STDBIT_TEST_ALL,
.sfc_val = 0x18,
.sfc_floor = 1ULL << 4,
.sfc_ceil = 1ULL << 5
}, {
.sfc_types = STDBIT_TEST_U8,
.sfc_val = 0x81,
.sfc_floor = 1ULL << 7,
.sfc_ceil = 0
}, {
.sfc_types = STDBIT_TEST_16P,
.sfc_val = UINT8_MAX,
.sfc_floor = 1ULL << 7,
.sfc_ceil = 1ULL << 8
}, {
.sfc_types = STDBIT_TEST_16P,
.sfc_val = 0x0ff7,
.sfc_floor = 1ULL << 11,
.sfc_ceil = 1ULL << 12
}, {
.sfc_types = STDBIT_TEST_16P,
.sfc_val = 0x20a4,
.sfc_floor = 1ULL << 13,
.sfc_ceil = 1ULL << 14
}, {
.sfc_types = STDBIT_TEST_U16,
.sfc_val = 0x8ab1,
.sfc_floor = 1ULL << 15,
.sfc_ceil = 0
}, {
.sfc_types = STDBIT_TEST_U16,
.sfc_val = UINT16_MAX,
.sfc_floor = 1ULL << 15,
.sfc_ceil = 0
}, {
.sfc_types = STDBIT_TEST_32P,
.sfc_val = UINT16_MAX,
.sfc_floor = 1ULL << 15,
.sfc_ceil = 1ULL << 16
}, {
.sfc_types = STDBIT_TEST_32P,
.sfc_val = 0x000271ab,
.sfc_floor = 1ULL << 17,
.sfc_ceil = 1ULL << 18
}, {
.sfc_types = STDBIT_TEST_32P,
.sfc_val = 0x01000009,
.sfc_floor = 1ULL << 24,
.sfc_ceil = 1ULL << 25
}, {
.sfc_types = STDBIT_TEST_32P,
.sfc_val = 0x02000000,
.sfc_floor = 1ULL << 25,
.sfc_ceil = 1ULL << 25
}, {
.sfc_types = STDBIT_TEST_32P,
.sfc_val = 0x1cabf917,
.sfc_floor = 1ULL << 28,
.sfc_ceil = 1ULL << 29
}, {
.sfc_types = STDBIT_TEST_U32,
.sfc_val = 0x800a9b03,
.sfc_floor = 1ULL << 31,
.sfc_ceil = 0
}, {
.sfc_types = STDBIT_TEST_U32,
.sfc_val = UINT32_MAX,
.sfc_floor = 1ULL << 31,
.sfc_ceil = 0
}, {
.sfc_types = STDBIT_TEST_64P,
.sfc_val = UINT32_MAX,
.sfc_floor = 1ULL << 31,
.sfc_ceil = 1ULL << 32
}, {
.sfc_types = STDBIT_TEST_U64,
.sfc_val = 0x0089a23b1389ba87,
.sfc_floor = 1ULL << 55,
.sfc_ceil = 1ULL << 56
}, {
.sfc_types = STDBIT_TEST_U64,
.sfc_val = 0x499aff6eb12e7777,
.sfc_floor = 1ULL << 62,
.sfc_ceil = 1ULL << 63
}, {
.sfc_types = STDBIT_TEST_U64,
.sfc_val = 0xc00123481980ab87,
.sfc_floor = 1ULL << 63,
.sfc_ceil = 0
}, {
.sfc_types = STDBIT_TEST_U64,
.sfc_val = UINT64_MAX,
.sfc_floor = 1ULL << 63,
.sfc_ceil = 0
} };
static bool
stdbit_fc_test_one(const stdbit_fc_test_t *test)
{
bool ret = true;
VERIFY3U(test->sfc_types, !=, 0);
if ((test->sfc_types & STDBIT_TEST_U8) != 0) {
uint64_t res = stdc_bit_floor_uc(test->sfc_val);
if (res != test->sfc_floor) {
warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 8-bit "
"(uchar) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_floor);
ret = false;
}
res = stdc_bit_ceil_uc(test->sfc_val);
if (res != test->sfc_ceil) {
warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 8-bit "
"(uchar) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_ceil);
ret = false;
}
}
if ((test->sfc_types & STDBIT_TEST_U16) != 0) {
uint64_t res = stdc_bit_floor_us(test->sfc_val);
if (res != test->sfc_floor) {
warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 16-bit "
"(ushort) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_floor);
ret = false;
}
res = stdc_bit_ceil_us(test->sfc_val);
if (res != test->sfc_ceil) {
warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 16-bit "
"(ushort) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_ceil);
ret = false;
}
}
if ((test->sfc_types & STDBIT_TEST_U32) != 0) {
uint64_t res = stdc_bit_floor_ui(test->sfc_val);
if (res != test->sfc_floor) {
warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 32-bit "
"(uint) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_floor);
ret = false;
}
res = stdc_bit_ceil_ui(test->sfc_val);
if (res != test->sfc_ceil) {
warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 32-bit "
"(uint) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_ceil);
ret = false;
}
#ifdef _ILP32
res = stdc_bit_floor_ul(test->sfc_val);
if (res != test->sfc_floor) {
warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 32-bit "
"(ulong) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_floor);
ret = false;
}
res = stdc_bit_ceil_ul(test->sfc_val);
if (res != test->sfc_ceil) {
warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 32-bit "
"(ulong) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_ceil);
ret = false;
}
#endif
}
if ((test->sfc_types & STDBIT_TEST_U64) != 0) {
uint64_t res;
#ifdef _LP64
res = stdc_bit_floor_ul(test->sfc_val);
if (res != test->sfc_floor) {
warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 64-bit "
"(ulong) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_floor);
ret = false;
}
res = stdc_bit_ceil_ul(test->sfc_val);
if (res != test->sfc_ceil) {
warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 64-bit "
"(ulong) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_ceil);
ret = false;
}
#endif
res = stdc_bit_floor_ull(test->sfc_val);
if (res != test->sfc_floor) {
warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 64-bit "
"(ulong long) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_floor);
ret = false;
}
res = stdc_bit_ceil_ull(test->sfc_val);
if (res != test->sfc_ceil) {
warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 64-bit "
"(ulong long) returned 0x%" PRIx64 ", expected 0x%"
PRIx64, test->sfc_val, res, test->sfc_ceil);
ret = false;
}
}
if (ret) {
stdbit_print_pass(test->sfc_types, test->sfc_val,
"Bit Floor/Ceiling");
}
return (ret);
}
int
main(void)
{
int ret = EXIT_SUCCESS;
for (size_t i = 0; i < ARRAY_SIZE(stdbit_groups); i++) {
for (size_t t = 0; t < stdbit_groups[i].sg_ntests; t++) {
if (!stdbit_test_one(&stdbit_groups[i].sg_tests[t],
stdbit_groups[i].sg_ops)) {
ret = EXIT_FAILURE;
}
}
}
for (size_t i = 0; i < ARRAY_SIZE(stdbit_1b_tests); i++) {
if (!stdbit_1b_test_one(&stdbit_1b_tests[i])) {
ret = EXIT_FAILURE;
}
}
for (size_t i = 0; i < ARRAY_SIZE(stdbit_fc_tests); i++) {
if (!stdbit_fc_test_one(&stdbit_fc_tests[i])) {
ret = EXIT_FAILURE;
}
}
if (ret == EXIT_SUCCESS) {
(void) printf("All tests passed successfully\n");
}
return (ret);
}