blob: d9d9bfaad47530d84793e3467a6a5ede600acdc2 [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.
*/
#pragma once
#include <sys/cdefs.h>
/* C23 7.18.1 says this header also makes int*_t/uint*_t etc available. */
#include <stdint.h>
__BEGIN_DECLS
/* C23 7.18.1 General */
/** Declares this implementation as supporting the C23 functionality. */
#define __STDC_VERSION_STDBIT_H__ 202311L
/* C23 7.18.2 Endian */
/** Constant representing little-endian. */
#define __STDC_ENDIAN_LITTLE__ 1234
/** Constant representing big-endian. */
#define __STDC_ENDIAN_BIG__ 4321
/**
* Constant representing the endian of the target.
* Android is always little-endian.
*/
#define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__
/*
* Notes on the implementation.
*
* Ideally we'd have clang builtins for all of these, like gcc has.
* If/when clang catches up, we can replace all of this with direct calls to
* the relevant builtins.
*
* In the meantime:
*
* We only use macros because (a) we want to support all api levels and
* (b) the whole point of these functions is that they should all be just an
* instruction or two, where function call overhead would ruin everything.
*
* Where there's a similar generic builtin (such as __builtin_clzg) we
* forward all the type-specific variants to that.
*
* Even when not, we try to forward all the type-specific variants to the
* generic variant so it's all "obviously correct".
*
* (It's 2025, and this will only be used in new code, so we haven't bothered
* with special cases for ILP32 systems.)
*
* We cast the arguments to the expected argument types because the builtins
* do argument type checking that the <stdbit.h> functionality is not expected
* to do (causing warnings rather than silent conversion when passing a signed
* int, say).
*
* We cast the results to the expected `unsigned int` type because the builtins
* return signed results.
*
* We don't worry about C++ casts because it's unclear how this file is
* supposed to interact with C++, and C++ has had <bit> longer than C has
* had <stdbit.h>.
*/
/* C23 7.18.3 Count Leading Zeros */
/** Returns the count of consecutive 0 bits, starting from the most-significant. */
#define stdc_leading_zeros_uc(__x) stdc_leading_zeros((unsigned char) (__x))
/** Returns the count of consecutive 0 bits, starting from the most-significant. */
#define stdc_leading_zeros_us(__x) stdc_leading_zeros((unsigned short) (__x))
/** Returns the count of consecutive 0 bits, starting from the most-significant. */
#define stdc_leading_zeros_ui(__x) stdc_leading_zeros((unsigned int) (__x))
/** Returns the count of consecutive 0 bits, starting from the most-significant. */
#define stdc_leading_zeros_ul(__x) stdc_leading_zeros((unsigned long) (__x))
/** Returns the count of consecutive 0 bits, starting from the most-significant. */
#define stdc_leading_zeros_ull(__x) stdc_leading_zeros((unsigned long long) (__x))
/** Returns the count of consecutive 0 bits, starting from the most-significant. */
#define stdc_leading_zeros(__x) \
((unsigned int) __builtin_clzg(__x, (int) (8 * sizeof(__x))))
/* C23 7.18.4 Count Leading Ones */
/** Returns the count of consecutive 1 bits, starting from the most-significant. */
#define stdc_leading_ones_uc(__x) stdc_leading_ones((unsigned char) (__x))
/** Returns the count of consecutive 1 bits, starting from the most-significant. */
#define stdc_leading_ones_us(__x) stdc_leading_ones((unsigned short) (__x))
/** Returns the count of consecutive 1 bits, starting from the most-significant. */
#define stdc_leading_ones_ui(__x) stdc_leading_ones((unsigned int) (__x))
/** Returns the count of consecutive 1 bits, starting from the most-significant. */
#define stdc_leading_ones_ul(__x) stdc_leading_ones((unsigned long) (__x))
/** Returns the count of consecutive 1 bits, starting from the most-significant. */
#define stdc_leading_ones_ull(__x) stdc_leading_ones((unsigned long long) (__x))
/** Returns the count of consecutive 1 bits, starting from the most-significant. */
#define stdc_leading_ones(__x) \
((unsigned int) (__builtin_clzg(~(((unsigned long long) (__x)) << ((8 * sizeof(unsigned long long)) - (8 * sizeof(__x)))), \
(int) (8 * sizeof(__x)))))
/* C23 7.18.5 Count Trailing Zeros */
/** Returns the count of consecutive 0 bits, starting from the least-significant. */
#define stdc_trailing_zeros_uc(__x) stdc_trailing_zeros((unsigned char) (__x))
/** Returns the count of consecutive 0 bits, starting from the least-significant. */
#define stdc_trailing_zeros_us(__x) stdc_trailing_zeros((unsigned short) (__x))
/** Returns the count of consecutive 0 bits, starting from the least-significant. */
#define stdc_trailing_zeros_ui(__x) stdc_trailing_zeros((unsigned int) (__x))
/** Returns the count of consecutive 0 bits, starting from the least-significant. */
#define stdc_trailing_zeros_ul(__x) stdc_trailing_zeros((unsigned long) (__x))
/** Returns the count of consecutive 0 bits, starting from the least-significant. */
#define stdc_trailing_zeros_ull(__x) stdc_trailing_zeros((unsigned long long) (__x))
/** Returns the count of consecutive 0 bits, starting from the least-significant. */
#define stdc_trailing_zeros(__x) \
((unsigned int) __builtin_ctzg(__x, \
(int) (8 * sizeof(__x))))
/* C23 7.18.6 Count Trailing Ones */
/** Returns the count of consecutive 1 bits, starting from the least-significant. */
#define stdc_trailing_ones_uc(__x) stdc_trailing_ones((unsigned char) (__x))
/** Returns the count of consecutive 1 bits, starting from the least-significant. */
#define stdc_trailing_ones_us(__x) stdc_trailing_ones((unsigned short) (__x))
/** Returns the count of consecutive 1 bits, starting from the least-significant. */
#define stdc_trailing_ones_ui(__x) stdc_trailing_ones((unsigned int) (__x))
/** Returns the count of consecutive 1 bits, starting from the least-significant. */
#define stdc_trailing_ones_ul(__x) stdc_trailing_ones((unsigned long) (__x))
/** Returns the count of consecutive 1 bits, starting from the least-significant. */
#define stdc_trailing_ones_ull(__x) stdc_trailing_ones((unsigned long long) (__x))
/** Returns the count of consecutive 1 bits, starting from the least-significant. */
#define stdc_trailing_ones(__x) \
((unsigned int) (__builtin_ctzg((typeof(__x)) ~(__x), \
(int) (8 * sizeof(__x)))))
/* C23 7.18.7 First Leading Zero */
/** Returns the index of the first 0 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_zero_uc(__x) stdc_first_leading_zero((unsigned char) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_zero_us(__x) stdc_first_leading_zero((unsigned short) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_zero_ui(__x) stdc_first_leading_zero((unsigned int) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_zero_ul(__x) stdc_first_leading_zero((unsigned long) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_zero_ull(__x) stdc_first_leading_zero((unsigned long long) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_zero(__x) ({ \
typeof(__x) __val = (__x); \
((unsigned int) ((__val == (typeof(__x)) -1 \
? 0 \
: 1 + __builtin_clzg((typeof(__x)) ~__val)))); \
})
/* C23 7.18.8 First Leading One */
/** Returns the index of the first 1 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_one_uc(__x) stdc_first_leading_one((unsigned char) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_one_us(__x) stdc_first_leading_one((unsigned short) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_one_ui(__x) stdc_first_leading_one((unsigned int) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_one_ul(__x) stdc_first_leading_one((unsigned long) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_one_ull(__x) stdc_first_leading_one((unsigned long long) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the most-significant (0 if none). */
#define stdc_first_leading_one(__x) ({ \
typeof(__x) __val = (__x); \
((unsigned int) ((__val == (typeof(__val)) 0 \
? 0 \
: 1 + __builtin_clzg(__val)))); \
})
/* C23 7.18.9 First Trailing Zero */
/** Returns the index of the first 0 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_zero_uc(__x) stdc_first_trailing_zero((unsigned char) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_zero_us(__x) stdc_first_trailing_zero((unsigned short) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_zero_ui(__x) stdc_first_trailing_zero((unsigned int) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_zero_ul(__x) stdc_first_trailing_zero((unsigned long) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_zero_ull(__x) stdc_first_trailing_zero((unsigned long long) (__x))
/** Returns the index of the first 0 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_zero(__x) ({ \
typeof(__x) __val = (__x); \
((unsigned int) ((__val == (typeof(__val)) -1 \
? 0 \
: 1 + __builtin_ctzg((typeof(__val)) ~__val)))); \
})
/* C23 7.18.10 First Trailing One */
/** Returns the index of the first 1 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_one_uc(__x) stdc_first_trailing_one((unsigned char) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_one_us(__x) stdc_first_trailing_one((unsigned short) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_one_ui(__x) stdc_first_trailing_one((unsigned int) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_one_ul(__x) stdc_first_trailing_one((unsigned long) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_one_ull(__x) stdc_first_trailing_one((unsigned long long) (__x))
/** Returns the index of the first 1 bit, plus 1, starting from the least-significant (0 if none). */
#define stdc_first_trailing_one(__x) \
((unsigned int) (((__x) == (typeof(__x)) 0 \
? 0 \
: 1 + __builtin_ctzg(__x))))
/* C23 7.18.11 Count Zeros */
/** Returns the count of 0 bits. */
#define stdc_count_zeros_uc(__x) stdc_count_zeros((unsigned char) (__x))
/** Returns the count of 0 bits. */
#define stdc_count_zeros_us(__x) stdc_count_zeros((unsigned short) (__x))
/** Returns the count of 0 bits. */
#define stdc_count_zeros_ui(__x) stdc_count_zeros((unsigned int) (__x))
/** Returns the count of 0 bits. */
#define stdc_count_zeros_ul(__x) stdc_count_zeros((unsigned long) (__x))
/** Returns the count of 0 bits. */
#define stdc_count_zeros_ull(__x) stdc_count_zeros((unsigned long long) (__x))
/** Returns the count of 0 bits. */
#define stdc_count_zeros(__x) ((unsigned int) ((8 * sizeof(__x)) - __builtin_popcountg(__x)))
/* C23 7.18.12 Count Ones */
/** Returns the count of 1 bits. */
#define stdc_count_ones_uc(__x) stdc_count_ones((unsigned char) (__x))
/** Returns the count of 1 bits. */
#define stdc_count_ones_us(__x) stdc_count_ones((unsigned short) (__x))
/** Returns the count of 1 bits. */
#define stdc_count_ones_ui(__x) stdc_count_ones((unsigned int) (__x))
/** Returns the count of 1 bits. */
#define stdc_count_ones_ul(__x) stdc_count_ones((unsigned long) (__x))
/** Returns the count of 1 bits. */
#define stdc_count_ones_ull(__x) stdc_count_ones((unsigned long long) (__x))
/** Returns the count of 1 bits. */
#define stdc_count_ones(__x) ((unsigned int) __builtin_popcountg(__x))
/* C23 7.18.13 Single-Bit Check */
/** Returns true if exactly one bit is set (that is: it's a non-zero power of 2). */
#define stdc_has_single_bit_uc(__x) stdc_has_single_bit((unsigned char) (__x))
/** Returns true if exactly one bit is set (that is: it's a non-zero power of 2). */
#define stdc_has_single_bit_us(__x) stdc_has_single_bit((unsigned short) (__x))
/** Returns true if exactly one bit is set (that is: it's a non-zero power of 2). */
#define stdc_has_single_bit_ui(__x) stdc_has_single_bit((unsigned int) (__x))
/** Returns true if exactly one bit is set (that is: it's a non-zero power of 2). */
#define stdc_has_single_bit_ul(__x) stdc_has_single_bit((unsigned long) (__x))
/** Returns true if exactly one bit is set (that is: it's a non-zero power of 2). */
#define stdc_has_single_bit_ull(__x) stdc_has_single_bit((unsigned long long) (__x))
/** Returns true if exactly one bit is set (that is: it's a non-zero power of 2). */
#define stdc_has_single_bit(__x) ({ \
typeof(__x) __val = (__x); \
((bool) (__val != 0 && ((__val & (__val - 1)) == 0))); \
})
/* C23 7.18.14 Bit Width */
/** Returns the smallest number of bits needed to store the value (0 for 0). */
#define stdc_bit_width_uc(__x) stdc_bit_width((unsigned char) (__x))
/** Returns the smallest number of bits needed to store the value (0 for 0). */
#define stdc_bit_width_us(__x) stdc_bit_width((unsigned short) (__x))
/** Returns the smallest number of bits needed to store the value (0 for 0). */
#define stdc_bit_width_ui(__x) stdc_bit_width((unsigned int) (__x))
/** Returns the smallest number of bits needed to store the value (0 for 0). */
#define stdc_bit_width_ul(__x) stdc_bit_width((unsigned long) (__x))
/** Returns the smallest number of bits needed to store the value (0 for 0). */
#define stdc_bit_width_ull(__x) stdc_bit_width((unsigned long long) (__x))
/** Returns the smallest number of bits needed to store the value (0 for 0). */
#define stdc_bit_width(__x) \
((unsigned int) (8 * sizeof(__x)) - __builtin_clzg(__x, \
(int) (8 * sizeof(__x))))
/* C23 7.18.15 Bit Floor */
/** Returns the largest integral power of 2 not greater than the value (0 for 0). */
#define stdc_bit_floor_uc(__x) stdc_bit_floor((unsigned char) (__x))
/** Returns the largest integral power of 2 not greater than the value (0 for 0). */
#define stdc_bit_floor_us(__x) stdc_bit_floor((unsigned short) (__x))
/** Returns the largest integral power of 2 not greater than the value (0 for 0). */
#define stdc_bit_floor_ui(__x) stdc_bit_floor((unsigned int) (__x))
/** Returns the largest integral power of 2 not greater than the value (0 for 0). */
#define stdc_bit_floor_ul(__x) stdc_bit_floor((unsigned long) (__x))
/** Returns the largest integral power of 2 not greater than the value (0 for 0). */
#define stdc_bit_floor_ull(__x) stdc_bit_floor((unsigned long long) (__x))
/** Returns the largest integral power of 2 not greater than the value (0 for 0). */
#define stdc_bit_floor(__x) ({ \
typeof(__x) __val = (__x); \
((typeof(__val)) (__val == 0 ? 0 : ((typeof(__val)) 1) << (stdc_bit_width(__val) - 1))); \
})
/* C23 7.18.15 Bit Ceil */
/** Returns the smallest integral power of 2 not less than the value. */
#define stdc_bit_ceil_uc(__x) stdc_bit_ceil((unsigned char) (__x))
/** Returns the smallest integral power of 2 not less than the value. */
#define stdc_bit_ceil_us(__x) stdc_bit_ceil((unsigned short) (__x))
/** Returns the smallest integral power of 2 not less than the value. */
#define stdc_bit_ceil_ui(__x) stdc_bit_ceil((unsigned int) (__x))
/** Returns the smallest integral power of 2 not less than the value. */
#define stdc_bit_ceil_ul(__x) stdc_bit_ceil((unsigned long) (__x))
/** Returns the smallest integral power of 2 not less than the value. */
#define stdc_bit_ceil_ull(__x) stdc_bit_ceil((unsigned long long) (__x))
/** Returns the smallest integral power of 2 not less than the value. */
#define stdc_bit_ceil(__x) ({ \
typeof(__x) __result = 1; \
typeof(__x) __val = (__x); \
if (__val > 1) { \
/* Avoid shifts greater than the width of the type. */ \
unsigned __shift = stdc_bit_width(__val - 1u); \
if (__shift < 8 * sizeof(__result)) __result = 1ull << __shift; \
else __result = 0; \
} \
__result; })
__END_DECLS