| author | |
| committer | |
| log | c34fc8f19884ebe551b1dea9b8061efd3680848a |
| tree | a5a1517fd255f3c491d1023cff84769fb0206383 |
| parent | d9f0fbf9838060b1e8c2ec0df21b43e75430350f |
| signature |
Still only the subset needed for libcxx.24 files changed, 313 insertions(+), 130 deletions(-)
lib/libcxx/libc/include/llvm-libc-macros/stdfix-macros.h+39| ... | ... | @@ -323,6 +323,45 @@ |
| 323 | 323 | #define ULACCUM_EPSILON 0x1.0p-32ULK |
| 324 | 324 | #endif // ULACCUM_EPSILON |
| 325 | 325 | |
| 326 | #define absfx(x) \ | |
| 327 | _Generic((x), \ | |
| 328 | fract: absr, \ | |
| 329 | short fract: abshr, \ | |
| 330 | long fract: abslr, \ | |
| 331 | accum: absk, \ | |
| 332 | short accum: abshk, \ | |
| 333 | long accum: abslk)(x) | |
| 334 | ||
| 335 | #define countlsfx(x) \ | |
| 336 | _Generic((x), \ | |
| 337 | fract: countlsr, \ | |
| 338 | short fract: countlshr, \ | |
| 339 | long fract: countlslr, \ | |
| 340 | accum: countlsk, \ | |
| 341 | short accum: countlshk, \ | |
| 342 | long accum: countlslk, \ | |
| 343 | unsigned fract: countlsur, \ | |
| 344 | unsigned short fract: countlsuhr, \ | |
| 345 | unsigned long fract: countlsulr, \ | |
| 346 | unsigned accum: countlsuk, \ | |
| 347 | unsigned short accum: countlsuhk, \ | |
| 348 | unsigned long accum: countlsulk)(x) | |
| 349 | ||
| 350 | #define roundfx(x, y) \ | |
| 351 | _Generic((x), \ | |
| 352 | fract: roundr, \ | |
| 353 | short fract: roundhr, \ | |
| 354 | long fract: roundlr, \ | |
| 355 | accum: roundk, \ | |
| 356 | short accum: roundhk, \ | |
| 357 | long accum: roundlk, \ | |
| 358 | unsigned fract: roundur, \ | |
| 359 | unsigned short fract: rounduhr, \ | |
| 360 | unsigned long fract: roundulr, \ | |
| 361 | unsigned accum: rounduk, \ | |
| 362 | unsigned short accum: rounduhk, \ | |
| 363 | unsigned long accum: roundulk)(x, y) | |
| 364 | ||
| 326 | 365 | #endif // LIBC_COMPILER_HAS_FIXED_POINT |
| 327 | 366 | |
| 328 | 367 | #endif // LLVM_LIBC_MACROS_STDFIX_MACROS_H |
lib/libcxx/libc/shared/fp_bits.h+1| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #ifndef LLVM_LIBC_SHARED_FP_BITS_H |
| 10 | 10 | #define LLVM_LIBC_SHARED_FP_BITS_H |
| 11 | 11 | |
| 12 | #include "libc_common.h" | |
| 12 | 13 | #include "src/__support/FPUtil/FPBits.h" |
| 13 | 14 | |
| 14 | 15 | namespace LIBC_NAMESPACE_DECL { |
lib/libcxx/libc/shared/libc_common.h created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | //===-- Common defines for sharing LLVM libc with LLVM projects -*- C++ -*-===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef LLVM_LIBC_SHARED_LIBC_COMMON_H | |
| 10 | #define LLVM_LIBC_SHARED_LIBC_COMMON_H | |
| 11 | ||
| 12 | // Use system errno. | |
| 13 | #ifdef LIBC_ERRNO_MODE | |
| 14 | #if LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM_INLINE | |
| 15 | #error \ | |
| 16 | "LIBC_ERRNO_MODE was set to something different from LIBC_ERRNO_MODE_SYSTEM_INLINE." | |
| 17 | #endif // LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM_INLINE | |
| 18 | #else | |
| 19 | #define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM_INLINE | |
| 20 | #endif // LIBC_ERRNO_MODE | |
| 21 | ||
| 22 | #ifndef LIBC_NAMESPACE | |
| 23 | #define LIBC_NAMESPACE __llvm_libc | |
| 24 | #endif // LIBC_NAMESPACE | |
| 25 | ||
| 26 | #endif // LLVM_LIBC_SHARED_LIBC_COMMON_H |
lib/libcxx/libc/shared/str_to_float.h+1| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #ifndef LLVM_LIBC_SHARED_STR_TO_FLOAT_H |
| 10 | 10 | #define LLVM_LIBC_SHARED_STR_TO_FLOAT_H |
| 11 | 11 | |
| 12 | #include "libc_common.h" | |
| 12 | 13 | #include "src/__support/str_to_float.h" |
| 13 | 14 | |
| 14 | 15 | namespace LIBC_NAMESPACE_DECL { |
lib/libcxx/libc/shared/str_to_integer.h+1| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #ifndef LLVM_LIBC_SHARED_STR_TO_INTEGER_H |
| 10 | 10 | #define LLVM_LIBC_SHARED_STR_TO_INTEGER_H |
| 11 | 11 | |
| 12 | #include "libc_common.h" | |
| 12 | 13 | #include "src/__support/str_to_integer.h" |
| 13 | 14 | |
| 14 | 15 | namespace LIBC_NAMESPACE_DECL { |
lib/libcxx/libc/src/__support/CPP/bit.h+8-8| ... | ... | @@ -101,7 +101,7 @@ countr_zero(T value) { |
| 101 | 101 | shift >>= 1; |
| 102 | 102 | mask >>= shift; |
| 103 | 103 | } |
| 104 | return zero_bits; | |
| 104 | return static_cast<int>(zero_bits); | |
| 105 | 105 | } |
| 106 | 106 | #if __has_builtin(__builtin_ctzs) |
| 107 | 107 | ADD_SPECIALIZATION(countr_zero, unsigned short, __builtin_ctzs) |
| ... | ... | @@ -140,7 +140,7 @@ countl_zero(T value) { |
| 140 | 140 | else |
| 141 | 141 | zero_bits |= shift; |
| 142 | 142 | } |
| 143 | return zero_bits; | |
| 143 | return static_cast<int>(zero_bits); | |
| 144 | 144 | } |
| 145 | 145 | #if __has_builtin(__builtin_clzs) |
| 146 | 146 | ADD_SPECIALIZATION(countl_zero, unsigned short, __builtin_clzs) |
| ... | ... | @@ -162,7 +162,7 @@ ADD_SPECIALIZATION(countl_zero, unsigned long long, __builtin_clzll) |
| 162 | 162 | template <typename T> |
| 163 | 163 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int> |
| 164 | 164 | countl_one(T value) { |
| 165 | return cpp::countl_zero<T>(~value); | |
| 165 | return cpp::countl_zero<T>(static_cast<T>(~value)); | |
| 166 | 166 | } |
| 167 | 167 | |
| 168 | 168 | /// Count the number of ones from the least significant bit to the first |
| ... | ... | @@ -175,7 +175,7 @@ countl_one(T value) { |
| 175 | 175 | template <typename T> |
| 176 | 176 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int> |
| 177 | 177 | countr_one(T value) { |
| 178 | return cpp::countr_zero<T>(~value); | |
| 178 | return cpp::countr_zero<T>(static_cast<T>(~value)); | |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | 181 | /// Returns the number of bits needed to represent value if value is nonzero. |
| ... | ... | @@ -226,25 +226,25 @@ rotr(T value, int rotate); |
| 226 | 226 | template <typename T> |
| 227 | 227 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T> |
| 228 | 228 | rotl(T value, int rotate) { |
| 229 | constexpr unsigned N = cpp::numeric_limits<T>::digits; | |
| 229 | constexpr int N = cpp::numeric_limits<T>::digits; | |
| 230 | 230 | rotate = rotate % N; |
| 231 | 231 | if (!rotate) |
| 232 | 232 | return value; |
| 233 | 233 | if (rotate < 0) |
| 234 | 234 | return cpp::rotr<T>(value, -rotate); |
| 235 | return (value << rotate) | (value >> (N - rotate)); | |
| 235 | return static_cast<T>((value << rotate) | (value >> (N - rotate))); | |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | 238 | template <typename T> |
| 239 | 239 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T> |
| 240 | 240 | rotr(T value, int rotate) { |
| 241 | constexpr unsigned N = cpp::numeric_limits<T>::digits; | |
| 241 | constexpr int N = cpp::numeric_limits<T>::digits; | |
| 242 | 242 | rotate = rotate % N; |
| 243 | 243 | if (!rotate) |
| 244 | 244 | return value; |
| 245 | 245 | if (rotate < 0) |
| 246 | 246 | return cpp::rotl<T>(value, -rotate); |
| 247 | return (value >> rotate) | (value << (N - rotate)); | |
| 247 | return static_cast<T>((value >> rotate) | (value << (N - rotate))); | |
| 248 | 248 | } |
| 249 | 249 | |
| 250 | 250 | // TODO: Do we need this function at all? How is it different from |
lib/libcxx/libc/src/__support/CPP/string_view.h+4-2| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_STRING_VIEW_H |
| 10 | 10 | #define LLVM_LIBC_SRC___SUPPORT_CPP_STRING_VIEW_H |
| 11 | 11 | |
| 12 | #include "limits.h" | |
| 12 | 13 | #include "src/__support/common.h" |
| 13 | 14 | #include "src/__support/macros/config.h" |
| 14 | 15 | |
| ... | ... | @@ -40,7 +41,7 @@ private: |
| 40 | 41 | LIBC_INLINE static constexpr size_t length(const char *Str) { |
| 41 | 42 | for (const char *End = Str;; ++End) |
| 42 | 43 | if (*End == '\0') |
| 43 | return End - Str; | |
| 44 | return static_cast<size_t>(End - Str); | |
| 44 | 45 | } |
| 45 | 46 | |
| 46 | 47 | LIBC_INLINE bool equals(string_view Other) const { |
| ... | ... | @@ -61,7 +62,8 @@ public: |
| 61 | 62 | |
| 62 | 63 | // special value equal to the maximum value representable by the type |
| 63 | 64 | // size_type. |
| 64 | LIBC_INLINE_VAR static constexpr size_t npos = -1; | |
| 65 | LIBC_INLINE_VAR static constexpr size_t npos = | |
| 66 | cpp::numeric_limits<size_t>::max(); | |
| 65 | 67 | |
| 66 | 68 | LIBC_INLINE constexpr string_view() : Data(nullptr), Len(0) {} |
| 67 | 69 |
lib/libcxx/libc/src/__support/CPP/type_traits/is_floating_point.h+2-1| ... | ... | @@ -36,7 +36,8 @@ public: |
| 36 | 36 | , |
| 37 | 37 | float128 |
| 38 | 38 | #endif |
| 39 | >(); | |
| 39 | , | |
| 40 | bfloat16>(); | |
| 40 | 41 | }; |
| 41 | 42 | template <typename T> |
| 42 | 43 | LIBC_INLINE_VAR constexpr bool is_floating_point_v = |
lib/libcxx/libc/src/__support/CPP/type_traits/is_signed.h+24-1| ... | ... | @@ -8,20 +8,43 @@ |
| 8 | 8 | #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_SIGNED_H |
| 9 | 9 | #define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_SIGNED_H |
| 10 | 10 | |
| 11 | #include "include/llvm-libc-macros/stdfix-macros.h" | |
| 11 | 12 | #include "src/__support/CPP/type_traits/bool_constant.h" |
| 12 | 13 | #include "src/__support/CPP/type_traits/is_arithmetic.h" |
| 14 | #include "src/__support/CPP/type_traits/is_same.h" | |
| 15 | #include "src/__support/CPP/type_traits/remove_cv.h" | |
| 13 | 16 | #include "src/__support/macros/attributes.h" |
| 14 | 17 | #include "src/__support/macros/config.h" |
| 15 | 18 | |
| 16 | 19 | namespace LIBC_NAMESPACE_DECL { |
| 17 | 20 | namespace cpp { |
| 18 | 21 | |
| 19 | // is_signed | |
| 22 | #ifndef LIBC_COMPILER_HAS_FIXED_POINT | |
| 20 | 23 | template <typename T> |
| 21 | 24 | struct is_signed : bool_constant<(is_arithmetic_v<T> && (T(-1) < T(0)))> { |
| 22 | 25 | LIBC_INLINE constexpr operator bool() const { return is_signed::value; } |
| 23 | 26 | LIBC_INLINE constexpr bool operator()() const { return is_signed::value; } |
| 24 | 27 | }; |
| 28 | #else | |
| 29 | template <typename T> struct is_signed { | |
| 30 | private: | |
| 31 | template <typename Head, typename... Args> | |
| 32 | LIBC_INLINE static constexpr bool __is_unqualified_any_of() { | |
| 33 | return (... || is_same_v<remove_cv_t<Head>, Args>); | |
| 34 | } | |
| 35 | ||
| 36 | public: | |
| 37 | LIBC_INLINE_VAR static constexpr bool value = | |
| 38 | (is_arithmetic_v<T> && (T(-1) < T(0))) || | |
| 39 | __is_unqualified_any_of<T, short fract, fract, long fract, short accum, | |
| 40 | accum, long accum, short sat fract, sat fract, | |
| 41 | long sat fract, short sat accum, sat accum, | |
| 42 | long sat accum>(); | |
| 43 | LIBC_INLINE constexpr operator bool() const { return is_signed::value; } | |
| 44 | LIBC_INLINE constexpr bool operator()() const { return is_signed::value; } | |
| 45 | }; | |
| 46 | #endif // LIBC_COMPILER_HAS_FIXED_POINT | |
| 47 | ||
| 25 | 48 | template <typename T> |
| 26 | 49 | LIBC_INLINE_VAR constexpr bool is_signed_v = is_signed<T>::value; |
| 27 | 50 |
lib/libcxx/libc/src/__support/CPP/type_traits/is_unsigned.h+26-1| ... | ... | @@ -8,20 +8,45 @@ |
| 8 | 8 | #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_UNSIGNED_H |
| 9 | 9 | #define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_UNSIGNED_H |
| 10 | 10 | |
| 11 | #include "include/llvm-libc-macros/stdfix-macros.h" | |
| 11 | 12 | #include "src/__support/CPP/type_traits/bool_constant.h" |
| 12 | 13 | #include "src/__support/CPP/type_traits/is_arithmetic.h" |
| 14 | #include "src/__support/CPP/type_traits/is_same.h" | |
| 15 | #include "src/__support/CPP/type_traits/remove_cv.h" | |
| 13 | 16 | #include "src/__support/macros/attributes.h" |
| 14 | 17 | #include "src/__support/macros/config.h" |
| 15 | 18 | |
| 16 | 19 | namespace LIBC_NAMESPACE_DECL { |
| 17 | 20 | namespace cpp { |
| 18 | 21 | |
| 19 | // is_unsigned | |
| 22 | #ifndef LIBC_COMPILER_HAS_FIXED_POINT | |
| 20 | 23 | template <typename T> |
| 21 | 24 | struct is_unsigned : bool_constant<(is_arithmetic_v<T> && (T(-1) > T(0)))> { |
| 22 | 25 | LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; } |
| 23 | 26 | LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; } |
| 24 | 27 | }; |
| 28 | #else | |
| 29 | template <typename T> struct is_unsigned { | |
| 30 | private: | |
| 31 | template <typename Head, typename... Args> | |
| 32 | LIBC_INLINE static constexpr bool __is_unqualified_any_of() { | |
| 33 | return (... || is_same_v<remove_cv_t<Head>, Args>); | |
| 34 | } | |
| 35 | ||
| 36 | public: | |
| 37 | LIBC_INLINE_VAR static constexpr bool value = | |
| 38 | (is_arithmetic_v<T> && (T(-1) > T(0))) || | |
| 39 | __is_unqualified_any_of<T, unsigned short fract, unsigned fract, | |
| 40 | unsigned long fract, unsigned short accum, | |
| 41 | unsigned accum, unsigned long accum, | |
| 42 | unsigned short sat fract, unsigned sat fract, | |
| 43 | unsigned long sat fract, unsigned short sat accum, | |
| 44 | unsigned sat accum, unsigned long sat accum>(); | |
| 45 | LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; } | |
| 46 | LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; } | |
| 47 | }; | |
| 48 | #endif // LIBC_COMPILER_HAS_FIXED_POINT | |
| 49 | ||
| 25 | 50 | template <typename T> |
| 26 | 51 | LIBC_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned<T>::value; |
| 27 | 52 |
lib/libcxx/libc/src/__support/FPUtil/FPBits.h+15-4| ... | ... | @@ -38,6 +38,7 @@ enum class FPType { |
| 38 | 38 | IEEE754_Binary64, |
| 39 | 39 | IEEE754_Binary128, |
| 40 | 40 | X86_Binary80, |
| 41 | BFloat16 | |
| 41 | 42 | }; |
| 42 | 43 | |
| 43 | 44 | // The classes hierarchy is as follows: |
| ... | ... | @@ -138,6 +139,14 @@ template <> struct FPLayout<FPType::X86_Binary80> { |
| 138 | 139 | LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN - 1; |
| 139 | 140 | }; |
| 140 | 141 | |
| 142 | template <> struct FPLayout<FPType::BFloat16> { | |
| 143 | using StorageType = uint16_t; | |
| 144 | LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1; | |
| 145 | LIBC_INLINE_VAR static constexpr int EXP_LEN = 8; | |
| 146 | LIBC_INLINE_VAR static constexpr int SIG_LEN = 7; | |
| 147 | LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN; | |
| 148 | }; | |
| 149 | ||
| 141 | 150 | // FPStorage derives useful constants from the FPLayout above. |
| 142 | 151 | template <FPType fp_type> struct FPStorage : public FPLayout<fp_type> { |
| 143 | 152 | using UP = FPLayout<fp_type>; |
| ... | ... | @@ -247,11 +256,11 @@ protected: |
| 247 | 256 | using UP::UP; |
| 248 | 257 | |
| 249 | 258 | LIBC_INLINE constexpr BiasedExponent(Exponent exp) |
| 250 | : UP(static_cast<int32_t>(exp) + EXP_BIAS) {} | |
| 259 | : UP(static_cast<uint32_t>(static_cast<int32_t>(exp) + EXP_BIAS)) {} | |
| 251 | 260 | |
| 252 | 261 | // Cast operator to get convert from BiasedExponent to Exponent. |
| 253 | 262 | LIBC_INLINE constexpr operator Exponent() const { |
| 254 | return Exponent(UP::value - EXP_BIAS); | |
| 263 | return Exponent(static_cast<int32_t>(UP::value - EXP_BIAS)); | |
| 255 | 264 | } |
| 256 | 265 | |
| 257 | 266 | LIBC_INLINE constexpr BiasedExponent &operator++() { |
| ... | ... | @@ -686,7 +695,7 @@ public: |
| 686 | 695 | } |
| 687 | 696 | |
| 688 | 697 | LIBC_INLINE constexpr void set_biased_exponent(StorageType biased) { |
| 689 | UP::set_biased_exponent(BiasedExponent((int32_t)biased)); | |
| 698 | UP::set_biased_exponent(BiasedExponent(static_cast<uint32_t>(biased))); | |
| 690 | 699 | } |
| 691 | 700 | |
| 692 | 701 | LIBC_INLINE constexpr int get_exponent() const { |
| ... | ... | @@ -757,7 +766,7 @@ public: |
| 757 | 766 | result.set_significand(number); |
| 758 | 767 | result.set_biased_exponent(static_cast<StorageType>(ep + 1)); |
| 759 | 768 | } else { |
| 760 | result.set_significand(number >> -ep); | |
| 769 | result.set_significand(number >> static_cast<unsigned>(-ep)); | |
| 761 | 770 | } |
| 762 | 771 | return RetT(result.uintval()); |
| 763 | 772 | } |
| ... | ... | @@ -801,6 +810,8 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() { |
| 801 | 810 | else if constexpr (cpp::is_same_v<UnqualT, float128>) |
| 802 | 811 | return FPType::IEEE754_Binary128; |
| 803 | 812 | #endif |
| 813 | else if constexpr (cpp::is_same_v<UnqualT, bfloat16>) | |
| 814 | return FPType::BFloat16; | |
| 804 | 815 | else |
| 805 | 816 | static_assert(cpp::always_false<UnqualT>, "Unsupported type"); |
| 806 | 817 | } |
lib/libcxx/libc/src/__support/big_int.h+33-26| ... | ... | @@ -241,7 +241,7 @@ LIBC_INLINE constexpr void quick_mul_hi(cpp::array<word, N> &dst, |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | 243 | template <typename word, size_t N> |
| 244 | LIBC_INLINE constexpr bool is_negative(cpp::array<word, N> &array) { | |
| 244 | LIBC_INLINE constexpr bool is_negative(const cpp::array<word, N> &array) { | |
| 245 | 245 | using signed_word = cpp::make_signed_t<word>; |
| 246 | 246 | return cpp::bit_cast<signed_word>(array.back()) < 0; |
| 247 | 247 | } |
| ... | ... | @@ -284,8 +284,8 @@ LIBC_INLINE constexpr cpp::array<word, N> shift(cpp::array<word, N> array, |
| 284 | 284 | if (i < 0) |
| 285 | 285 | return 0; |
| 286 | 286 | if (i >= int(N)) |
| 287 | return is_neg ? -1 : 0; | |
| 288 | return array[i]; | |
| 287 | return is_neg ? cpp::numeric_limits<word>::max() : 0; | |
| 288 | return array[static_cast<unsigned>(i)]; | |
| 289 | 289 | }; |
| 290 | 290 | const size_t index_offset = offset / WORD_BITS; |
| 291 | 291 | const size_t bit_offset = offset % WORD_BITS; |
| ... | ... | @@ -296,7 +296,7 @@ LIBC_INLINE constexpr cpp::array<word, N> shift(cpp::array<word, N> array, |
| 296 | 296 | for (size_t index = 0; index < N; ++index) { |
| 297 | 297 | const word part1 = safe_get_at(index + index_offset); |
| 298 | 298 | const word part2 = safe_get_at(index + index_offset + 1); |
| 299 | word &dst = out[at(index)]; | |
| 299 | word &dst = out[static_cast<unsigned>(at(index))]; | |
| 300 | 300 | if (bit_offset == 0) |
| 301 | 301 | dst = part1; // no crosstalk between parts. |
| 302 | 302 | else if constexpr (direction == LEFT) |
| ... | ... | @@ -465,8 +465,7 @@ public: |
| 465 | 465 | } |
| 466 | 466 | |
| 467 | 467 | // Initialize the first word to |v| and the rest to 0. |
| 468 | template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T> && | |
| 469 | !cpp::is_same_v<T, bool>>> | |
| 468 | template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T>>> | |
| 470 | 469 | LIBC_INLINE constexpr BigInt(T v) { |
| 471 | 470 | constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT; |
| 472 | 471 | const bool is_neg = v < 0; |
| ... | ... | @@ -697,7 +696,8 @@ public: |
| 697 | 696 | } |
| 698 | 697 | BigInt quotient; |
| 699 | 698 | WordType x_word = static_cast<WordType>(x); |
| 700 | constexpr size_t LOG2_WORD_SIZE = cpp::bit_width(WORD_SIZE) - 1; | |
| 699 | constexpr size_t LOG2_WORD_SIZE = | |
| 700 | static_cast<size_t>(cpp::bit_width(WORD_SIZE) - 1); | |
| 701 | 701 | constexpr size_t HALF_WORD_SIZE = WORD_SIZE >> 1; |
| 702 | 702 | constexpr WordType HALF_MASK = ((WordType(1) << HALF_WORD_SIZE) - 1); |
| 703 | 703 | // lower = smallest multiple of WORD_SIZE that is >= e. |
| ... | ... | @@ -866,7 +866,7 @@ public: |
| 866 | 866 | LIBC_INLINE constexpr BigInt operator~() const { |
| 867 | 867 | BigInt result; |
| 868 | 868 | for (size_t i = 0; i < WORD_COUNT; ++i) |
| 869 | result[i] = ~val[i]; | |
| 869 | result[i] = static_cast<WordType>(~val[i]); | |
| 870 | 870 | return result; |
| 871 | 871 | } |
| 872 | 872 | |
| ... | ... | @@ -936,6 +936,18 @@ public: |
| 936 | 936 | // Return the i-th word of the number. |
| 937 | 937 | LIBC_INLINE constexpr WordType &operator[](size_t i) { return val[i]; } |
| 938 | 938 | |
| 939 | // Return the i-th bit of the number. | |
| 940 | LIBC_INLINE constexpr bool get_bit(size_t i) const { | |
| 941 | const size_t word_index = i / WORD_SIZE; | |
| 942 | return 1 & (val[word_index] >> (i % WORD_SIZE)); | |
| 943 | } | |
| 944 | ||
| 945 | // Set the i-th bit of the number. | |
| 946 | LIBC_INLINE constexpr void set_bit(size_t i) { | |
| 947 | const size_t word_index = i / WORD_SIZE; | |
| 948 | val[word_index] |= WordType(1) << (i % WORD_SIZE); | |
| 949 | } | |
| 950 | ||
| 939 | 951 | private: |
| 940 | 952 | LIBC_INLINE friend constexpr int cmp(const BigInt &lhs, const BigInt &rhs) { |
| 941 | 953 | constexpr auto compare = [](WordType a, WordType b) { |
| ... | ... | @@ -955,7 +967,7 @@ private: |
| 955 | 967 | |
| 956 | 968 | LIBC_INLINE constexpr void bitwise_not() { |
| 957 | 969 | for (auto &part : val) |
| 958 | part = ~part; | |
| 970 | part = static_cast<WordType>(~part); | |
| 959 | 971 | } |
| 960 | 972 | |
| 961 | 973 | LIBC_INLINE constexpr void negate() { |
| ... | ... | @@ -968,7 +980,7 @@ private: |
| 968 | 980 | } |
| 969 | 981 | |
| 970 | 982 | LIBC_INLINE constexpr void decrement() { |
| 971 | multiword::add_with_carry(val, cpp::array<WordType, 1>{1}); | |
| 983 | multiword::sub_with_borrow(val, cpp::array<WordType, 1>{1}); | |
| 972 | 984 | } |
| 973 | 985 | |
| 974 | 986 | LIBC_INLINE constexpr void extend(size_t index, bool is_neg) { |
| ... | ... | @@ -989,12 +1001,6 @@ private: |
| 989 | 1001 | LIBC_INLINE constexpr void clear_msb() { |
| 990 | 1002 | val.back() &= mask_trailing_ones<WordType, WORD_SIZE - 1>(); |
| 991 | 1003 | } |
| 992 | ||
| 993 | LIBC_INLINE constexpr void set_bit(size_t i) { | |
| 994 | const size_t word_index = i / WORD_SIZE; | |
| 995 | val[word_index] |= WordType(1) << (i % WORD_SIZE); | |
| 996 | } | |
| 997 | ||
| 998 | 1004 | LIBC_INLINE constexpr static Division divide_unsigned(const BigInt &dividend, |
| 999 | 1005 | const BigInt &divider) { |
| 1000 | 1006 | BigInt remainder = dividend; |
| ... | ... | @@ -1003,12 +1009,12 @@ private: |
| 1003 | 1009 | BigInt subtractor = divider; |
| 1004 | 1010 | int cur_bit = multiword::countl_zero(subtractor.val) - |
| 1005 | 1011 | multiword::countl_zero(remainder.val); |
| 1006 | subtractor <<= cur_bit; | |
| 1012 | subtractor <<= static_cast<size_t>(cur_bit); | |
| 1007 | 1013 | for (; cur_bit >= 0 && remainder > 0; --cur_bit, subtractor >>= 1) { |
| 1008 | 1014 | if (remainder < subtractor) |
| 1009 | 1015 | continue; |
| 1010 | 1016 | remainder -= subtractor; |
| 1011 | quotient.set_bit(cur_bit); | |
| 1017 | quotient.set_bit(static_cast<size_t>(cur_bit)); | |
| 1012 | 1018 | } |
| 1013 | 1019 | } |
| 1014 | 1020 | return Division{quotient, remainder}; |
| ... | ... | @@ -1270,26 +1276,28 @@ rotr(T value, int rotate); |
| 1270 | 1276 | template <typename T> |
| 1271 | 1277 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> |
| 1272 | 1278 | rotl(T value, int rotate) { |
| 1273 | constexpr unsigned N = cpp::numeric_limits<T>::digits; | |
| 1279 | constexpr int N = cpp::numeric_limits<T>::digits; | |
| 1274 | 1280 | rotate = rotate % N; |
| 1275 | 1281 | if (!rotate) |
| 1276 | 1282 | return value; |
| 1277 | 1283 | if (rotate < 0) |
| 1278 | 1284 | return cpp::rotr<T>(value, -rotate); |
| 1279 | return (value << rotate) | (value >> (N - rotate)); | |
| 1285 | return (value << static_cast<size_t>(rotate)) | | |
| 1286 | (value >> (N - static_cast<size_t>(rotate))); | |
| 1280 | 1287 | } |
| 1281 | 1288 | |
| 1282 | 1289 | // Specialization of cpp::rotr ('bit.h') for BigInt. |
| 1283 | 1290 | template <typename T> |
| 1284 | 1291 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> |
| 1285 | 1292 | rotr(T value, int rotate) { |
| 1286 | constexpr unsigned N = cpp::numeric_limits<T>::digits; | |
| 1293 | constexpr int N = cpp::numeric_limits<T>::digits; | |
| 1287 | 1294 | rotate = rotate % N; |
| 1288 | 1295 | if (!rotate) |
| 1289 | 1296 | return value; |
| 1290 | 1297 | if (rotate < 0) |
| 1291 | 1298 | return cpp::rotl<T>(value, -rotate); |
| 1292 | return (value >> rotate) | (value << (N - rotate)); | |
| 1299 | return (value >> static_cast<size_t>(rotate)) | | |
| 1300 | (value << (N - static_cast<size_t>(rotate))); | |
| 1293 | 1301 | } |
| 1294 | 1302 | |
| 1295 | 1303 | } // namespace cpp |
| ... | ... | @@ -1306,7 +1314,7 @@ mask_trailing_ones() { |
| 1306 | 1314 | T out; // zero initialized |
| 1307 | 1315 | for (size_t i = 0; i <= QUOTIENT; ++i) |
| 1308 | 1316 | out[i] = i < QUOTIENT |
| 1309 | ? -1 | |
| 1317 | ? cpp::numeric_limits<typename T::word_type>::max() | |
| 1310 | 1318 | : mask_trailing_ones<typename T::word_type, REMAINDER>(); |
| 1311 | 1319 | return out; |
| 1312 | 1320 | } |
| ... | ... | @@ -1322,7 +1330,7 @@ LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> mask_leading_ones() { |
| 1322 | 1330 | T out; // zero initialized |
| 1323 | 1331 | for (size_t i = QUOTIENT; i < T::WORD_COUNT; ++i) |
| 1324 | 1332 | out[i] = i > QUOTIENT |
| 1325 | ? -1 | |
| 1333 | ? cpp::numeric_limits<typename T::word_type>::max() | |
| 1326 | 1334 | : mask_leading_ones<typename T::word_type, REMAINDER>(); |
| 1327 | 1335 | return out; |
| 1328 | 1336 | } |
| ... | ... | @@ -1375,8 +1383,7 @@ first_trailing_zero(T value) { |
| 1375 | 1383 | template <typename T> |
| 1376 | 1384 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> |
| 1377 | 1385 | first_trailing_one(T value) { |
| 1378 | return value == cpp::numeric_limits<T>::max() ? 0 | |
| 1379 | : cpp::countr_zero(value) + 1; | |
| 1386 | return value == 0 ? 0 : cpp::countr_zero(value) + 1; | |
| 1380 | 1387 | } |
| 1381 | 1388 | |
| 1382 | 1389 | } // namespace LIBC_NAMESPACE_DECL |
lib/libcxx/libc/src/__support/common.h+14-4| ... | ... | @@ -37,17 +37,27 @@ |
| 37 | 37 | |
| 38 | 38 | #define LLVM_LIBC_ATTR(name) EXPAND_THEN_SECOND(LLVM_LIBC_FUNCTION_ATTR_##name) |
| 39 | 39 | |
| 40 | // MacOS needs to be excluded because it does not support aliasing. | |
| 41 | #if defined(LIBC_COPT_PUBLIC_PACKAGING) && (!defined(__APPLE__)) | |
| 40 | // At the moment, [[gnu::alias()]] is not supported on MacOS, and it is needed | |
| 41 | // to cleanly export and alias the C++ symbol `LIBC_NAMESPACE::func` with the C | |
| 42 | // symbol `func`. So for public packaging on MacOS, we will only export the C | |
| 43 | // symbol. Moreover, a C symbol `func` in macOS is mangled as `_func`. | |
| 44 | #if defined(LIBC_COPT_PUBLIC_PACKAGING) | |
| 45 | #ifndef __APPLE__ | |
| 42 | 46 | #define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \ |
| 43 | 47 | LLVM_LIBC_ATTR(name) \ |
| 44 | 48 | LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \ |
| 45 | 49 | __##name##_impl__ __asm__(#name); \ |
| 46 | 50 | decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]]; \ |
| 47 | 51 | type __##name##_impl__ arglist |
| 48 | #else | |
| 52 | #else // __APPLE__ | |
| 53 | #define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \ | |
| 54 | LLVM_LIBC_ATTR(name) \ | |
| 55 | LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) name asm("_" #name); \ | |
| 56 | type name arglist | |
| 57 | #endif // __APPLE__ | |
| 58 | #else // LIBC_COPT_PUBLIC_PACKAGING | |
| 49 | 59 | #define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) type name arglist |
| 50 | #endif | |
| 60 | #endif // LIBC_COPT_PUBLIC_PACKAGING | |
| 51 | 61 | |
| 52 | 62 | // This extra layer of macro allows `name` to be a macro to rename a function. |
| 53 | 63 | #define LLVM_LIBC_FUNCTION(type, name, arglist) \ |
lib/libcxx/libc/src/__support/high_precision_decimal.h+7-7| ... | ... | @@ -264,7 +264,7 @@ private: |
| 264 | 264 | LIBC_INLINE void left_shift(uint32_t shift_amount) { |
| 265 | 265 | uint32_t new_digits = this->get_num_new_digits(shift_amount); |
| 266 | 266 | |
| 267 | int32_t read_index = this->num_digits - 1; | |
| 267 | int32_t read_index = static_cast<int32_t>(this->num_digits - 1); | |
| 268 | 268 | uint32_t write_index = this->num_digits + new_digits; |
| 269 | 269 | |
| 270 | 270 | uint64_t accumulator = 0; |
| ... | ... | @@ -329,7 +329,7 @@ public: |
| 329 | 329 | if (saw_dot) { |
| 330 | 330 | break; |
| 331 | 331 | } |
| 332 | this->decimal_point = total_digits; | |
| 332 | this->decimal_point = static_cast<int32_t>(total_digits); | |
| 333 | 333 | saw_dot = true; |
| 334 | 334 | } else { |
| 335 | 335 | if (num_string[num_cur] == '0' && this->num_digits == 0) { |
| ... | ... | @@ -350,7 +350,7 @@ public: |
| 350 | 350 | } |
| 351 | 351 | |
| 352 | 352 | if (!saw_dot) |
| 353 | this->decimal_point = total_digits; | |
| 353 | this->decimal_point = static_cast<int32_t>(total_digits); | |
| 354 | 354 | |
| 355 | 355 | if (num_cur < num_len && |
| 356 | 356 | (num_string[num_cur] == 'e' || num_string[num_cur] == 'E')) { |
| ... | ... | @@ -393,7 +393,7 @@ public: |
| 393 | 393 | this->left_shift(MAX_SHIFT_AMOUNT); |
| 394 | 394 | shift_amount -= MAX_SHIFT_AMOUNT; |
| 395 | 395 | } |
| 396 | this->left_shift(shift_amount); | |
| 396 | this->left_shift(static_cast<uint32_t>(shift_amount)); | |
| 397 | 397 | } |
| 398 | 398 | // Right |
| 399 | 399 | else { |
| ... | ... | @@ -401,7 +401,7 @@ public: |
| 401 | 401 | this->right_shift(MAX_SHIFT_AMOUNT); |
| 402 | 402 | shift_amount += MAX_SHIFT_AMOUNT; |
| 403 | 403 | } |
| 404 | this->right_shift(-shift_amount); | |
| 404 | this->right_shift(static_cast<uint32_t>(-shift_amount)); | |
| 405 | 405 | } |
| 406 | 406 | } |
| 407 | 407 | |
| ... | ... | @@ -424,8 +424,8 @@ public: |
| 424 | 424 | result *= 10; |
| 425 | 425 | ++cur_digit; |
| 426 | 426 | } |
| 427 | return result + static_cast<unsigned int>( | |
| 428 | this->should_round_up(this->decimal_point, round)); | |
| 427 | return result + | |
| 428 | static_cast<T>(this->should_round_up(this->decimal_point, round)); | |
| 429 | 429 | } |
| 430 | 430 | |
| 431 | 431 | // Extra functions for testing. |
lib/libcxx/libc/src/__support/libc_assert.h+1-1| ... | ... | @@ -9,7 +9,6 @@ |
| 9 | 9 | #ifndef LLVM_LIBC_SRC___SUPPORT_LIBC_ASSERT_H |
| 10 | 10 | #define LLVM_LIBC_SRC___SUPPORT_LIBC_ASSERT_H |
| 11 | 11 | |
| 12 | #include "src/__support/macros/config.h" | |
| 13 | 12 | #if defined(LIBC_COPT_USE_C_ASSERT) || !defined(LIBC_FULL_BUILD) |
| 14 | 13 | |
| 15 | 14 | // The build is configured to just use the public <assert.h> API |
| ... | ... | @@ -25,6 +24,7 @@ |
| 25 | 24 | #include "src/__support/OSUtil/io.h" |
| 26 | 25 | #include "src/__support/integer_to_string.h" |
| 27 | 26 | #include "src/__support/macros/attributes.h" // For LIBC_INLINE |
| 27 | #include "src/__support/macros/config.h" | |
| 28 | 28 | #include "src/__support/macros/optimization.h" // For LIBC_UNLIKELY |
| 29 | 29 | |
| 30 | 30 | namespace LIBC_NAMESPACE_DECL { |
lib/libcxx/libc/src/__support/macros/null_check.h+9| ... | ... | @@ -19,10 +19,19 @@ |
| 19 | 19 | if (LIBC_UNLIKELY((ptr) == nullptr)) \ |
| 20 | 20 | __builtin_trap(); \ |
| 21 | 21 | } while (0) |
| 22 | #define LIBC_CRASH_ON_VALUE(var, value) \ | |
| 23 | do { \ | |
| 24 | if (LIBC_UNLIKELY((var) == (value))) \ | |
| 25 | __builtin_trap(); \ | |
| 26 | } while (0) | |
| 27 | ||
| 22 | 28 | #else |
| 23 | 29 | #define LIBC_CRASH_ON_NULLPTR(ptr) \ |
| 24 | 30 | do { \ |
| 25 | 31 | } while (0) |
| 32 | #define LIBC_CRASH_ON_VALUE(var, value) \ | |
| 33 | do { \ | |
| 34 | } while (0) | |
| 26 | 35 | #endif |
| 27 | 36 | |
| 28 | 37 | #endif // LLVM_LIBC_SRC___SUPPORT_MACROS_NULL_CHECK_H |
lib/libcxx/libc/src/__support/macros/optimization.h+16-1| ... | ... | @@ -10,7 +10,7 @@ |
| 10 | 10 | #ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H |
| 11 | 11 | #define LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H |
| 12 | 12 | |
| 13 | #include "src/__support/macros/attributes.h" // LIBC_INLINE | |
| 13 | #include "src/__support/macros/attributes.h" // LIBC_INLINE | |
| 14 | 14 | #include "src/__support/macros/config.h" |
| 15 | 15 | #include "src/__support/macros/properties/compiler.h" // LIBC_COMPILER_IS_CLANG |
| 16 | 16 | |
| ... | ... | @@ -30,8 +30,10 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) { |
| 30 | 30 | |
| 31 | 31 | #if defined(LIBC_COMPILER_IS_CLANG) |
| 32 | 32 | #define LIBC_LOOP_NOUNROLL _Pragma("nounroll") |
| 33 | #define LIBC_LOOP_UNROLL _Pragma("unroll") | |
| 33 | 34 | #elif defined(LIBC_COMPILER_IS_GCC) |
| 34 | 35 | #define LIBC_LOOP_NOUNROLL _Pragma("GCC unroll 0") |
| 36 | #define LIBC_LOOP_UNROLL _Pragma("GCC unroll 2048") | |
| 35 | 37 | #else |
| 36 | 38 | #error "Unhandled compiler" |
| 37 | 39 | #endif |
| ... | ... | @@ -45,6 +47,7 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) { |
| 45 | 47 | #define LIBC_MATH_FAST \ |
| 46 | 48 | (LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | \ |
| 47 | 49 | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT) |
| 50 | #define LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT 0x10 | |
| 48 | 51 | |
| 49 | 52 | #ifndef LIBC_MATH |
| 50 | 53 | #define LIBC_MATH 0 |
| ... | ... | @@ -58,4 +61,16 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) { |
| 58 | 61 | #define LIBC_MATH_HAS_SMALL_TABLES |
| 59 | 62 | #endif |
| 60 | 63 | |
| 64 | #if (LIBC_MATH & LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT) | |
| 65 | #define LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT | |
| 66 | #endif | |
| 67 | ||
| 68 | #if (LIBC_MATH & LIBC_MATH_NO_ERRNO) | |
| 69 | #define LIBC_MATH_HAS_NO_ERRNO | |
| 70 | #endif | |
| 71 | ||
| 72 | #if (LIBC_MATH & LIBC_MATH_NO_EXCEPT) | |
| 73 | #define LIBC_MATH_HAS_NO_EXCEPT | |
| 74 | #endif | |
| 75 | ||
| 61 | 76 | #endif // LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H |
lib/libcxx/libc/src/__support/macros/properties/cpu_features.h+48| ... | ... | @@ -20,6 +20,8 @@ |
| 20 | 20 | |
| 21 | 21 | #if defined(__SSE2__) |
| 22 | 22 | #define LIBC_TARGET_CPU_HAS_SSE2 |
| 23 | #define LIBC_TARGET_CPU_HAS_FPU_FLOAT | |
| 24 | #define LIBC_TARGET_CPU_HAS_FPU_DOUBLE | |
| 23 | 25 | #endif |
| 24 | 26 | |
| 25 | 27 | #if defined(__SSE4_2__) |
| ... | ... | @@ -42,9 +44,55 @@ |
| 42 | 44 | #define LIBC_TARGET_CPU_HAS_AVX512BW |
| 43 | 45 | #endif |
| 44 | 46 | |
| 47 | #if defined(__ARM_FP) | |
| 48 | #if (__ARM_FP & 0x2) | |
| 49 | #define LIBC_TARGET_CPU_HAS_ARM_FPU_HALF | |
| 50 | #define LIBC_TARGET_CPU_HAS_FPU_HALF | |
| 51 | #endif // LIBC_TARGET_CPU_HAS_ARM_FPU_HALF | |
| 52 | #if (__ARM_FP & 0x4) | |
| 53 | #define LIBC_TARGET_CPU_HAS_ARM_FPU_FLOAT | |
| 54 | #define LIBC_TARGET_CPU_HAS_FPU_FLOAT | |
| 55 | #endif // LIBC_TARGET_CPU_HAS_ARM_FPU_FLOAT | |
| 56 | #if (__ARM_FP & 0x8) | |
| 57 | #define LIBC_TARGET_CPU_HAS_ARM_FPU_DOUBLE | |
| 58 | #define LIBC_TARGET_CPU_HAS_FPU_DOUBLE | |
| 59 | #endif // LIBC_TARGET_CPU_HAS_ARM_FPU_DOUBLE | |
| 60 | #endif // __ARM_FP | |
| 61 | ||
| 62 | #if defined(__riscv_flen) | |
| 63 | // https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc | |
| 64 | #if defined(__riscv_zfhmin) | |
| 65 | #define LIBC_TARGET_CPU_HAS_RISCV_FPU_HALF | |
| 66 | #define LIBC_TARGET_CPU_HAS_FPU_HALF | |
| 67 | #endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_HALF | |
| 68 | #if (__riscv_flen >= 32) | |
| 69 | #define LIBC_TARGET_CPU_HAS_RISCV_FPU_FLOAT | |
| 70 | #define LIBC_TARGET_CPU_HAS_FPU_FLOAT | |
| 71 | #endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_FLOAT | |
| 72 | #if (__riscv_flen >= 64) | |
| 73 | #define LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE | |
| 74 | #define LIBC_TARGET_CPU_HAS_FPU_DOUBLE | |
| 75 | #endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE | |
| 76 | #endif // __riscv_flen | |
| 77 | ||
| 78 | #if defined(__NVPTX__) || defined(__AMDGPU__) | |
| 79 | #define LIBC_TARGET_CPU_HAS_FPU_FLOAT | |
| 80 | #define LIBC_TARGET_CPU_HAS_FPU_DOUBLE | |
| 81 | #endif | |
| 82 | ||
| 45 | 83 | #if defined(__ARM_FEATURE_FMA) || (defined(__AVX2__) && defined(__FMA__)) || \ |
| 46 | 84 | defined(__NVPTX__) || defined(__AMDGPU__) || defined(__LIBC_RISCV_USE_FMA) |
| 47 | 85 | #define LIBC_TARGET_CPU_HAS_FMA |
| 86 | // Provide a more fine-grained control of FMA instruction for ARM targets. | |
| 87 | #if defined(LIBC_TARGET_CPU_HAS_FPU_HALF) | |
| 88 | #define LIBC_TARGET_CPU_HAS_FMA_HALF | |
| 89 | #endif // LIBC_TARGET_CPU_HAS_FMA_HALF | |
| 90 | #if defined(LIBC_TARGET_CPU_HAS_FPU_FLOAT) | |
| 91 | #define LIBC_TARGET_CPU_HAS_FMA_FLOAT | |
| 92 | #endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT | |
| 93 | #if defined(LIBC_TARGET_CPU_HAS_FPU_DOUBLE) | |
| 94 | #define LIBC_TARGET_CPU_HAS_FMA_DOUBLE | |
| 95 | #endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE | |
| 48 | 96 | #endif |
| 49 | 97 | |
| 50 | 98 | #if defined(LIBC_TARGET_ARCH_IS_AARCH64) || \ |
lib/libcxx/libc/src/__support/macros/properties/types.h+12-1| ... | ... | @@ -10,9 +10,10 @@ |
| 10 | 10 | #ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H |
| 11 | 11 | #define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H |
| 12 | 12 | |
| 13 | #include "hdr/float_macros.h" // LDBL_MANT_DIG | |
| 13 | #include "hdr/float_macros.h" // LDBL_MANT_DIG | |
| 14 | 14 | #include "include/llvm-libc-macros/float16-macros.h" // LIBC_TYPES_HAS_FLOAT16 |
| 15 | 15 | #include "include/llvm-libc-types/float128.h" // float128 |
| 16 | #include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL | |
| 16 | 17 | #include "src/__support/macros/properties/architectures.h" |
| 17 | 18 | #include "src/__support/macros/properties/compiler.h" |
| 18 | 19 | #include "src/__support/macros/properties/cpu_features.h" |
| ... | ... | @@ -58,4 +59,14 @@ using float16 = _Float16; |
| 58 | 59 | // LIBC_TYPES_HAS_FLOAT128 and 'float128' type are provided by |
| 59 | 60 | // "include/llvm-libc-types/float128.h" |
| 60 | 61 | |
| 62 | // -- bfloat16 support --------------------------------------------------------- | |
| 63 | ||
| 64 | namespace LIBC_NAMESPACE_DECL { | |
| 65 | namespace fputil { | |
| 66 | struct BFloat16; | |
| 67 | } | |
| 68 | } // namespace LIBC_NAMESPACE_DECL | |
| 69 | ||
| 70 | using bfloat16 = LIBC_NAMESPACE::fputil::BFloat16; | |
| 71 | ||
| 61 | 72 | #endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H |
lib/libcxx/libc/src/__support/math_extras.h+1-2| ... | ... | @@ -146,8 +146,7 @@ first_trailing_zero(T value) { |
| 146 | 146 | template <typename T> |
| 147 | 147 | [[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int> |
| 148 | 148 | first_trailing_one(T value) { |
| 149 | return value == cpp::numeric_limits<T>::max() ? 0 | |
| 150 | : cpp::countr_zero(value) + 1; | |
| 149 | return value == 0 ? 0 : cpp::countr_zero(value) + 1; | |
| 151 | 150 | } |
| 152 | 151 | |
| 153 | 152 | template <typename T> |
lib/libcxx/libc/src/__support/sign.h+2| ... | ... | @@ -29,6 +29,8 @@ struct Sign { |
| 29 | 29 | static const Sign POS; |
| 30 | 30 | static const Sign NEG; |
| 31 | 31 | |
| 32 | LIBC_INLINE constexpr Sign negate() const { return Sign(!is_negative); } | |
| 33 | ||
| 32 | 34 | private: |
| 33 | 35 | LIBC_INLINE constexpr explicit Sign(bool is_negative) |
| 34 | 36 | : is_negative(is_negative) {} |
lib/libcxx/libc/src/__support/str_to_float.h+13-13| ... | ... | @@ -15,6 +15,7 @@ |
| 15 | 15 | #ifndef LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H |
| 16 | 16 | #define LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H |
| 17 | 17 | |
| 18 | #include "hdr/errno_macros.h" // For ERANGE | |
| 18 | 19 | #include "src/__support/CPP/bit.h" |
| 19 | 20 | #include "src/__support/CPP/limits.h" |
| 20 | 21 | #include "src/__support/CPP/optional.h" |
| ... | ... | @@ -31,7 +32,6 @@ |
| 31 | 32 | #include "src/__support/str_to_integer.h" |
| 32 | 33 | #include "src/__support/str_to_num_result.h" |
| 33 | 34 | #include "src/__support/uint128.h" |
| 34 | #include "src/errno/libc_errno.h" // For ERANGE | |
| 35 | 35 | |
| 36 | 36 | #include <stdint.h> |
| 37 | 37 | |
| ... | ... | @@ -108,11 +108,11 @@ eisel_lemire(ExpandedFloat<T> init_num, |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | // Normalization |
| 111 | uint32_t clz = cpp::countl_zero<StorageType>(mantissa); | |
| 111 | uint32_t clz = static_cast<uint32_t>(cpp::countl_zero<StorageType>(mantissa)); | |
| 112 | 112 | mantissa <<= clz; |
| 113 | 113 | |
| 114 | int32_t exp2 = | |
| 115 | exp10_to_exp2(exp10) + FPBits::STORAGE_LEN + FPBits::EXP_BIAS - clz; | |
| 114 | int32_t exp2 = exp10_to_exp2(exp10) + FPBits::STORAGE_LEN + FPBits::EXP_BIAS - | |
| 115 | static_cast<int32_t>(clz); | |
| 116 | 116 | |
| 117 | 117 | // Multiplication |
| 118 | 118 | const uint64_t *power_of_ten = |
| ... | ... | @@ -225,8 +225,8 @@ eisel_lemire<long double>(ExpandedFloat<long double> init_num, |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | 227 | // Normalization |
| 228 | uint32_t clz = cpp::countl_zero(mantissa) - | |
| 229 | ((sizeof(UInt128) - sizeof(StorageType)) * CHAR_BIT); | |
| 228 | int32_t clz = static_cast<int32_t>(cpp::countl_zero(mantissa)) - | |
| 229 | ((sizeof(UInt128) - sizeof(StorageType)) * CHAR_BIT); | |
| 230 | 230 | mantissa <<= clz; |
| 231 | 231 | |
| 232 | 232 | int32_t exp2 = |
| ... | ... | @@ -802,7 +802,7 @@ LIBC_INLINE FloatConvertReturn<T> binary_exp_to_float(ExpandedFloat<T> init_num, |
| 802 | 802 | |
| 803 | 803 | // Handle subnormals. |
| 804 | 804 | if (biased_exponent <= 0) { |
| 805 | amount_to_shift_right += 1 - biased_exponent; | |
| 805 | amount_to_shift_right += static_cast<uint32_t>(1 - biased_exponent); | |
| 806 | 806 | biased_exponent = 0; |
| 807 | 807 | |
| 808 | 808 | if (amount_to_shift_right > FPBits::STORAGE_LEN) { |
| ... | ... | @@ -909,7 +909,7 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT, |
| 909 | 909 | cpp::numeric_limits<StorageType>::max() / BASE; |
| 910 | 910 | while (true) { |
| 911 | 911 | if (isdigit(src[index])) { |
| 912 | uint32_t digit = b36_char_to_int(src[index]); | |
| 912 | uint32_t digit = static_cast<uint32_t>(b36_char_to_int(src[index])); | |
| 913 | 913 | seen_digit = true; |
| 914 | 914 | |
| 915 | 915 | if (mantissa < bitstype_max_div_by_base) { |
| ... | ... | @@ -956,7 +956,7 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT, |
| 956 | 956 | if (result.has_error()) |
| 957 | 957 | output.error = result.error; |
| 958 | 958 | int32_t add_to_exponent = result.value; |
| 959 | index += result.parsed_len; | |
| 959 | index += static_cast<size_t>(result.parsed_len); | |
| 960 | 960 | |
| 961 | 961 | // Here we do this operation as int64 to avoid overflow. |
| 962 | 962 | int64_t temp_exponent = static_cast<int64_t>(exponent) + |
| ... | ... | @@ -1020,7 +1020,7 @@ hexadecimal_string_to_float(const char *__restrict src, |
| 1020 | 1020 | cpp::numeric_limits<StorageType>::max() / BASE; |
| 1021 | 1021 | while (true) { |
| 1022 | 1022 | if (isalnum(src[index])) { |
| 1023 | uint32_t digit = b36_char_to_int(src[index]); | |
| 1023 | uint32_t digit = static_cast<uint32_t>(b36_char_to_int(src[index])); | |
| 1024 | 1024 | if (digit < BASE) |
| 1025 | 1025 | seen_digit = true; |
| 1026 | 1026 | else |
| ... | ... | @@ -1070,7 +1070,7 @@ hexadecimal_string_to_float(const char *__restrict src, |
| 1070 | 1070 | output.error = result.error; |
| 1071 | 1071 | |
| 1072 | 1072 | int32_t add_to_exponent = result.value; |
| 1073 | index += result.parsed_len; | |
| 1073 | index += static_cast<size_t>(result.parsed_len); | |
| 1074 | 1074 | |
| 1075 | 1075 | // Here we do this operation as int64 to avoid overflow. |
| 1076 | 1076 | int64_t temp_exponent = static_cast<int64_t>(exponent) + |
| ... | ... | @@ -1135,7 +1135,7 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) { |
| 1135 | 1135 | |
| 1136 | 1136 | int error = 0; |
| 1137 | 1137 | |
| 1138 | ptrdiff_t index = first_non_whitespace(src) - src; | |
| 1138 | size_t index = first_non_whitespace(src); | |
| 1139 | 1139 | |
| 1140 | 1140 | if (src[index] == '+' || src[index] == '-') { |
| 1141 | 1141 | sign = src[index]; |
| ... | ... | @@ -1245,7 +1245,7 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) { |
| 1245 | 1245 | // special 80 bit long doubles. Otherwise it should be inlined out. |
| 1246 | 1246 | set_implicit_bit<T>(result); |
| 1247 | 1247 | |
| 1248 | return {result.get_val(), index, error}; | |
| 1248 | return {result.get_val(), static_cast<ptrdiff_t>(index), error}; | |
| 1249 | 1249 | } |
| 1250 | 1250 | |
| 1251 | 1251 | template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) { |
lib/libcxx/libc/src/__support/str_to_integer.h+10-11| ... | ... | @@ -15,6 +15,7 @@ |
| 15 | 15 | #ifndef LLVM_LIBC_SRC___SUPPORT_STR_TO_INTEGER_H |
| 16 | 16 | #define LLVM_LIBC_SRC___SUPPORT_STR_TO_INTEGER_H |
| 17 | 17 | |
| 18 | #include "hdr/errno_macros.h" // For ERANGE | |
| 18 | 19 | #include "src/__support/CPP/limits.h" |
| 19 | 20 | #include "src/__support/CPP/type_traits.h" |
| 20 | 21 | #include "src/__support/CPP/type_traits/make_unsigned.h" |
| ... | ... | @@ -24,22 +25,20 @@ |
| 24 | 25 | #include "src/__support/macros/config.h" |
| 25 | 26 | #include "src/__support/str_to_num_result.h" |
| 26 | 27 | #include "src/__support/uint128.h" |
| 27 | #include "src/errno/libc_errno.h" // For ERANGE | |
| 28 | 28 | |
| 29 | 29 | namespace LIBC_NAMESPACE_DECL { |
| 30 | 30 | namespace internal { |
| 31 | 31 | |
| 32 | // Returns a pointer to the first character in src that is not a whitespace | |
| 32 | // Returns the idx to the first character in src that is not a whitespace | |
| 33 | 33 | // character (as determined by isspace()) |
| 34 | // TODO: Change from returning a pointer to returning a length. | |
| 35 | LIBC_INLINE const char * | |
| 34 | LIBC_INLINE size_t | |
| 36 | 35 | first_non_whitespace(const char *__restrict src, |
| 37 | 36 | size_t src_len = cpp::numeric_limits<size_t>::max()) { |
| 38 | 37 | size_t src_cur = 0; |
| 39 | 38 | while (src_cur < src_len && internal::isspace(src[src_cur])) { |
| 40 | 39 | ++src_cur; |
| 41 | 40 | } |
| 42 | return src + src_cur; | |
| 41 | return src_cur; | |
| 43 | 42 | } |
| 44 | 43 | |
| 45 | 44 | // checks if the next 3 characters of the string pointer are the start of a |
| ... | ... | @@ -96,7 +95,7 @@ strtointeger(const char *__restrict src, int base, |
| 96 | 95 | if (base < 0 || base == 1 || base > 36) |
| 97 | 96 | return {0, 0, EINVAL}; |
| 98 | 97 | |
| 99 | src_cur = first_non_whitespace(src, src_len) - src; | |
| 98 | src_cur = first_non_whitespace(src, src_len); | |
| 100 | 99 | |
| 101 | 100 | char result_sign = '+'; |
| 102 | 101 | if (src[src_cur] == '+' || src[src_cur] == '-') { |
| ... | ... | @@ -119,7 +118,7 @@ strtointeger(const char *__restrict src, int base, |
| 119 | 118 | ResultType const abs_max = |
| 120 | 119 | (is_positive ? cpp::numeric_limits<T>::max() : NEGATIVE_MAX); |
| 121 | 120 | ResultType const abs_max_div_by_base = |
| 122 | static_cast<ResultType>(abs_max / base); | |
| 121 | abs_max / static_cast<ResultType>(base); | |
| 123 | 122 | |
| 124 | 123 | while (src_cur < src_len && isalnum(src[src_cur])) { |
| 125 | 124 | int cur_digit = b36_char_to_int(src[src_cur]); |
| ... | ... | @@ -141,17 +140,17 @@ strtointeger(const char *__restrict src, int base, |
| 141 | 140 | result = abs_max; |
| 142 | 141 | error_val = ERANGE; |
| 143 | 142 | } else { |
| 144 | result = static_cast<ResultType>(result * base); | |
| 143 | result = result * static_cast<ResultType>(base); | |
| 145 | 144 | } |
| 146 | if (result > abs_max - cur_digit) { | |
| 145 | if (result > abs_max - static_cast<ResultType>(cur_digit)) { | |
| 147 | 146 | result = abs_max; |
| 148 | 147 | error_val = ERANGE; |
| 149 | 148 | } else { |
| 150 | result = static_cast<ResultType>(result + cur_digit); | |
| 149 | result = result + static_cast<ResultType>(cur_digit); | |
| 151 | 150 | } |
| 152 | 151 | } |
| 153 | 152 | |
| 154 | ptrdiff_t str_len = is_number ? (src_cur) : 0; | |
| 153 | ptrdiff_t str_len = is_number ? static_cast<ptrdiff_t>(src_cur) : 0; | |
| 155 | 154 | |
| 156 | 155 | if (error_val == ERANGE) { |
| 157 | 156 | if (is_positive || IS_UNSIGNED) |
lib/libcxx/libc/src/errno/libc_errno.h deleted-47| ... | ... | @@ -1,47 +0,0 @@ |
| 1 | //===-- Implementation header for libc_errno --------------------*- C++ -*-===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef LLVM_LIBC_SRC_ERRNO_LIBC_ERRNO_H | |
| 10 | #define LLVM_LIBC_SRC_ERRNO_LIBC_ERRNO_H | |
| 11 | ||
| 12 | #include "src/__support/macros/attributes.h" | |
| 13 | #include "src/__support/macros/config.h" | |
| 14 | #include "src/__support/macros/properties/architectures.h" | |
| 15 | ||
| 16 | #include "hdr/errno_macros.h" | |
| 17 | ||
| 18 | // This header is to be consumed by internal implementations, in which all of | |
| 19 | // them should refer to `libc_errno` instead of using `errno` directly from | |
| 20 | // <errno.h> header. | |
| 21 | ||
| 22 | // Unit and hermetic tests should: | |
| 23 | // - #include "src/errno/libc_errno.h" | |
| 24 | // - NOT #include <errno.h> | |
| 25 | // - Only use `libc_errno` in the code | |
| 26 | // - Depend on libc.src.errno.errno | |
| 27 | ||
| 28 | // Integration tests should: | |
| 29 | // - NOT #include "src/errno/libc_errno.h" | |
| 30 | // - #include <errno.h> | |
| 31 | // - Use regular `errno` in the code | |
| 32 | // - Still depend on libc.src.errno.errno | |
| 33 | ||
| 34 | namespace LIBC_NAMESPACE_DECL { | |
| 35 | ||
| 36 | extern "C" int *__llvm_libc_errno() noexcept; | |
| 37 | ||
| 38 | struct Errno { | |
| 39 | void operator=(int); | |
| 40 | operator int(); | |
| 41 | }; | |
| 42 | ||
| 43 | extern Errno libc_errno; | |
| 44 | ||
| 45 | } // namespace LIBC_NAMESPACE_DECL | |
| 46 | ||
| 47 | #endif // LLVM_LIBC_SRC_ERRNO_LIBC_ERRNO_H |