blob: 136e9f2ddaf59f82a694db758e50dba426e535aa [file] [log] [blame]
/*
* Copyright (C) 2025 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if __has_include(<stdbit.h>)
#include <gtest/gtest.h>
#include <stdbit.h>
#include <limits.h>
typedef unsigned char uc;
typedef unsigned short us;
typedef unsigned int ui;
typedef unsigned long int ul;
typedef unsigned long long int ull;
TEST(stdbit, version) {
EXPECT_EQ(202311L, __STDC_VERSION_STDBIT_H__);
}
TEST(stdbit, endian) {
EXPECT_EQ(__STDC_ENDIAN_LITTLE__, __STDC_ENDIAN_NATIVE__);
}
static constexpr unsigned kLongBit = static_cast<unsigned>(LONG_BIT);
TEST(stdbit, stdc_leading_zeros) {
EXPECT_EQ(64u, stdc_leading_zeros(0x0000000000000000ull));
EXPECT_EQ(32u, stdc_leading_zeros(0x00000000ffffffffull));
EXPECT_EQ(48u, stdc_leading_zeros(0x000000000000ffffull));
EXPECT_EQ(0u, stdc_leading_zeros(0xffffffffffffffffull));
}
TEST(stdbit, stdc_leading_zeros_forwarding) {
EXPECT_EQ(8u, stdc_leading_zeros_uc(0x0000000000000000ull));
EXPECT_EQ(16u, stdc_leading_zeros_us(0x0000000000000000ull));
EXPECT_EQ(32u, stdc_leading_zeros_ui(0x0000000000000000ull));
EXPECT_EQ(kLongBit, stdc_leading_zeros_ul(0x0000000000000000ull));
EXPECT_EQ(64u, stdc_leading_zeros_ull(0x0000000000000000ull));
}
TEST(stdbit, stdc_leading_ones) {
EXPECT_EQ(64u, stdc_leading_ones(0xffffffffffffffffull));
EXPECT_EQ(32u, stdc_leading_ones(0xffffffff00000000ull));
EXPECT_EQ(16u, stdc_leading_ones(0xffff000000000000ull));
EXPECT_EQ(0u, stdc_leading_ones(0x0000000000000000ull));
}
TEST(stdbit, stdc_leading_ones_forwarding) {
EXPECT_EQ(8u, stdc_leading_ones_uc(0xffffffffffffffffull));
EXPECT_EQ(16u, stdc_leading_ones_us(0xffffffffffffffffull));
EXPECT_EQ(32u, stdc_leading_ones_ui(0xffffffffffffffffull));
EXPECT_EQ(kLongBit, stdc_leading_ones_ul(0xffffffffffffffffull));
EXPECT_EQ(64u, stdc_leading_ones_ull(0xffffffffffffffffull));
}
TEST(stdbit, stdc_trailing_zeros) {
EXPECT_EQ(64u, stdc_trailing_zeros(0x0000000000000000ull));
EXPECT_EQ(0u, stdc_trailing_zeros(0x0000000000000001ull));
EXPECT_EQ(8u, stdc_trailing_zeros(0x0000000000000100ull));
EXPECT_EQ(16u, stdc_trailing_zeros(0x0000000000010000ull));
EXPECT_EQ(32u, stdc_trailing_zeros(0x0000000100000000ull));
EXPECT_EQ(63u, stdc_trailing_zeros(0x8000000000000000ull));
EXPECT_EQ(0u, stdc_trailing_zeros(0xffffffffffffffffull));
}
TEST(stdbit, stdc_trailing_zeros_forwarding) {
EXPECT_EQ(8u, stdc_trailing_zeros_uc(0x0000000000000000ull));
EXPECT_EQ(16u, stdc_trailing_zeros_us(0x0000000000000000ull));
EXPECT_EQ(32u, stdc_trailing_zeros_ui(0x0000000000000000ull));
EXPECT_EQ(kLongBit, stdc_trailing_zeros_ul(0x0000000000000000ull));
EXPECT_EQ(64u, stdc_trailing_zeros_ull(0x0000000000000000ull));
}
TEST(stdbit, stdc_trailing_ones) {
EXPECT_EQ(0u, stdc_trailing_ones(0x0000000000000000ull));
EXPECT_EQ(8u, stdc_trailing_ones(0x00000000000000ffull));
EXPECT_EQ(16u, stdc_trailing_ones(0x000000000000ffffull));
EXPECT_EQ(32u, stdc_trailing_ones(0x00000000ffffffffull));
EXPECT_EQ(64u, stdc_trailing_ones(0xffffffffffffffffull));
}
TEST(stdbit, stdc_trailing_ones_forwarding) {
EXPECT_EQ(8u, stdc_trailing_ones_uc(0xffffffffffffffffull));
EXPECT_EQ(16u, stdc_trailing_ones_us(0xffffffffffffffffull));
EXPECT_EQ(32u, stdc_trailing_ones_ui(0xffffffffffffffffull));
EXPECT_EQ(kLongBit, stdc_trailing_ones_ul(0xffffffffffffffffull));
EXPECT_EQ(64u, stdc_trailing_ones_ull(0xffffffffffffffffull));
}
TEST(stdbit, stdc_first_leading_zero) {
EXPECT_EQ(1u, stdc_first_leading_zero(0x0000000000000000ull));
EXPECT_EQ(9u, stdc_first_leading_zero(0xff00000000000000ull));
EXPECT_EQ(17u, stdc_first_leading_zero(0xffff000000000000ull));
EXPECT_EQ(33u, stdc_first_leading_zero(0xffffffff00000000ull));
EXPECT_EQ(0u, stdc_first_leading_zero(0xffffffffffffffffull));
}
TEST(stdbit, stdc_first_leading_zero_forwarding) {
EXPECT_EQ(8u, stdc_first_leading_zero_uc(0xfffffffffffffffeull));
EXPECT_EQ(16u, stdc_first_leading_zero_us(0xfffffffffffffffeull));
EXPECT_EQ(32u, stdc_first_leading_zero_ui(0xfffffffffffffffeull));
#if defined(__LP64__)
EXPECT_EQ(64u, stdc_first_leading_zero_ul(0xfffffffffffffffeull));
#else
EXPECT_EQ(32u, stdc_first_leading_zero_ul(0xfffffffffffffffeull));
#endif
EXPECT_EQ(64u, stdc_first_leading_zero_ull(0xfffffffffffffffeull));
}
TEST(stdbit, stdc_first_leading_one) {
EXPECT_EQ(0u, stdc_first_leading_one(0x0000000000000000ull));
EXPECT_EQ(57u, stdc_first_leading_one(0x00000000000000ffull));
EXPECT_EQ(49u, stdc_first_leading_one(0x000000000000ffffull));
EXPECT_EQ(33u, stdc_first_leading_one(0x00000000ffffffffull));
EXPECT_EQ(1u, stdc_first_leading_one(0xffffffffffffffffull));
}
TEST(stdbit, stdc_first_leading_one_forwarding) {
EXPECT_EQ(8u, stdc_first_leading_one_uc(0x0000000000000001ull));
EXPECT_EQ(16u, stdc_first_leading_one_us(0x0000000000000001ull));
EXPECT_EQ(32u, stdc_first_leading_one_ui(0x0000000000000001ull));
EXPECT_EQ(kLongBit, stdc_first_leading_one_ul(0x0000000000000001ull));
EXPECT_EQ(64u, stdc_first_leading_one_ull(0x0000000000000001ull));
}
TEST(stdbit, stdc_first_trailing_zero) {
EXPECT_EQ(1u, stdc_first_trailing_zero(0x0000000000000000ull));
EXPECT_EQ(9u, stdc_first_trailing_zero(0x00000000000000ffull));
EXPECT_EQ(17u, stdc_first_trailing_zero(0x000000000000ffffull));
EXPECT_EQ(33u, stdc_first_trailing_zero(0x00000000ffffffffull));
EXPECT_EQ(0u, stdc_first_trailing_zero(0xffffffffffffffffull));
}
TEST(stdbit, stdc_first_trailing_zero_forwarding) {
EXPECT_EQ(8u, stdc_first_trailing_zero_uc(0x00000000000007full));
EXPECT_EQ(16u, stdc_first_trailing_zero_us(0x000000000007fffull));
EXPECT_EQ(32u, stdc_first_trailing_zero_ui(0x00000007fffffffull));
#if defined(__LP64__)
EXPECT_EQ(64u, stdc_first_trailing_zero_ul(0x7fffffffffffffffull));
#else
EXPECT_EQ(32u, stdc_first_trailing_zero_ul(0x00000007fffffffull));
#endif
EXPECT_EQ(64u, stdc_first_trailing_zero_ull(0x7fffffffffffffffull));
}
TEST(stdbit, stdc_first_trailing_one) {
EXPECT_EQ(0u, stdc_first_trailing_one(0x0000000000000000ull));
EXPECT_EQ(57u, stdc_first_trailing_one(0xff00000000000000ull));
EXPECT_EQ(49u, stdc_first_trailing_one(0xffff000000000000ull));
EXPECT_EQ(33u, stdc_first_trailing_one(0xffffffff00000000ull));
EXPECT_EQ(1u, stdc_first_trailing_one(0xffffffffffffffffull));
}
TEST(stdbit, stdc_first_trailing_one_forwarding) {
EXPECT_EQ(8u, stdc_first_trailing_one_uc(0x000000000000080ull));
EXPECT_EQ(16u, stdc_first_trailing_one_us(0x000000000008000ull));
EXPECT_EQ(32u, stdc_first_trailing_one_ui(0x000000080000000ull));
#if defined(__LP64__)
EXPECT_EQ(64u, stdc_first_trailing_one_ul(0x8000000000000000ull));
#else
EXPECT_EQ(32u, stdc_first_trailing_one_ul(0x000000080000000ull));
#endif
EXPECT_EQ(64u, stdc_first_trailing_one_ull(0x8000000000000000ull));
}
TEST(stdbit, stdc_count_zeros) {
EXPECT_EQ(64u, stdc_count_zeros(0x0000000000000000ull));
EXPECT_EQ(56u, stdc_count_zeros(0xff00000000000000ull));
EXPECT_EQ(48u, stdc_count_zeros(0xffff000000000000ull));
EXPECT_EQ(32u, stdc_count_zeros(0xffffffff00000000ull));
EXPECT_EQ(0u, stdc_count_zeros(0xffffffffffffffffull));
}
TEST(stdbit, stdc_count_zeros_forwarding) {
EXPECT_EQ(8u, stdc_count_zeros_uc(0x0000000000000000ull));
EXPECT_EQ(16u, stdc_count_zeros_us(0x0000000000000000ull));
EXPECT_EQ(32u, stdc_count_zeros_ui(0x0000000000000000ull));
EXPECT_EQ(kLongBit, stdc_count_zeros_ul(0x0000000000000000ull));
EXPECT_EQ(64u, stdc_count_zeros_ull(0x0000000000000000ull));
}
TEST(stdbit, stdc_count_ones) {
EXPECT_EQ(0u, stdc_count_ones(0x0000000000000000ull));
EXPECT_EQ(8u, stdc_count_ones(0xff00000000000000ull));
EXPECT_EQ(16u, stdc_count_ones(0xffff000000000000ull));
EXPECT_EQ(32u, stdc_count_ones(0xffffffff00000000ull));
EXPECT_EQ(64u, stdc_count_ones(0xffffffffffffffffull));
}
TEST(stdbit, stdc_count_ones_forwarding) {
EXPECT_EQ(8u, stdc_count_ones_uc(0xffffffffffffffffull));
EXPECT_EQ(16u, stdc_count_ones_us(0xffffffffffffffffull));
EXPECT_EQ(32u, stdc_count_ones_ui(0xffffffffffffffffull));
EXPECT_EQ(kLongBit, stdc_count_ones_ul(0xffffffffffffffffull));
EXPECT_EQ(64u, stdc_count_ones_ull(0xffffffffffffffffull));
}
TEST(stdbit, stdc_has_single_bit) {
EXPECT_EQ(false, stdc_has_single_bit(0x0000000000000000ull));
EXPECT_EQ(false, stdc_has_single_bit(0x0000000000000003ull));
EXPECT_EQ(false, stdc_has_single_bit(0x1000000000000001ull));
EXPECT_EQ(false, stdc_has_single_bit(0xffffffffffffffffull));
EXPECT_EQ(true, stdc_has_single_bit(0x0000000000000001ull));
EXPECT_EQ(true, stdc_has_single_bit(0x0000000000008000ull));
EXPECT_EQ(true, stdc_has_single_bit(0x0000000080000000ull));
EXPECT_EQ(true, stdc_has_single_bit(0x8000000000000000ull));
}
TEST(stdbit, stdc_has_single_bit_forwarding) {
EXPECT_EQ(true, stdc_has_single_bit_uc(0x8000000080008080ull));
EXPECT_EQ(true, stdc_has_single_bit_us(0x8000000080008000ull));
EXPECT_EQ(true, stdc_has_single_bit_ui(0x8000000080000000ull));
#if defined(__LP64__)
EXPECT_EQ(true, stdc_has_single_bit_ul(0x8000000000000000ull));
#else
EXPECT_EQ(true, stdc_has_single_bit_ul(0x8000000080000000ull));
#endif
EXPECT_EQ(true, stdc_has_single_bit_ull(0x8000000000000000ull));
}
TEST(stdbit, stdc_bit_width) {
EXPECT_EQ(0u, stdc_bit_width(0x0000000000000000ull));
EXPECT_EQ(8u, stdc_bit_width(0x0000000000000080ull));
EXPECT_EQ(16u, stdc_bit_width(0x0000000000008000ull));
EXPECT_EQ(32u, stdc_bit_width(0x0000000080000000ull));
EXPECT_EQ(64u, stdc_bit_width(0x8000000000000000ull));
EXPECT_EQ(64u, stdc_bit_width(0xffffffffffffffffull));
}
TEST(stdbit, stdc_bit_width_forwarding) {
EXPECT_EQ(8u, stdc_bit_width_uc(0xffffffffffffffffull));
EXPECT_EQ(16u, stdc_bit_width_us(0xffffffffffffffffull));
EXPECT_EQ(32u, stdc_bit_width_ui(0xffffffffffffffffull));
EXPECT_EQ(kLongBit, stdc_bit_width_ul(0xffffffffffffffffull));
EXPECT_EQ(64u, stdc_bit_width_ull(0xffffffffffffffffull));
}
TEST(stdbit, stdc_bit_floor) {
EXPECT_EQ(0x0000000000000000ull, stdc_bit_floor(0x0000000000000000ull));
EXPECT_EQ(0x0000000000000040ull, stdc_bit_floor(0x000000000000007full));
EXPECT_EQ(0x0000000000000080ull, stdc_bit_floor(0x0000000000000080ull));
EXPECT_EQ(0x0000000000000100ull, stdc_bit_floor(0x0000000000000100ull));
EXPECT_EQ(0x0000000000004000ull, stdc_bit_floor(0x0000000000007fffull));
EXPECT_EQ(0x0000000000008000ull, stdc_bit_floor(0x0000000000008000ull));
EXPECT_EQ(0x0000000000010000ull, stdc_bit_floor(0x0000000000010000ull));
EXPECT_EQ(0x0000000040000000ull, stdc_bit_floor(0x000000007fffffffull));
EXPECT_EQ(0x0000000080000000ull, stdc_bit_floor(0x0000000080000000ull));
EXPECT_EQ(0x0000000100000000ull, stdc_bit_floor(0x0000000100000000ull));
EXPECT_EQ(0x4000000000000000ull, stdc_bit_floor(0x7fffffffffffffffull));
EXPECT_EQ(0x8000000000000000ull, stdc_bit_floor(0x8000000000000000ull));
EXPECT_EQ(0x8000000000000000ull, stdc_bit_floor(0xffffffffffffffffull));
}
TEST(stdbit, stdc_bit_floor_forwarding) {
EXPECT_EQ(0x0000000000000080ull, stdc_bit_floor_uc(0x8000000080008080ull));
EXPECT_EQ(0x0000000000008000ull, stdc_bit_floor_us(0x8000000080008080ull));
EXPECT_EQ(0x0000000080000000ull, stdc_bit_floor_ui(0x8000000080008080ull));
#if defined(__LP64__)
EXPECT_EQ(0x8000000000000000ull, stdc_bit_floor_ul(0x8000000080008080ull));
#else
EXPECT_EQ(0x0000000080000000ull, stdc_bit_floor_ul(0x8000000080008080ull));
#endif
EXPECT_EQ(0x8000000000000000ull, stdc_bit_floor_ull(0x8000000080008080ull));
}
TEST(stdbit, stdc_bit_ceil) {
EXPECT_EQ(0x0000000000000001ull, stdc_bit_ceil(0x0000000000000000ull));
EXPECT_EQ(0x0000000000000080ull, stdc_bit_ceil(0x000000000000007full));
EXPECT_EQ(0x0000000000000080ull, stdc_bit_ceil(0x0000000000000080ull));
EXPECT_EQ(0x0000000000000100ull, stdc_bit_ceil(0x0000000000000100ull));
EXPECT_EQ(0x0000000000008000ull, stdc_bit_ceil(0x0000000000007fffull));
EXPECT_EQ(0x0000000000008000ull, stdc_bit_ceil(0x0000000000008000ull));
EXPECT_EQ(0x0000000000010000ull, stdc_bit_ceil(0x0000000000010000ull));
EXPECT_EQ(0x0000000080000000ull, stdc_bit_ceil(0x000000007fffffffull));
EXPECT_EQ(0x0000000080000000ull, stdc_bit_ceil(0x0000000080000000ull));
EXPECT_EQ(0x0000000100000000ull, stdc_bit_ceil(0x0000000100000000ull));
EXPECT_EQ(0x8000000000000000ull, stdc_bit_ceil(0x7fffffffffffffffull));
EXPECT_EQ(0x8000000000000000ull, stdc_bit_ceil(0x8000000000000000ull));
EXPECT_EQ(0x0000000000000000ull, stdc_bit_ceil(0xffffffffffffffffull));
}
TEST(stdbit, stdc_bit_ceil_forwarding) {
EXPECT_EQ(0x0000000000000080ull, stdc_bit_ceil_uc(0x800000008000807full));
EXPECT_EQ(0x0000000000008000ull, stdc_bit_ceil_us(0x8000000080007fffull));
EXPECT_EQ(0x0000000080000000ull, stdc_bit_ceil_ui(0x800000007fffffffull));
#if defined(__LP64__)
EXPECT_EQ(0x8000000000000000ull, stdc_bit_ceil_ul(0x7fffffffffffffffull));
#else
EXPECT_EQ(0x0000000080000000ull, stdc_bit_ceil_ul(0x800000007fffffffull));
#endif
EXPECT_EQ(0x8000000000000000ull, stdc_bit_ceil_ull(0x7fffffffffffffffull));
}
TEST(stdbit, no_double_evaluation) {
ull x;
x = 0;
stdc_leading_zeros(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_leading_ones(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_trailing_zeros(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_trailing_ones(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_first_leading_zero(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_first_leading_one(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_first_trailing_zero(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_first_trailing_one(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_count_zeros(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_count_ones(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_has_single_bit(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_bit_width(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_bit_floor(x++);
EXPECT_EQ(x, 1u);
x = 0;
stdc_bit_ceil(x++);
EXPECT_EQ(x, 1u);
}
#endif