mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
llvm-libc: update to LLVM 21
Still only the subset needed for libcxx.
This commit is contained in:
parent
d9f0fbf983
commit
c34fc8f198
24 changed files with 313 additions and 130 deletions
|
|
@ -323,6 +323,45 @@
|
|||
#define ULACCUM_EPSILON 0x1.0p-32ULK
|
||||
#endif // ULACCUM_EPSILON
|
||||
|
||||
#define absfx(x) \
|
||||
_Generic((x), \
|
||||
fract: absr, \
|
||||
short fract: abshr, \
|
||||
long fract: abslr, \
|
||||
accum: absk, \
|
||||
short accum: abshk, \
|
||||
long accum: abslk)(x)
|
||||
|
||||
#define countlsfx(x) \
|
||||
_Generic((x), \
|
||||
fract: countlsr, \
|
||||
short fract: countlshr, \
|
||||
long fract: countlslr, \
|
||||
accum: countlsk, \
|
||||
short accum: countlshk, \
|
||||
long accum: countlslk, \
|
||||
unsigned fract: countlsur, \
|
||||
unsigned short fract: countlsuhr, \
|
||||
unsigned long fract: countlsulr, \
|
||||
unsigned accum: countlsuk, \
|
||||
unsigned short accum: countlsuhk, \
|
||||
unsigned long accum: countlsulk)(x)
|
||||
|
||||
#define roundfx(x, y) \
|
||||
_Generic((x), \
|
||||
fract: roundr, \
|
||||
short fract: roundhr, \
|
||||
long fract: roundlr, \
|
||||
accum: roundk, \
|
||||
short accum: roundhk, \
|
||||
long accum: roundlk, \
|
||||
unsigned fract: roundur, \
|
||||
unsigned short fract: rounduhr, \
|
||||
unsigned long fract: roundulr, \
|
||||
unsigned accum: rounduk, \
|
||||
unsigned short accum: rounduhk, \
|
||||
unsigned long accum: roundulk)(x, y)
|
||||
|
||||
#endif // LIBC_COMPILER_HAS_FIXED_POINT
|
||||
|
||||
#endif // LLVM_LIBC_MACROS_STDFIX_MACROS_H
|
||||
|
|
|
|||
1
lib/libcxx/libc/shared/fp_bits.h
vendored
1
lib/libcxx/libc/shared/fp_bits.h
vendored
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef LLVM_LIBC_SHARED_FP_BITS_H
|
||||
#define LLVM_LIBC_SHARED_FP_BITS_H
|
||||
|
||||
#include "libc_common.h"
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
|
|
|||
26
lib/libcxx/libc/shared/libc_common.h
vendored
Normal file
26
lib/libcxx/libc/shared/libc_common.h
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//===-- Common defines for sharing LLVM libc with LLVM projects -*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SHARED_LIBC_COMMON_H
|
||||
#define LLVM_LIBC_SHARED_LIBC_COMMON_H
|
||||
|
||||
// Use system errno.
|
||||
#ifdef LIBC_ERRNO_MODE
|
||||
#if LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM_INLINE
|
||||
#error \
|
||||
"LIBC_ERRNO_MODE was set to something different from LIBC_ERRNO_MODE_SYSTEM_INLINE."
|
||||
#endif // LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM_INLINE
|
||||
#else
|
||||
#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM_INLINE
|
||||
#endif // LIBC_ERRNO_MODE
|
||||
|
||||
#ifndef LIBC_NAMESPACE
|
||||
#define LIBC_NAMESPACE __llvm_libc
|
||||
#endif // LIBC_NAMESPACE
|
||||
|
||||
#endif // LLVM_LIBC_SHARED_LIBC_COMMON_H
|
||||
1
lib/libcxx/libc/shared/str_to_float.h
vendored
1
lib/libcxx/libc/shared/str_to_float.h
vendored
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef LLVM_LIBC_SHARED_STR_TO_FLOAT_H
|
||||
#define LLVM_LIBC_SHARED_STR_TO_FLOAT_H
|
||||
|
||||
#include "libc_common.h"
|
||||
#include "src/__support/str_to_float.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
|
|
|||
1
lib/libcxx/libc/shared/str_to_integer.h
vendored
1
lib/libcxx/libc/shared/str_to_integer.h
vendored
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef LLVM_LIBC_SHARED_STR_TO_INTEGER_H
|
||||
#define LLVM_LIBC_SHARED_STR_TO_INTEGER_H
|
||||
|
||||
#include "libc_common.h"
|
||||
#include "src/__support/str_to_integer.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
|
|
|||
16
lib/libcxx/libc/src/__support/CPP/bit.h
vendored
16
lib/libcxx/libc/src/__support/CPP/bit.h
vendored
|
|
@ -101,7 +101,7 @@ countr_zero(T value) {
|
|||
shift >>= 1;
|
||||
mask >>= shift;
|
||||
}
|
||||
return zero_bits;
|
||||
return static_cast<int>(zero_bits);
|
||||
}
|
||||
#if __has_builtin(__builtin_ctzs)
|
||||
ADD_SPECIALIZATION(countr_zero, unsigned short, __builtin_ctzs)
|
||||
|
|
@ -140,7 +140,7 @@ countl_zero(T value) {
|
|||
else
|
||||
zero_bits |= shift;
|
||||
}
|
||||
return zero_bits;
|
||||
return static_cast<int>(zero_bits);
|
||||
}
|
||||
#if __has_builtin(__builtin_clzs)
|
||||
ADD_SPECIALIZATION(countl_zero, unsigned short, __builtin_clzs)
|
||||
|
|
@ -162,7 +162,7 @@ ADD_SPECIALIZATION(countl_zero, unsigned long long, __builtin_clzll)
|
|||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
|
||||
countl_one(T value) {
|
||||
return cpp::countl_zero<T>(~value);
|
||||
return cpp::countl_zero<T>(static_cast<T>(~value));
|
||||
}
|
||||
|
||||
/// Count the number of ones from the least significant bit to the first
|
||||
|
|
@ -175,7 +175,7 @@ countl_one(T value) {
|
|||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
|
||||
countr_one(T value) {
|
||||
return cpp::countr_zero<T>(~value);
|
||||
return cpp::countr_zero<T>(static_cast<T>(~value));
|
||||
}
|
||||
|
||||
/// Returns the number of bits needed to represent value if value is nonzero.
|
||||
|
|
@ -226,25 +226,25 @@ rotr(T value, int rotate);
|
|||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
|
||||
rotl(T value, int rotate) {
|
||||
constexpr unsigned N = cpp::numeric_limits<T>::digits;
|
||||
constexpr int N = cpp::numeric_limits<T>::digits;
|
||||
rotate = rotate % N;
|
||||
if (!rotate)
|
||||
return value;
|
||||
if (rotate < 0)
|
||||
return cpp::rotr<T>(value, -rotate);
|
||||
return (value << rotate) | (value >> (N - rotate));
|
||||
return static_cast<T>((value << rotate) | (value >> (N - rotate)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
|
||||
rotr(T value, int rotate) {
|
||||
constexpr unsigned N = cpp::numeric_limits<T>::digits;
|
||||
constexpr int N = cpp::numeric_limits<T>::digits;
|
||||
rotate = rotate % N;
|
||||
if (!rotate)
|
||||
return value;
|
||||
if (rotate < 0)
|
||||
return cpp::rotl<T>(value, -rotate);
|
||||
return (value >> rotate) | (value << (N - rotate));
|
||||
return static_cast<T>((value >> rotate) | (value << (N - rotate)));
|
||||
}
|
||||
|
||||
// TODO: Do we need this function at all? How is it different from
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_STRING_VIEW_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_CPP_STRING_VIEW_H
|
||||
|
||||
#include "limits.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ private:
|
|||
LIBC_INLINE static constexpr size_t length(const char *Str) {
|
||||
for (const char *End = Str;; ++End)
|
||||
if (*End == '\0')
|
||||
return End - Str;
|
||||
return static_cast<size_t>(End - Str);
|
||||
}
|
||||
|
||||
LIBC_INLINE bool equals(string_view Other) const {
|
||||
|
|
@ -61,7 +62,8 @@ public:
|
|||
|
||||
// special value equal to the maximum value representable by the type
|
||||
// size_type.
|
||||
LIBC_INLINE_VAR static constexpr size_t npos = -1;
|
||||
LIBC_INLINE_VAR static constexpr size_t npos =
|
||||
cpp::numeric_limits<size_t>::max();
|
||||
|
||||
LIBC_INLINE constexpr string_view() : Data(nullptr), Len(0) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ public:
|
|||
,
|
||||
float128
|
||||
#endif
|
||||
>();
|
||||
,
|
||||
bfloat16>();
|
||||
};
|
||||
template <typename T>
|
||||
LIBC_INLINE_VAR constexpr bool is_floating_point_v =
|
||||
|
|
|
|||
|
|
@ -8,20 +8,43 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_SIGNED_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_SIGNED_H
|
||||
|
||||
#include "include/llvm-libc-macros/stdfix-macros.h"
|
||||
#include "src/__support/CPP/type_traits/bool_constant.h"
|
||||
#include "src/__support/CPP/type_traits/is_arithmetic.h"
|
||||
#include "src/__support/CPP/type_traits/is_same.h"
|
||||
#include "src/__support/CPP/type_traits/remove_cv.h"
|
||||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace cpp {
|
||||
|
||||
// is_signed
|
||||
#ifndef LIBC_COMPILER_HAS_FIXED_POINT
|
||||
template <typename T>
|
||||
struct is_signed : bool_constant<(is_arithmetic_v<T> && (T(-1) < T(0)))> {
|
||||
LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
|
||||
LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
|
||||
};
|
||||
#else
|
||||
template <typename T> struct is_signed {
|
||||
private:
|
||||
template <typename Head, typename... Args>
|
||||
LIBC_INLINE static constexpr bool __is_unqualified_any_of() {
|
||||
return (... || is_same_v<remove_cv_t<Head>, Args>);
|
||||
}
|
||||
|
||||
public:
|
||||
LIBC_INLINE_VAR static constexpr bool value =
|
||||
(is_arithmetic_v<T> && (T(-1) < T(0))) ||
|
||||
__is_unqualified_any_of<T, short fract, fract, long fract, short accum,
|
||||
accum, long accum, short sat fract, sat fract,
|
||||
long sat fract, short sat accum, sat accum,
|
||||
long sat accum>();
|
||||
LIBC_INLINE constexpr operator bool() const { return is_signed::value; }
|
||||
LIBC_INLINE constexpr bool operator()() const { return is_signed::value; }
|
||||
};
|
||||
#endif // LIBC_COMPILER_HAS_FIXED_POINT
|
||||
|
||||
template <typename T>
|
||||
LIBC_INLINE_VAR constexpr bool is_signed_v = is_signed<T>::value;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,20 +8,45 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_UNSIGNED_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_UNSIGNED_H
|
||||
|
||||
#include "include/llvm-libc-macros/stdfix-macros.h"
|
||||
#include "src/__support/CPP/type_traits/bool_constant.h"
|
||||
#include "src/__support/CPP/type_traits/is_arithmetic.h"
|
||||
#include "src/__support/CPP/type_traits/is_same.h"
|
||||
#include "src/__support/CPP/type_traits/remove_cv.h"
|
||||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace cpp {
|
||||
|
||||
// is_unsigned
|
||||
#ifndef LIBC_COMPILER_HAS_FIXED_POINT
|
||||
template <typename T>
|
||||
struct is_unsigned : bool_constant<(is_arithmetic_v<T> && (T(-1) > T(0)))> {
|
||||
LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
|
||||
LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
|
||||
};
|
||||
#else
|
||||
template <typename T> struct is_unsigned {
|
||||
private:
|
||||
template <typename Head, typename... Args>
|
||||
LIBC_INLINE static constexpr bool __is_unqualified_any_of() {
|
||||
return (... || is_same_v<remove_cv_t<Head>, Args>);
|
||||
}
|
||||
|
||||
public:
|
||||
LIBC_INLINE_VAR static constexpr bool value =
|
||||
(is_arithmetic_v<T> && (T(-1) > T(0))) ||
|
||||
__is_unqualified_any_of<T, unsigned short fract, unsigned fract,
|
||||
unsigned long fract, unsigned short accum,
|
||||
unsigned accum, unsigned long accum,
|
||||
unsigned short sat fract, unsigned sat fract,
|
||||
unsigned long sat fract, unsigned short sat accum,
|
||||
unsigned sat accum, unsigned long sat accum>();
|
||||
LIBC_INLINE constexpr operator bool() const { return is_unsigned::value; }
|
||||
LIBC_INLINE constexpr bool operator()() const { return is_unsigned::value; }
|
||||
};
|
||||
#endif // LIBC_COMPILER_HAS_FIXED_POINT
|
||||
|
||||
template <typename T>
|
||||
LIBC_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned<T>::value;
|
||||
|
||||
|
|
|
|||
19
lib/libcxx/libc/src/__support/FPUtil/FPBits.h
vendored
19
lib/libcxx/libc/src/__support/FPUtil/FPBits.h
vendored
|
|
@ -38,6 +38,7 @@ enum class FPType {
|
|||
IEEE754_Binary64,
|
||||
IEEE754_Binary128,
|
||||
X86_Binary80,
|
||||
BFloat16
|
||||
};
|
||||
|
||||
// The classes hierarchy is as follows:
|
||||
|
|
@ -138,6 +139,14 @@ template <> struct FPLayout<FPType::X86_Binary80> {
|
|||
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN - 1;
|
||||
};
|
||||
|
||||
template <> struct FPLayout<FPType::BFloat16> {
|
||||
using StorageType = uint16_t;
|
||||
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
|
||||
LIBC_INLINE_VAR static constexpr int EXP_LEN = 8;
|
||||
LIBC_INLINE_VAR static constexpr int SIG_LEN = 7;
|
||||
LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN;
|
||||
};
|
||||
|
||||
// FPStorage derives useful constants from the FPLayout above.
|
||||
template <FPType fp_type> struct FPStorage : public FPLayout<fp_type> {
|
||||
using UP = FPLayout<fp_type>;
|
||||
|
|
@ -247,11 +256,11 @@ protected:
|
|||
using UP::UP;
|
||||
|
||||
LIBC_INLINE constexpr BiasedExponent(Exponent exp)
|
||||
: UP(static_cast<int32_t>(exp) + EXP_BIAS) {}
|
||||
: UP(static_cast<uint32_t>(static_cast<int32_t>(exp) + EXP_BIAS)) {}
|
||||
|
||||
// Cast operator to get convert from BiasedExponent to Exponent.
|
||||
LIBC_INLINE constexpr operator Exponent() const {
|
||||
return Exponent(UP::value - EXP_BIAS);
|
||||
return Exponent(static_cast<int32_t>(UP::value - EXP_BIAS));
|
||||
}
|
||||
|
||||
LIBC_INLINE constexpr BiasedExponent &operator++() {
|
||||
|
|
@ -686,7 +695,7 @@ public:
|
|||
}
|
||||
|
||||
LIBC_INLINE constexpr void set_biased_exponent(StorageType biased) {
|
||||
UP::set_biased_exponent(BiasedExponent((int32_t)biased));
|
||||
UP::set_biased_exponent(BiasedExponent(static_cast<uint32_t>(biased)));
|
||||
}
|
||||
|
||||
LIBC_INLINE constexpr int get_exponent() const {
|
||||
|
|
@ -757,7 +766,7 @@ public:
|
|||
result.set_significand(number);
|
||||
result.set_biased_exponent(static_cast<StorageType>(ep + 1));
|
||||
} else {
|
||||
result.set_significand(number >> -ep);
|
||||
result.set_significand(number >> static_cast<unsigned>(-ep));
|
||||
}
|
||||
return RetT(result.uintval());
|
||||
}
|
||||
|
|
@ -801,6 +810,8 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
|
|||
else if constexpr (cpp::is_same_v<UnqualT, float128>)
|
||||
return FPType::IEEE754_Binary128;
|
||||
#endif
|
||||
else if constexpr (cpp::is_same_v<UnqualT, bfloat16>)
|
||||
return FPType::BFloat16;
|
||||
else
|
||||
static_assert(cpp::always_false<UnqualT>, "Unsupported type");
|
||||
}
|
||||
|
|
|
|||
59
lib/libcxx/libc/src/__support/big_int.h
vendored
59
lib/libcxx/libc/src/__support/big_int.h
vendored
|
|
@ -241,7 +241,7 @@ LIBC_INLINE constexpr void quick_mul_hi(cpp::array<word, N> &dst,
|
|||
}
|
||||
|
||||
template <typename word, size_t N>
|
||||
LIBC_INLINE constexpr bool is_negative(cpp::array<word, N> &array) {
|
||||
LIBC_INLINE constexpr bool is_negative(const cpp::array<word, N> &array) {
|
||||
using signed_word = cpp::make_signed_t<word>;
|
||||
return cpp::bit_cast<signed_word>(array.back()) < 0;
|
||||
}
|
||||
|
|
@ -284,8 +284,8 @@ LIBC_INLINE constexpr cpp::array<word, N> shift(cpp::array<word, N> array,
|
|||
if (i < 0)
|
||||
return 0;
|
||||
if (i >= int(N))
|
||||
return is_neg ? -1 : 0;
|
||||
return array[i];
|
||||
return is_neg ? cpp::numeric_limits<word>::max() : 0;
|
||||
return array[static_cast<unsigned>(i)];
|
||||
};
|
||||
const size_t index_offset = offset / WORD_BITS;
|
||||
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,
|
|||
for (size_t index = 0; index < N; ++index) {
|
||||
const word part1 = safe_get_at(index + index_offset);
|
||||
const word part2 = safe_get_at(index + index_offset + 1);
|
||||
word &dst = out[at(index)];
|
||||
word &dst = out[static_cast<unsigned>(at(index))];
|
||||
if (bit_offset == 0)
|
||||
dst = part1; // no crosstalk between parts.
|
||||
else if constexpr (direction == LEFT)
|
||||
|
|
@ -465,8 +465,7 @@ public:
|
|||
}
|
||||
|
||||
// Initialize the first word to |v| and the rest to 0.
|
||||
template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T> &&
|
||||
!cpp::is_same_v<T, bool>>>
|
||||
template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T>>>
|
||||
LIBC_INLINE constexpr BigInt(T v) {
|
||||
constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT;
|
||||
const bool is_neg = v < 0;
|
||||
|
|
@ -697,7 +696,8 @@ public:
|
|||
}
|
||||
BigInt quotient;
|
||||
WordType x_word = static_cast<WordType>(x);
|
||||
constexpr size_t LOG2_WORD_SIZE = cpp::bit_width(WORD_SIZE) - 1;
|
||||
constexpr size_t LOG2_WORD_SIZE =
|
||||
static_cast<size_t>(cpp::bit_width(WORD_SIZE) - 1);
|
||||
constexpr size_t HALF_WORD_SIZE = WORD_SIZE >> 1;
|
||||
constexpr WordType HALF_MASK = ((WordType(1) << HALF_WORD_SIZE) - 1);
|
||||
// lower = smallest multiple of WORD_SIZE that is >= e.
|
||||
|
|
@ -866,7 +866,7 @@ public:
|
|||
LIBC_INLINE constexpr BigInt operator~() const {
|
||||
BigInt result;
|
||||
for (size_t i = 0; i < WORD_COUNT; ++i)
|
||||
result[i] = ~val[i];
|
||||
result[i] = static_cast<WordType>(~val[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -936,6 +936,18 @@ public:
|
|||
// Return the i-th word of the number.
|
||||
LIBC_INLINE constexpr WordType &operator[](size_t i) { return val[i]; }
|
||||
|
||||
// Return the i-th bit of the number.
|
||||
LIBC_INLINE constexpr bool get_bit(size_t i) const {
|
||||
const size_t word_index = i / WORD_SIZE;
|
||||
return 1 & (val[word_index] >> (i % WORD_SIZE));
|
||||
}
|
||||
|
||||
// Set the i-th bit of the number.
|
||||
LIBC_INLINE constexpr void set_bit(size_t i) {
|
||||
const size_t word_index = i / WORD_SIZE;
|
||||
val[word_index] |= WordType(1) << (i % WORD_SIZE);
|
||||
}
|
||||
|
||||
private:
|
||||
LIBC_INLINE friend constexpr int cmp(const BigInt &lhs, const BigInt &rhs) {
|
||||
constexpr auto compare = [](WordType a, WordType b) {
|
||||
|
|
@ -955,7 +967,7 @@ private:
|
|||
|
||||
LIBC_INLINE constexpr void bitwise_not() {
|
||||
for (auto &part : val)
|
||||
part = ~part;
|
||||
part = static_cast<WordType>(~part);
|
||||
}
|
||||
|
||||
LIBC_INLINE constexpr void negate() {
|
||||
|
|
@ -968,7 +980,7 @@ private:
|
|||
}
|
||||
|
||||
LIBC_INLINE constexpr void decrement() {
|
||||
multiword::add_with_carry(val, cpp::array<WordType, 1>{1});
|
||||
multiword::sub_with_borrow(val, cpp::array<WordType, 1>{1});
|
||||
}
|
||||
|
||||
LIBC_INLINE constexpr void extend(size_t index, bool is_neg) {
|
||||
|
|
@ -989,12 +1001,6 @@ private:
|
|||
LIBC_INLINE constexpr void clear_msb() {
|
||||
val.back() &= mask_trailing_ones<WordType, WORD_SIZE - 1>();
|
||||
}
|
||||
|
||||
LIBC_INLINE constexpr void set_bit(size_t i) {
|
||||
const size_t word_index = i / WORD_SIZE;
|
||||
val[word_index] |= WordType(1) << (i % WORD_SIZE);
|
||||
}
|
||||
|
||||
LIBC_INLINE constexpr static Division divide_unsigned(const BigInt ÷nd,
|
||||
const BigInt ÷r) {
|
||||
BigInt remainder = dividend;
|
||||
|
|
@ -1003,12 +1009,12 @@ private:
|
|||
BigInt subtractor = divider;
|
||||
int cur_bit = multiword::countl_zero(subtractor.val) -
|
||||
multiword::countl_zero(remainder.val);
|
||||
subtractor <<= cur_bit;
|
||||
subtractor <<= static_cast<size_t>(cur_bit);
|
||||
for (; cur_bit >= 0 && remainder > 0; --cur_bit, subtractor >>= 1) {
|
||||
if (remainder < subtractor)
|
||||
continue;
|
||||
remainder -= subtractor;
|
||||
quotient.set_bit(cur_bit);
|
||||
quotient.set_bit(static_cast<size_t>(cur_bit));
|
||||
}
|
||||
}
|
||||
return Division{quotient, remainder};
|
||||
|
|
@ -1270,26 +1276,28 @@ rotr(T value, int rotate);
|
|||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
|
||||
rotl(T value, int rotate) {
|
||||
constexpr unsigned N = cpp::numeric_limits<T>::digits;
|
||||
constexpr int N = cpp::numeric_limits<T>::digits;
|
||||
rotate = rotate % N;
|
||||
if (!rotate)
|
||||
return value;
|
||||
if (rotate < 0)
|
||||
return cpp::rotr<T>(value, -rotate);
|
||||
return (value << rotate) | (value >> (N - rotate));
|
||||
return (value << static_cast<size_t>(rotate)) |
|
||||
(value >> (N - static_cast<size_t>(rotate)));
|
||||
}
|
||||
|
||||
// Specialization of cpp::rotr ('bit.h') for BigInt.
|
||||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T>
|
||||
rotr(T value, int rotate) {
|
||||
constexpr unsigned N = cpp::numeric_limits<T>::digits;
|
||||
constexpr int N = cpp::numeric_limits<T>::digits;
|
||||
rotate = rotate % N;
|
||||
if (!rotate)
|
||||
return value;
|
||||
if (rotate < 0)
|
||||
return cpp::rotl<T>(value, -rotate);
|
||||
return (value >> rotate) | (value << (N - rotate));
|
||||
return (value >> static_cast<size_t>(rotate)) |
|
||||
(value << (N - static_cast<size_t>(rotate)));
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
|
|
@ -1306,7 +1314,7 @@ mask_trailing_ones() {
|
|||
T out; // zero initialized
|
||||
for (size_t i = 0; i <= QUOTIENT; ++i)
|
||||
out[i] = i < QUOTIENT
|
||||
? -1
|
||||
? cpp::numeric_limits<typename T::word_type>::max()
|
||||
: mask_trailing_ones<typename T::word_type, REMAINDER>();
|
||||
return out;
|
||||
}
|
||||
|
|
@ -1322,7 +1330,7 @@ LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, T> mask_leading_ones() {
|
|||
T out; // zero initialized
|
||||
for (size_t i = QUOTIENT; i < T::WORD_COUNT; ++i)
|
||||
out[i] = i > QUOTIENT
|
||||
? -1
|
||||
? cpp::numeric_limits<typename T::word_type>::max()
|
||||
: mask_leading_ones<typename T::word_type, REMAINDER>();
|
||||
return out;
|
||||
}
|
||||
|
|
@ -1375,8 +1383,7 @@ first_trailing_zero(T value) {
|
|||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
|
||||
first_trailing_one(T value) {
|
||||
return value == cpp::numeric_limits<T>::max() ? 0
|
||||
: cpp::countr_zero(value) + 1;
|
||||
return value == 0 ? 0 : cpp::countr_zero(value) + 1;
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
|
|
|||
18
lib/libcxx/libc/src/__support/common.h
vendored
18
lib/libcxx/libc/src/__support/common.h
vendored
|
|
@ -37,17 +37,27 @@
|
|||
|
||||
#define LLVM_LIBC_ATTR(name) EXPAND_THEN_SECOND(LLVM_LIBC_FUNCTION_ATTR_##name)
|
||||
|
||||
// MacOS needs to be excluded because it does not support aliasing.
|
||||
#if defined(LIBC_COPT_PUBLIC_PACKAGING) && (!defined(__APPLE__))
|
||||
// At the moment, [[gnu::alias()]] is not supported on MacOS, and it is needed
|
||||
// to cleanly export and alias the C++ symbol `LIBC_NAMESPACE::func` with the C
|
||||
// symbol `func`. So for public packaging on MacOS, we will only export the C
|
||||
// symbol. Moreover, a C symbol `func` in macOS is mangled as `_func`.
|
||||
#if defined(LIBC_COPT_PUBLIC_PACKAGING)
|
||||
#ifndef __APPLE__
|
||||
#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \
|
||||
LLVM_LIBC_ATTR(name) \
|
||||
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \
|
||||
__##name##_impl__ __asm__(#name); \
|
||||
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]]; \
|
||||
type __##name##_impl__ arglist
|
||||
#else
|
||||
#else // __APPLE__
|
||||
#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \
|
||||
LLVM_LIBC_ATTR(name) \
|
||||
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) name asm("_" #name); \
|
||||
type name arglist
|
||||
#endif // __APPLE__
|
||||
#else // LIBC_COPT_PUBLIC_PACKAGING
|
||||
#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) type name arglist
|
||||
#endif
|
||||
#endif // LIBC_COPT_PUBLIC_PACKAGING
|
||||
|
||||
// This extra layer of macro allows `name` to be a macro to rename a function.
|
||||
#define LLVM_LIBC_FUNCTION(type, name, arglist) \
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ private:
|
|||
LIBC_INLINE void left_shift(uint32_t shift_amount) {
|
||||
uint32_t new_digits = this->get_num_new_digits(shift_amount);
|
||||
|
||||
int32_t read_index = this->num_digits - 1;
|
||||
int32_t read_index = static_cast<int32_t>(this->num_digits - 1);
|
||||
uint32_t write_index = this->num_digits + new_digits;
|
||||
|
||||
uint64_t accumulator = 0;
|
||||
|
|
@ -329,7 +329,7 @@ public:
|
|||
if (saw_dot) {
|
||||
break;
|
||||
}
|
||||
this->decimal_point = total_digits;
|
||||
this->decimal_point = static_cast<int32_t>(total_digits);
|
||||
saw_dot = true;
|
||||
} else {
|
||||
if (num_string[num_cur] == '0' && this->num_digits == 0) {
|
||||
|
|
@ -350,7 +350,7 @@ public:
|
|||
}
|
||||
|
||||
if (!saw_dot)
|
||||
this->decimal_point = total_digits;
|
||||
this->decimal_point = static_cast<int32_t>(total_digits);
|
||||
|
||||
if (num_cur < num_len &&
|
||||
(num_string[num_cur] == 'e' || num_string[num_cur] == 'E')) {
|
||||
|
|
@ -393,7 +393,7 @@ public:
|
|||
this->left_shift(MAX_SHIFT_AMOUNT);
|
||||
shift_amount -= MAX_SHIFT_AMOUNT;
|
||||
}
|
||||
this->left_shift(shift_amount);
|
||||
this->left_shift(static_cast<uint32_t>(shift_amount));
|
||||
}
|
||||
// Right
|
||||
else {
|
||||
|
|
@ -401,7 +401,7 @@ public:
|
|||
this->right_shift(MAX_SHIFT_AMOUNT);
|
||||
shift_amount += MAX_SHIFT_AMOUNT;
|
||||
}
|
||||
this->right_shift(-shift_amount);
|
||||
this->right_shift(static_cast<uint32_t>(-shift_amount));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -424,8 +424,8 @@ public:
|
|||
result *= 10;
|
||||
++cur_digit;
|
||||
}
|
||||
return result + static_cast<unsigned int>(
|
||||
this->should_round_up(this->decimal_point, round));
|
||||
return result +
|
||||
static_cast<T>(this->should_round_up(this->decimal_point, round));
|
||||
}
|
||||
|
||||
// Extra functions for testing.
|
||||
|
|
|
|||
2
lib/libcxx/libc/src/__support/libc_assert.h
vendored
2
lib/libcxx/libc/src/__support/libc_assert.h
vendored
|
|
@ -9,7 +9,6 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_LIBC_ASSERT_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_LIBC_ASSERT_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
#if defined(LIBC_COPT_USE_C_ASSERT) || !defined(LIBC_FULL_BUILD)
|
||||
|
||||
// The build is configured to just use the public <assert.h> API
|
||||
|
|
@ -25,6 +24,7 @@
|
|||
#include "src/__support/OSUtil/io.h"
|
||||
#include "src/__support/integer_to_string.h"
|
||||
#include "src/__support/macros/attributes.h" // For LIBC_INLINE
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/optimization.h" // For LIBC_UNLIKELY
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
|
|
|||
|
|
@ -19,10 +19,19 @@
|
|||
if (LIBC_UNLIKELY((ptr) == nullptr)) \
|
||||
__builtin_trap(); \
|
||||
} while (0)
|
||||
#define LIBC_CRASH_ON_VALUE(var, value) \
|
||||
do { \
|
||||
if (LIBC_UNLIKELY((var) == (value))) \
|
||||
__builtin_trap(); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define LIBC_CRASH_ON_NULLPTR(ptr) \
|
||||
do { \
|
||||
} while (0)
|
||||
#define LIBC_CRASH_ON_VALUE(var, value) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_NULL_CHECK_H
|
||||
|
|
|
|||
|
|
@ -30,8 +30,10 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) {
|
|||
|
||||
#if defined(LIBC_COMPILER_IS_CLANG)
|
||||
#define LIBC_LOOP_NOUNROLL _Pragma("nounroll")
|
||||
#define LIBC_LOOP_UNROLL _Pragma("unroll")
|
||||
#elif defined(LIBC_COMPILER_IS_GCC)
|
||||
#define LIBC_LOOP_NOUNROLL _Pragma("GCC unroll 0")
|
||||
#define LIBC_LOOP_UNROLL _Pragma("GCC unroll 2048")
|
||||
#else
|
||||
#error "Unhandled compiler"
|
||||
#endif
|
||||
|
|
@ -45,6 +47,7 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) {
|
|||
#define LIBC_MATH_FAST \
|
||||
(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | \
|
||||
LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
|
||||
#define LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT 0x10
|
||||
|
||||
#ifndef LIBC_MATH
|
||||
#define LIBC_MATH 0
|
||||
|
|
@ -58,4 +61,16 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) {
|
|||
#define LIBC_MATH_HAS_SMALL_TABLES
|
||||
#endif
|
||||
|
||||
#if (LIBC_MATH & LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT)
|
||||
#define LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT
|
||||
#endif
|
||||
|
||||
#if (LIBC_MATH & LIBC_MATH_NO_ERRNO)
|
||||
#define LIBC_MATH_HAS_NO_ERRNO
|
||||
#endif
|
||||
|
||||
#if (LIBC_MATH & LIBC_MATH_NO_EXCEPT)
|
||||
#define LIBC_MATH_HAS_NO_EXCEPT
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#if defined(__SSE2__)
|
||||
#define LIBC_TARGET_CPU_HAS_SSE2
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_2__)
|
||||
|
|
@ -42,9 +44,55 @@
|
|||
#define LIBC_TARGET_CPU_HAS_AVX512BW
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FP)
|
||||
#if (__ARM_FP & 0x2)
|
||||
#define LIBC_TARGET_CPU_HAS_ARM_FPU_HALF
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_HALF
|
||||
#endif // LIBC_TARGET_CPU_HAS_ARM_FPU_HALF
|
||||
#if (__ARM_FP & 0x4)
|
||||
#define LIBC_TARGET_CPU_HAS_ARM_FPU_FLOAT
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
|
||||
#endif // LIBC_TARGET_CPU_HAS_ARM_FPU_FLOAT
|
||||
#if (__ARM_FP & 0x8)
|
||||
#define LIBC_TARGET_CPU_HAS_ARM_FPU_DOUBLE
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
|
||||
#endif // LIBC_TARGET_CPU_HAS_ARM_FPU_DOUBLE
|
||||
#endif // __ARM_FP
|
||||
|
||||
#if defined(__riscv_flen)
|
||||
// https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc
|
||||
#if defined(__riscv_zfhmin)
|
||||
#define LIBC_TARGET_CPU_HAS_RISCV_FPU_HALF
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_HALF
|
||||
#endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_HALF
|
||||
#if (__riscv_flen >= 32)
|
||||
#define LIBC_TARGET_CPU_HAS_RISCV_FPU_FLOAT
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
|
||||
#endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_FLOAT
|
||||
#if (__riscv_flen >= 64)
|
||||
#define LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
|
||||
#endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE
|
||||
#endif // __riscv_flen
|
||||
|
||||
#if defined(__NVPTX__) || defined(__AMDGPU__)
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_FLOAT
|
||||
#define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_FMA) || (defined(__AVX2__) && defined(__FMA__)) || \
|
||||
defined(__NVPTX__) || defined(__AMDGPU__) || defined(__LIBC_RISCV_USE_FMA)
|
||||
#define LIBC_TARGET_CPU_HAS_FMA
|
||||
// Provide a more fine-grained control of FMA instruction for ARM targets.
|
||||
#if defined(LIBC_TARGET_CPU_HAS_FPU_HALF)
|
||||
#define LIBC_TARGET_CPU_HAS_FMA_HALF
|
||||
#endif // LIBC_TARGET_CPU_HAS_FMA_HALF
|
||||
#if defined(LIBC_TARGET_CPU_HAS_FPU_FLOAT)
|
||||
#define LIBC_TARGET_CPU_HAS_FMA_FLOAT
|
||||
#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
|
||||
#if defined(LIBC_TARGET_CPU_HAS_FPU_DOUBLE)
|
||||
#define LIBC_TARGET_CPU_HAS_FMA_DOUBLE
|
||||
#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
|
||||
#endif
|
||||
|
||||
#if defined(LIBC_TARGET_ARCH_IS_AARCH64) || \
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "hdr/float_macros.h" // LDBL_MANT_DIG
|
||||
#include "include/llvm-libc-macros/float16-macros.h" // LIBC_TYPES_HAS_FLOAT16
|
||||
#include "include/llvm-libc-types/float128.h" // float128
|
||||
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
|
||||
#include "src/__support/macros/properties/architectures.h"
|
||||
#include "src/__support/macros/properties/compiler.h"
|
||||
#include "src/__support/macros/properties/cpu_features.h"
|
||||
|
|
@ -58,4 +59,14 @@ using float16 = _Float16;
|
|||
// LIBC_TYPES_HAS_FLOAT128 and 'float128' type are provided by
|
||||
// "include/llvm-libc-types/float128.h"
|
||||
|
||||
// -- bfloat16 support ---------------------------------------------------------
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace fputil {
|
||||
struct BFloat16;
|
||||
}
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
using bfloat16 = LIBC_NAMESPACE::fputil::BFloat16;
|
||||
|
||||
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
|
||||
|
|
|
|||
3
lib/libcxx/libc/src/__support/math_extras.h
vendored
3
lib/libcxx/libc/src/__support/math_extras.h
vendored
|
|
@ -146,8 +146,7 @@ first_trailing_zero(T value) {
|
|||
template <typename T>
|
||||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
|
||||
first_trailing_one(T value) {
|
||||
return value == cpp::numeric_limits<T>::max() ? 0
|
||||
: cpp::countr_zero(value) + 1;
|
||||
return value == 0 ? 0 : cpp::countr_zero(value) + 1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
|
|||
2
lib/libcxx/libc/src/__support/sign.h
vendored
2
lib/libcxx/libc/src/__support/sign.h
vendored
|
|
@ -29,6 +29,8 @@ struct Sign {
|
|||
static const Sign POS;
|
||||
static const Sign NEG;
|
||||
|
||||
LIBC_INLINE constexpr Sign negate() const { return Sign(!is_negative); }
|
||||
|
||||
private:
|
||||
LIBC_INLINE constexpr explicit Sign(bool is_negative)
|
||||
: is_negative(is_negative) {}
|
||||
|
|
|
|||
24
lib/libcxx/libc/src/__support/str_to_float.h
vendored
24
lib/libcxx/libc/src/__support/str_to_float.h
vendored
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H
|
||||
|
||||
#include "hdr/errno_macros.h" // For ERANGE
|
||||
#include "src/__support/CPP/bit.h"
|
||||
#include "src/__support/CPP/limits.h"
|
||||
#include "src/__support/CPP/optional.h"
|
||||
|
|
@ -31,7 +32,6 @@
|
|||
#include "src/__support/str_to_integer.h"
|
||||
#include "src/__support/str_to_num_result.h"
|
||||
#include "src/__support/uint128.h"
|
||||
#include "src/errno/libc_errno.h" // For ERANGE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -108,11 +108,11 @@ eisel_lemire(ExpandedFloat<T> init_num,
|
|||
}
|
||||
|
||||
// Normalization
|
||||
uint32_t clz = cpp::countl_zero<StorageType>(mantissa);
|
||||
uint32_t clz = static_cast<uint32_t>(cpp::countl_zero<StorageType>(mantissa));
|
||||
mantissa <<= clz;
|
||||
|
||||
int32_t exp2 =
|
||||
exp10_to_exp2(exp10) + FPBits::STORAGE_LEN + FPBits::EXP_BIAS - clz;
|
||||
int32_t exp2 = exp10_to_exp2(exp10) + FPBits::STORAGE_LEN + FPBits::EXP_BIAS -
|
||||
static_cast<int32_t>(clz);
|
||||
|
||||
// Multiplication
|
||||
const uint64_t *power_of_ten =
|
||||
|
|
@ -225,7 +225,7 @@ eisel_lemire<long double>(ExpandedFloat<long double> init_num,
|
|||
}
|
||||
|
||||
// Normalization
|
||||
uint32_t clz = cpp::countl_zero(mantissa) -
|
||||
int32_t clz = static_cast<int32_t>(cpp::countl_zero(mantissa)) -
|
||||
((sizeof(UInt128) - sizeof(StorageType)) * CHAR_BIT);
|
||||
mantissa <<= clz;
|
||||
|
||||
|
|
@ -802,7 +802,7 @@ LIBC_INLINE FloatConvertReturn<T> binary_exp_to_float(ExpandedFloat<T> init_num,
|
|||
|
||||
// Handle subnormals.
|
||||
if (biased_exponent <= 0) {
|
||||
amount_to_shift_right += 1 - biased_exponent;
|
||||
amount_to_shift_right += static_cast<uint32_t>(1 - biased_exponent);
|
||||
biased_exponent = 0;
|
||||
|
||||
if (amount_to_shift_right > FPBits::STORAGE_LEN) {
|
||||
|
|
@ -909,7 +909,7 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
|
|||
cpp::numeric_limits<StorageType>::max() / BASE;
|
||||
while (true) {
|
||||
if (isdigit(src[index])) {
|
||||
uint32_t digit = b36_char_to_int(src[index]);
|
||||
uint32_t digit = static_cast<uint32_t>(b36_char_to_int(src[index]));
|
||||
seen_digit = true;
|
||||
|
||||
if (mantissa < bitstype_max_div_by_base) {
|
||||
|
|
@ -956,7 +956,7 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
|
|||
if (result.has_error())
|
||||
output.error = result.error;
|
||||
int32_t add_to_exponent = result.value;
|
||||
index += result.parsed_len;
|
||||
index += static_cast<size_t>(result.parsed_len);
|
||||
|
||||
// Here we do this operation as int64 to avoid overflow.
|
||||
int64_t temp_exponent = static_cast<int64_t>(exponent) +
|
||||
|
|
@ -1020,7 +1020,7 @@ hexadecimal_string_to_float(const char *__restrict src,
|
|||
cpp::numeric_limits<StorageType>::max() / BASE;
|
||||
while (true) {
|
||||
if (isalnum(src[index])) {
|
||||
uint32_t digit = b36_char_to_int(src[index]);
|
||||
uint32_t digit = static_cast<uint32_t>(b36_char_to_int(src[index]));
|
||||
if (digit < BASE)
|
||||
seen_digit = true;
|
||||
else
|
||||
|
|
@ -1070,7 +1070,7 @@ hexadecimal_string_to_float(const char *__restrict src,
|
|||
output.error = result.error;
|
||||
|
||||
int32_t add_to_exponent = result.value;
|
||||
index += result.parsed_len;
|
||||
index += static_cast<size_t>(result.parsed_len);
|
||||
|
||||
// Here we do this operation as int64 to avoid overflow.
|
||||
int64_t temp_exponent = static_cast<int64_t>(exponent) +
|
||||
|
|
@ -1135,7 +1135,7 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
|
|||
|
||||
int error = 0;
|
||||
|
||||
ptrdiff_t index = first_non_whitespace(src) - src;
|
||||
size_t index = first_non_whitespace(src);
|
||||
|
||||
if (src[index] == '+' || src[index] == '-') {
|
||||
sign = src[index];
|
||||
|
|
@ -1245,7 +1245,7 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
|
|||
// special 80 bit long doubles. Otherwise it should be inlined out.
|
||||
set_implicit_bit<T>(result);
|
||||
|
||||
return {result.get_val(), index, error};
|
||||
return {result.get_val(), static_cast<ptrdiff_t>(index), error};
|
||||
}
|
||||
|
||||
template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) {
|
||||
|
|
|
|||
21
lib/libcxx/libc/src/__support/str_to_integer.h
vendored
21
lib/libcxx/libc/src/__support/str_to_integer.h
vendored
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef LLVM_LIBC_SRC___SUPPORT_STR_TO_INTEGER_H
|
||||
#define LLVM_LIBC_SRC___SUPPORT_STR_TO_INTEGER_H
|
||||
|
||||
#include "hdr/errno_macros.h" // For ERANGE
|
||||
#include "src/__support/CPP/limits.h"
|
||||
#include "src/__support/CPP/type_traits.h"
|
||||
#include "src/__support/CPP/type_traits/make_unsigned.h"
|
||||
|
|
@ -24,22 +25,20 @@
|
|||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/str_to_num_result.h"
|
||||
#include "src/__support/uint128.h"
|
||||
#include "src/errno/libc_errno.h" // For ERANGE
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace internal {
|
||||
|
||||
// Returns a pointer to the first character in src that is not a whitespace
|
||||
// Returns the idx to the first character in src that is not a whitespace
|
||||
// character (as determined by isspace())
|
||||
// TODO: Change from returning a pointer to returning a length.
|
||||
LIBC_INLINE const char *
|
||||
LIBC_INLINE size_t
|
||||
first_non_whitespace(const char *__restrict src,
|
||||
size_t src_len = cpp::numeric_limits<size_t>::max()) {
|
||||
size_t src_cur = 0;
|
||||
while (src_cur < src_len && internal::isspace(src[src_cur])) {
|
||||
++src_cur;
|
||||
}
|
||||
return src + src_cur;
|
||||
return src_cur;
|
||||
}
|
||||
|
||||
// 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,
|
|||
if (base < 0 || base == 1 || base > 36)
|
||||
return {0, 0, EINVAL};
|
||||
|
||||
src_cur = first_non_whitespace(src, src_len) - src;
|
||||
src_cur = first_non_whitespace(src, src_len);
|
||||
|
||||
char result_sign = '+';
|
||||
if (src[src_cur] == '+' || src[src_cur] == '-') {
|
||||
|
|
@ -119,7 +118,7 @@ strtointeger(const char *__restrict src, int base,
|
|||
ResultType const abs_max =
|
||||
(is_positive ? cpp::numeric_limits<T>::max() : NEGATIVE_MAX);
|
||||
ResultType const abs_max_div_by_base =
|
||||
static_cast<ResultType>(abs_max / base);
|
||||
abs_max / static_cast<ResultType>(base);
|
||||
|
||||
while (src_cur < src_len && isalnum(src[src_cur])) {
|
||||
int cur_digit = b36_char_to_int(src[src_cur]);
|
||||
|
|
@ -141,17 +140,17 @@ strtointeger(const char *__restrict src, int base,
|
|||
result = abs_max;
|
||||
error_val = ERANGE;
|
||||
} else {
|
||||
result = static_cast<ResultType>(result * base);
|
||||
result = result * static_cast<ResultType>(base);
|
||||
}
|
||||
if (result > abs_max - cur_digit) {
|
||||
if (result > abs_max - static_cast<ResultType>(cur_digit)) {
|
||||
result = abs_max;
|
||||
error_val = ERANGE;
|
||||
} else {
|
||||
result = static_cast<ResultType>(result + cur_digit);
|
||||
result = result + static_cast<ResultType>(cur_digit);
|
||||
}
|
||||
}
|
||||
|
||||
ptrdiff_t str_len = is_number ? (src_cur) : 0;
|
||||
ptrdiff_t str_len = is_number ? static_cast<ptrdiff_t>(src_cur) : 0;
|
||||
|
||||
if (error_val == ERANGE) {
|
||||
if (is_positive || IS_UNSIGNED)
|
||||
|
|
|
|||
47
lib/libcxx/libc/src/errno/libc_errno.h
vendored
47
lib/libcxx/libc/src/errno/libc_errno.h
vendored
|
|
@ -1,47 +0,0 @@
|
|||
//===-- Implementation header for libc_errno --------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_ERRNO_LIBC_ERRNO_H
|
||||
#define LLVM_LIBC_SRC_ERRNO_LIBC_ERRNO_H
|
||||
|
||||
#include "src/__support/macros/attributes.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/properties/architectures.h"
|
||||
|
||||
#include "hdr/errno_macros.h"
|
||||
|
||||
// This header is to be consumed by internal implementations, in which all of
|
||||
// them should refer to `libc_errno` instead of using `errno` directly from
|
||||
// <errno.h> header.
|
||||
|
||||
// Unit and hermetic tests should:
|
||||
// - #include "src/errno/libc_errno.h"
|
||||
// - NOT #include <errno.h>
|
||||
// - Only use `libc_errno` in the code
|
||||
// - Depend on libc.src.errno.errno
|
||||
|
||||
// Integration tests should:
|
||||
// - NOT #include "src/errno/libc_errno.h"
|
||||
// - #include <errno.h>
|
||||
// - Use regular `errno` in the code
|
||||
// - Still depend on libc.src.errno.errno
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
extern "C" int *__llvm_libc_errno() noexcept;
|
||||
|
||||
struct Errno {
|
||||
void operator=(int);
|
||||
operator int();
|
||||
};
|
||||
|
||||
extern Errno libc_errno;
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_ERRNO_LIBC_ERRNO_H
|
||||
Loading…
Add table
Reference in a new issue