| /* |
| * 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 |