diff options
Diffstat (limited to 'libc/src')
25 files changed, 309 insertions, 149 deletions
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt index 6e447fc..37520ea 100644 --- a/libc/src/__support/FPUtil/CMakeLists.txt +++ b/libc/src/__support/FPUtil/CMakeLists.txt @@ -285,6 +285,9 @@ add_header_library( libc.hdr.stdint_proxy libc.src.__support.CPP.bit libc.src.__support.CPP.type_traits + libc.src.__support.FPUtil.generic.add_sub + libc.src.__support.FPUtil.generic.div + libc.src.__support.FPUtil.generic.mul libc.src.__support.macros.config libc.src.__support.macros.properties.types ) diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h index fa45d73..3fab2b8 100644 --- a/libc/src/__support/FPUtil/bfloat16.h +++ b/libc/src/__support/FPUtil/bfloat16.h @@ -15,6 +15,9 @@ #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/comparison_operations.h" #include "src/__support/FPUtil/dyadic_float.h" +#include "src/__support/FPUtil/generic/add_sub.h" +#include "src/__support/FPUtil/generic/div.h" +#include "src/__support/FPUtil/generic/mul.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/types.h" @@ -81,6 +84,28 @@ struct BFloat16 { LIBC_INLINE bool operator>=(BFloat16 other) const { return fputil::greater_than_or_equals(*this, other); } + + LIBC_INLINE constexpr BFloat16 operator-() const { + fputil::FPBits<bfloat16> result(*this); + result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS); + return result.get_val(); + } + + LIBC_INLINE BFloat16 operator+(BFloat16 other) const { + return fputil::generic::add<BFloat16>(*this, other); + } + + LIBC_INLINE BFloat16 operator-(BFloat16 other) const { + return fputil::generic::sub<BFloat16>(*this, other); + } + + LIBC_INLINE BFloat16 operator*(BFloat16 other) const { + return fputil::generic::mul<bfloat16>(*this, other); + } + + LIBC_INLINE BFloat16 operator/(BFloat16 other) const { + return fputil::generic::div<bfloat16>(*this, other); + } }; // struct BFloat16 } // namespace fputil diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h index e999ece..54c80e8 100644 --- a/libc/src/__support/FPUtil/cast.h +++ b/libc/src/__support/FPUtil/cast.h @@ -27,47 +27,47 @@ LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> && OutType> cast(InType x) { // Casting to the same type is a no-op. - if constexpr (cpp::is_same_v<InType, OutType>) + if constexpr (cpp::is_same_v<InType, OutType>) { return x; - - // bfloat16 is always defined (for now) - if constexpr (cpp::is_same_v<OutType, bfloat16> || - cpp::is_same_v<InType, bfloat16> + } else { + if constexpr (cpp::is_same_v<OutType, bfloat16> || + cpp::is_same_v<InType, bfloat16> #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION) - || cpp::is_same_v<OutType, float16> || - cpp::is_same_v<InType, float16> + || cpp::is_same_v<OutType, float16> || + cpp::is_same_v<InType, float16> #endif - ) { - using InFPBits = FPBits<InType>; - using InStorageType = typename InFPBits::StorageType; - using OutFPBits = FPBits<OutType>; - using OutStorageType = typename OutFPBits::StorageType; + ) { + using InFPBits = FPBits<InType>; + using InStorageType = typename InFPBits::StorageType; + using OutFPBits = FPBits<OutType>; + using OutStorageType = typename OutFPBits::StorageType; - InFPBits x_bits(x); + InFPBits x_bits(x); - if (x_bits.is_nan()) { - if (x_bits.is_signaling_nan()) { - raise_except_if_required(FE_INVALID); - return OutFPBits::quiet_nan().get_val(); - } + if (x_bits.is_nan()) { + if (x_bits.is_signaling_nan()) { + raise_except_if_required(FE_INVALID); + return OutFPBits::quiet_nan().get_val(); + } - InStorageType x_mant = x_bits.get_mantissa(); - if (InFPBits::FRACTION_LEN > OutFPBits::FRACTION_LEN) - x_mant >>= InFPBits::FRACTION_LEN - OutFPBits::FRACTION_LEN; - return OutFPBits::quiet_nan(x_bits.sign(), - static_cast<OutStorageType>(x_mant)) - .get_val(); - } + InStorageType x_mant = x_bits.get_mantissa(); + if (InFPBits::FRACTION_LEN > OutFPBits::FRACTION_LEN) + x_mant >>= InFPBits::FRACTION_LEN - OutFPBits::FRACTION_LEN; + return OutFPBits::quiet_nan(x_bits.sign(), + static_cast<OutStorageType>(x_mant)) + .get_val(); + } - if (x_bits.is_inf()) - return OutFPBits::inf(x_bits.sign()).get_val(); + if (x_bits.is_inf()) + return OutFPBits::inf(x_bits.sign()).get_val(); - constexpr size_t MAX_FRACTION_LEN = - cpp::max(OutFPBits::FRACTION_LEN, InFPBits::FRACTION_LEN); - DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x); - return xd.template as<OutType, /*ShouldSignalExceptions=*/true>(); - } else { - return static_cast<OutType>(x); + constexpr size_t MAX_FRACTION_LEN = + cpp::max(OutFPBits::FRACTION_LEN, InFPBits::FRACTION_LEN); + DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x); + return xd.template as<OutType, /*ShouldSignalExceptions=*/true>(); + } else { + return static_cast<OutType>(x); + } } } diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h index 3464e4a..cc0710f 100644 --- a/libc/src/__support/FPUtil/dyadic_float.h +++ b/libc/src/__support/FPUtil/dyadic_float.h @@ -576,7 +576,7 @@ LIBC_INLINE constexpr DyadicFloat<Bits> quick_mul(const DyadicFloat<Bits> &a, // Check the leading bit directly, should be faster than using clz in // normalize(). if (result.mantissa.val[DyadicFloat<Bits>::MantissaType::WORD_COUNT - 1] >> - 63 == + (DyadicFloat<Bits>::MantissaType::WORD_SIZE - 1) == 0) result.shift_left(1); } else { diff --git a/libc/src/__support/FPUtil/generic/CMakeLists.txt b/libc/src/__support/FPUtil/generic/CMakeLists.txt index 117213f..b75efc8 100644 --- a/libc/src/__support/FPUtil/generic/CMakeLists.txt +++ b/libc/src/__support/FPUtil/generic/CMakeLists.txt @@ -68,6 +68,7 @@ add_header_library( libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.attributes libc.src.__support.macros.optimization + libc.src.__support.macros.properties.types ) add_header_library( @@ -77,6 +78,7 @@ add_header_library( DEPENDS libc.hdr.errno_macros libc.hdr.fenv_macros + libc.src.__support.CPP.algorithm libc.src.__support.CPP.bit libc.src.__support.CPP.type_traits libc.src.__support.FPUtil.basic_operations diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h index d4a4129..b2e9d81 100644 --- a/libc/src/__support/FPUtil/generic/add_sub.h +++ b/libc/src/__support/FPUtil/generic/add_sub.h @@ -104,13 +104,22 @@ add_or_sub(InType x, InType y) { } } - // volatile prevents Clang from converting tmp to OutType and then - // immediately back to InType before negating it, resulting in double - // rounding. - volatile InType tmp = y; - if constexpr (IsSub) - tmp = -tmp; - return cast<OutType>(tmp); + if constexpr (cpp::is_same_v<InType, bfloat16> && + cpp::is_same_v<OutType, bfloat16>) { + OutFPBits y_bits(y); + if constexpr (IsSub) + y_bits.set_sign(y_bits.sign().negate()); + return y_bits.get_val(); + } else { + + // volatile prevents Clang from converting tmp to OutType and then + // immediately back to InType before negating it, resulting in double + // rounding. + volatile InType tmp = y; + if constexpr (IsSub) + tmp = -tmp; + return cast<OutType>(tmp); + } } if (y_bits.is_zero()) @@ -165,8 +174,8 @@ add_or_sub(InType x, InType y) { int alignment = (max_bits.get_biased_exponent() - max_bits.is_normal()) - (min_bits.get_biased_exponent() - min_bits.is_normal()); - InStorageType aligned_min_mant = - min_mant >> cpp::min(alignment, RESULT_MANTISSA_LEN); + InStorageType aligned_min_mant = static_cast<InStorageType>( + min_mant >> cpp::min(alignment, RESULT_MANTISSA_LEN)); bool aligned_min_mant_sticky; if (alignment <= GUARD_BITS_LEN) diff --git a/libc/src/__support/FPUtil/generic/div.h b/libc/src/__support/FPUtil/generic/div.h index 0891ae0..bf7d0b7 100644 --- a/libc/src/__support/FPUtil/generic/div.h +++ b/libc/src/__support/FPUtil/generic/div.h @@ -11,6 +11,7 @@ #include "hdr/errno_macros.h" #include "hdr/fenv_macros.h" +#include "src/__support/CPP/algorithm.h" #include "src/__support/CPP/bit.h" #include "src/__support/CPP/type_traits.h" #include "src/__support/FPUtil/BasicOperations.h" @@ -34,8 +35,9 @@ div(InType x, InType y) { using OutStorageType = typename OutFPBits::StorageType; using InFPBits = FPBits<InType>; using InStorageType = typename InFPBits::StorageType; - using DyadicFloat = - DyadicFloat<cpp::bit_ceil(static_cast<size_t>(InFPBits::SIG_LEN + 1))>; + using DyadicFloat = DyadicFloat<cpp::max( + static_cast<size_t>(16), + cpp::bit_ceil(static_cast<size_t>(InFPBits::SIG_LEN + 1)))>; InFPBits x_bits(x); InFPBits y_bits(y); diff --git a/libc/src/__support/FPUtil/rounding_mode.h b/libc/src/__support/FPUtil/rounding_mode.h index 4ee0a0b..fdc8498 100644 --- a/libc/src/__support/FPUtil/rounding_mode.h +++ b/libc/src/__support/FPUtil/rounding_mode.h @@ -17,30 +17,24 @@ namespace LIBC_NAMESPACE_DECL { namespace fputil { +namespace generic { + // Quick free-standing test whether fegetround() == FE_UPWARD. // Using the following observation: // 1.0f + 2^-25 = 1.0f for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO // = 0x1.000002f for FE_UPWARD. -LIBC_INLINE static constexpr bool fenv_is_round_up() { - if (cpp::is_constant_evaluated()) { - return false; - } else { - volatile float x = 0x1.0p-25f; - return (1.0f + x != 1.0f); - } +LIBC_INLINE bool fenv_is_round_up() { + static volatile float x = 0x1.0p-25f; + return (1.0f + x != 1.0f); } // Quick free-standing test whether fegetround() == FE_DOWNWARD. // Using the following observation: // -1.0f - 2^-25 = -1.0f for FE_TONEAREST, FE_UPWARD, FE_TOWARDZERO // = -0x1.000002f for FE_DOWNWARD. -LIBC_INLINE static constexpr bool fenv_is_round_down() { - if (cpp::is_constant_evaluated()) { - return false; - } else { - volatile float x = 0x1.0p-25f; - return (-1.0f - x != -1.0f); - } +LIBC_INLINE bool fenv_is_round_down() { + static volatile float x = 0x1.0p-25f; + return (-1.0f - x != -1.0f); } // Quick free-standing test whether fegetround() == FE_TONEAREST. @@ -49,14 +43,10 @@ LIBC_INLINE static constexpr bool fenv_is_round_down() { // = 0x1.100002p0f for FE_UPWARD, // 1.5f - 2^-24 = 1.5f for FE_TONEAREST, FE_UPWARD // = 0x1.0ffffep-1f for FE_DOWNWARD, FE_TOWARDZERO -LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() { - if (cpp::is_constant_evaluated()) { - return true; - } else { - volatile float x = 0x1.0p-24f; - float y = 1.5f + x; - return (y == 1.5f - x); - } +LIBC_INLINE bool fenv_is_round_to_nearest() { + static volatile float x = 0x1.0p-24f; + float y = 1.5f + x; + return (y == 1.5f - x); } // Quick free-standing test whether fegetround() == FE_TOWARDZERO. @@ -69,13 +59,56 @@ LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() { // (0x1.000002p0f + 2^-24) + (-1.0f - 2^-24) = 2^-23 for FE_TOWARDZERO // = 2^-22 for FE_TONEAREST, FE_UPWARD // = 0 for FE_DOWNWARD +LIBC_INLINE bool fenv_is_round_to_zero() { + static volatile float x = 0x1.0p-24f; + float y = x; + return ((0x1.000002p0f + y) + (-1.0f - y) == 0x1.0p-23f); +} + +// Quick free standing get rounding mode based on the above observations. +LIBC_INLINE int quick_get_round() { + static volatile float x = 0x1.0p-24f; + float y = x; + float z = (0x1.000002p0f + y) + (-1.0f - y); + + if (z == 0.0f) + return FE_DOWNWARD; + if (z == 0x1.0p-23f) + return FE_TOWARDZERO; + return (2.0f + y == 2.0f) ? FE_TONEAREST : FE_UPWARD; +} + +} // namespace generic + +LIBC_INLINE static constexpr bool fenv_is_round_up() { + if (cpp::is_constant_evaluated()) { + return false; + } else { + return generic::fenv_is_round_up(); + } +} + +LIBC_INLINE static constexpr bool fenv_is_round_down() { + if (cpp::is_constant_evaluated()) { + return false; + } else { + return generic::fenv_is_round_down(); + } +} + +LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() { + if (cpp::is_constant_evaluated()) { + return true; + } else { + return generic::fenv_is_round_to_nearest(); + } +} + LIBC_INLINE static constexpr bool fenv_is_round_to_zero() { if (cpp::is_constant_evaluated()) { return false; } else { - volatile float x = 0x1.0p-24f; - volatile float y = 0x1.000002p0f + x; - return (y + (-1.0f - x) == 0x1.0p-23f); + return generic::fenv_is_round_to_zero(); } } @@ -84,15 +117,7 @@ LIBC_INLINE static constexpr int quick_get_round() { if (cpp::is_constant_evaluated()) { return FE_TONEAREST; } else { - volatile float x = 0x1.0p-24f; - volatile float y = 0x1.000002p0f + x; - float z = y + (-1.0f - x); - - if (z == 0.0f) - return FE_DOWNWARD; - if (z == 0x1.0p-23f) - return FE_TOWARDZERO; - return (2.0f + x == 2.0f) ? FE_TONEAREST : FE_UPWARD; + return generic::quick_get_round(); } } diff --git a/libc/src/__support/OSUtil/linux/aarch64/vdso.h b/libc/src/__support/OSUtil/linux/aarch64/vdso.h index 3c4c620..ee5777a 100644 --- a/libc/src/__support/OSUtil/linux/aarch64/vdso.h +++ b/libc/src/__support/OSUtil/linux/aarch64/vdso.h @@ -23,6 +23,8 @@ LIBC_INLINE constexpr cpp::string_view symbol_name(VDSOSym sym) { return "__kernel_clock_gettime"; case VDSOSym::ClockGetRes: return "__kernel_clock_getres"; + case VDSOSym::GetRandom: + return "__kernel_getrandom"; default: return ""; } diff --git a/libc/src/__support/OSUtil/linux/vdso_sym.h b/libc/src/__support/OSUtil/linux/vdso_sym.h index 968e153..01f0b72 100644 --- a/libc/src/__support/OSUtil/linux/vdso_sym.h +++ b/libc/src/__support/OSUtil/linux/vdso_sym.h @@ -35,7 +35,8 @@ enum class VDSOSym { RTSigReturn, FlushICache, RiscvHwProbe, - VDSOSymCount + GetRandom, + VDSOSymCount, }; template <VDSOSym sym> LIBC_INLINE constexpr auto dispatcher() { @@ -60,6 +61,9 @@ template <VDSOSym sym> LIBC_INLINE constexpr auto dispatcher() { else if constexpr (sym == VDSOSym::RiscvHwProbe) return static_cast<int (*)(riscv_hwprobe *, size_t, size_t, cpu_set_t *, unsigned)>(nullptr); + else if constexpr (sym == VDSOSym::GetRandom) + return static_cast<int (*)(void *, size_t, unsigned int, void *, size_t)>( + nullptr); else return static_cast<void *>(nullptr); } diff --git a/libc/src/__support/OSUtil/linux/x86_64/vdso.h b/libc/src/__support/OSUtil/linux/x86_64/vdso.h index abe7c33..f46fcb0 100644 --- a/libc/src/__support/OSUtil/linux/x86_64/vdso.h +++ b/libc/src/__support/OSUtil/linux/x86_64/vdso.h @@ -29,6 +29,8 @@ LIBC_INLINE constexpr cpp::string_view symbol_name(VDSOSym sym) { return "__vdso_time"; case VDSOSym::ClockGetRes: return "__vdso_clock_getres"; + case VDSOSym::GetRandom: + return "__vdso_getrandom"; default: return ""; } diff --git a/libc/src/__support/macros/attributes.h b/libc/src/__support/macros/attributes.h index c647467..4ff374b 100644 --- a/libc/src/__support/macros/attributes.h +++ b/libc/src/__support/macros/attributes.h @@ -28,7 +28,32 @@ #define LIBC_INLINE_ASM __asm__ __volatile__ #define LIBC_UNUSED __attribute__((unused)) -#ifdef LIBC_TARGET_ARCH_IS_GPU +// Uses the platform specific specialization +#define LIBC_THREAD_MODE_PLATFORM 0 + +// Mutex guards nothing, used in single-threaded implementations +#define LIBC_THREAD_MODE_SINGLE 1 + +// Vendor provides implementation +#define LIBC_THREAD_MODE_EXTERNAL 2 + +// libcxx doesn't define LIBC_THREAD_MODE, unless that is passed in the command +// line in the CMake invocation. This defaults to the original implementation +// (before changes in https://github.com/llvm/llvm-project/pull/145358) +#ifndef LIBC_THREAD_MODE +#define LIBC_THREAD_MODE LIBC_THREAD_MODE_PLATFORM +#endif // LIBC_THREAD_MODE + +#if LIBC_THREAD_MODE != LIBC_THREAD_MODE_PLATFORM && \ + LIBC_THREAD_MODE != LIBC_THREAD_MODE_SINGLE && \ + LIBC_THREAD_MODE != LIBC_THREAD_MODE_EXTERNAL +#error LIBC_THREAD_MODE must be one of the following values: \ +LIBC_THREAD_MODE_PLATFORM, \ +LIBC_THREAD_MODE_SINGLE, \ +LIBC_THREAD_MODE_EXTERNAL. +#endif + +#if LIBC_THREAD_MODE == LIBC_THREAD_MODE_SINGLE #define LIBC_THREAD_LOCAL #else #define LIBC_THREAD_LOCAL thread_local diff --git a/libc/src/__support/threads/mutex.h b/libc/src/__support/threads/mutex.h index cbef0d0..f64f7e7 100644 --- a/libc/src/__support/threads/mutex.h +++ b/libc/src/__support/threads/mutex.h @@ -12,28 +12,6 @@ #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" -// Uses the platform specific specialization -#define LIBC_THREAD_MODE_PLATFORM 0 - -// Mutex guards nothing, used in single-threaded implementations -#define LIBC_THREAD_MODE_SINGLE 1 - -// Vendor provides implementation -#define LIBC_THREAD_MODE_EXTERNAL 2 - -#if !defined(LIBC_THREAD_MODE) -#error LIBC_THREAD_MODE is undefined -#endif // LIBC_THREAD_MODE - -#if LIBC_THREAD_MODE != LIBC_THREAD_MODE_PLATFORM && \ - LIBC_THREAD_MODE != LIBC_THREAD_MODE_SINGLE && \ - LIBC_THREAD_MODE != LIBC_THREAD_MODE_EXTERNAL -#error LIBC_THREAD_MODE must be one of the following values: \ -LIBC_THREAD_MODE_PLATFORM, \ -LIBC_THREAD_MODE_SINGLE, \ -LIBC_THREAD_MODE_EXTERNAL. -#endif - #if LIBC_THREAD_MODE == LIBC_THREAD_MODE_PLATFORM // Platform independent code will include this header file which pulls diff --git a/libc/src/__support/wchar/character_converter.cpp b/libc/src/__support/wchar/character_converter.cpp index 15d0f47..2667288 100644 --- a/libc/src/__support/wchar/character_converter.cpp +++ b/libc/src/__support/wchar/character_converter.cpp @@ -132,12 +132,6 @@ ErrorOr<char32_t> CharacterConverter::pop_utf32() { return utf32; } -size_t CharacterConverter::sizeAsUTF32() { - return 1; // a single utf-32 value can fit an entire character -} - -size_t CharacterConverter::sizeAsUTF8() { return state->total_bytes; } - ErrorOr<char8_t> CharacterConverter::pop_utf8() { if (isEmpty()) return Error(-1); @@ -170,5 +164,13 @@ ErrorOr<char8_t> CharacterConverter::pop_utf8() { return static_cast<char8_t>(output); } +template <> ErrorOr<char8_t> CharacterConverter::pop() { return pop_utf8(); } +template <> ErrorOr<char32_t> CharacterConverter::pop() { return pop_utf32(); } + +template <> size_t CharacterConverter::sizeAs<char8_t>() { + return state->total_bytes; +} +template <> size_t CharacterConverter::sizeAs<char32_t>() { return 1; } + } // namespace internal } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/wchar/character_converter.h b/libc/src/__support/wchar/character_converter.h index b6d918f..2cc28ab 100644 --- a/libc/src/__support/wchar/character_converter.h +++ b/libc/src/__support/wchar/character_converter.h @@ -12,6 +12,7 @@ #include "hdr/types/char32_t.h" #include "hdr/types/char8_t.h" #include "hdr/types/size_t.h" +#include "src/__support/CPP/type_traits.h" #include "src/__support/common.h" #include "src/__support/error_or.h" #include "src/__support/wchar/mbstate.h" @@ -31,14 +32,14 @@ public: bool isEmpty(); bool isValidState(); - size_t sizeAsUTF32(); - size_t sizeAsUTF8(); + template <typename CharType> size_t sizeAs(); int push(char8_t utf8_byte); int push(char32_t utf32); ErrorOr<char8_t> pop_utf8(); ErrorOr<char32_t> pop_utf32(); + template <typename CharType> ErrorOr<CharType> pop(); }; } // namespace internal diff --git a/libc/src/__support/wchar/mbsnrtowcs.h b/libc/src/__support/wchar/mbsnrtowcs.h index 54e3152..6abb836 100644 --- a/libc/src/__support/wchar/mbsnrtowcs.h +++ b/libc/src/__support/wchar/mbsnrtowcs.h @@ -36,7 +36,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst, StringConverter<char8_t> str_conv(reinterpret_cast<const char8_t *>(*src), ps, len, nmc); size_t dst_idx = 0; - ErrorOr<char32_t> converted = str_conv.popUTF32(); + ErrorOr<char32_t> converted = str_conv.pop<char32_t>(); while (converted.has_value()) { if (dst != nullptr) dst[dst_idx] = converted.value(); @@ -47,7 +47,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst, return dst_idx; } dst_idx++; - converted = str_conv.popUTF32(); + converted = str_conv.pop<char32_t>(); } if (converted.error() == -1) { // if we hit conversion limit diff --git a/libc/src/__support/wchar/string_converter.h b/libc/src/__support/wchar/string_converter.h index 869ebdf..ba628bd 100644 --- a/libc/src/__support/wchar/string_converter.h +++ b/libc/src/__support/wchar/string_converter.h @@ -12,6 +12,7 @@ #include "hdr/types/char32_t.h" #include "hdr/types/char8_t.h" #include "hdr/types/size_t.h" +#include "src/__support/CPP/type_traits.h" #include "src/__support/common.h" #include "src/__support/error_or.h" #include "src/__support/wchar/character_converter.h" @@ -53,9 +54,7 @@ public: size_t srclen = SIZE_MAX) : cr(ps), src(s), src_len(srclen), src_idx(0), num_to_write(dstlen) {} - // TODO: following functions are almost identical - // look into templating CharacterConverter pop functions - ErrorOr<char32_t> popUTF32() { + template <typename CharType> ErrorOr<CharType> pop() { if (num_to_write == 0) return Error(-1); @@ -64,7 +63,7 @@ public: if (!src_elements_read.has_value()) return Error(src_elements_read.error()); - if (cr.sizeAsUTF32() > num_to_write) { + if (cr.sizeAs<CharType>() > num_to_write) { cr.clear(); return Error(-1); } @@ -72,34 +71,9 @@ public: src_idx += src_elements_read.value(); } - auto out = cr.pop_utf32(); - if (out.has_value() && out.value() == L'\0') - src_len = src_idx; - - num_to_write--; - - return out; - } - - ErrorOr<char8_t> popUTF8() { - if (num_to_write == 0) - return Error(-1); - - if (cr.isEmpty() || src_idx == 0) { - auto src_elements_read = pushFullCharacter(); - if (!src_elements_read.has_value()) - return Error(src_elements_read.error()); - - if (cr.sizeAsUTF8() > num_to_write) { - cr.clear(); - return Error(-1); - } - - src_idx += src_elements_read.value(); - } - - auto out = cr.pop_utf8(); - if (out.has_value() && out.value() == '\0') + ErrorOr<CharType> out = cr.pop<CharType>(); + // if out isn't null terminator or an error + if (out.has_value() && out.value() == 0) src_len = src_idx; num_to_write--; diff --git a/libc/src/__support/wchar/wcsnrtombs.h b/libc/src/__support/wchar/wcsnrtombs.h index 433097c..f593a0e 100644 --- a/libc/src/__support/wchar/wcsnrtombs.h +++ b/libc/src/__support/wchar/wcsnrtombs.h @@ -39,7 +39,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src, reinterpret_cast<const char32_t *>(*ptr_to_src), ps, dest_len, num_src_widechars); size_t dst_idx = 0; - ErrorOr<char8_t> converted = str_conv.popUTF8(); + ErrorOr<char8_t> converted = str_conv.pop<char8_t>(); while (converted.has_value()) { if (dest != nullptr) dest[dst_idx] = converted.value(); @@ -51,7 +51,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src, } dst_idx++; - converted = str_conv.popUTF8(); + converted = str_conv.pop<char8_t>(); } if (dest != nullptr) diff --git a/libc/src/dlfcn/CMakeLists.txt b/libc/src/dlfcn/CMakeLists.txt index e3a51ba..8ef0540 100644 --- a/libc/src/dlfcn/CMakeLists.txt +++ b/libc/src/dlfcn/CMakeLists.txt @@ -38,3 +38,25 @@ add_entrypoint_object( libc.include.dlfcn libc.src.errno.errno ) + +add_entrypoint_object( + dlinfo + SRCS + dlinfo.cpp + HDRS + dlinfo.h + DEPENDS + libc.include.dlfcn + libc.src.errno.errno +) + +add_entrypoint_object( + dladdr + SRCS + dladdr.cpp + HDRS + dladdr.h + DEPENDS + libc.include.dlfcn + libc.src.errno.errno +) diff --git a/libc/src/dlfcn/dladdr.cpp b/libc/src/dlfcn/dladdr.cpp new file mode 100644 index 0000000..61490fd --- /dev/null +++ b/libc/src/dlfcn/dladdr.cpp @@ -0,0 +1,21 @@ +//===-- Implementation of dladdr ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "dladdr.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +// TODO: https:// github.com/llvm/llvm-project/issues/97929 +LLVM_LIBC_FUNCTION(int, dladdr, (const void *addr, Dl_info *info)) { + return -1; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/dlfcn/dladdr.h b/libc/src/dlfcn/dladdr.h new file mode 100644 index 0000000..346fc8d --- /dev/null +++ b/libc/src/dlfcn/dladdr.h @@ -0,0 +1,20 @@ +//===-- Implementation header of dladdr -------------------------*- 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_DLFCN_DLADDR_H +#define LLVM_LIBC_SRC_DLFCN_DLADDR_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int dladdr(const void *, Dl_info *); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_DLFCN_DLADDR_H diff --git a/libc/src/dlfcn/dlinfo.cpp b/libc/src/dlfcn/dlinfo.cpp new file mode 100644 index 0000000..d78cade --- /dev/null +++ b/libc/src/dlfcn/dlinfo.cpp @@ -0,0 +1,23 @@ + +//===-- Implementation of dlinfo ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "dlinfo.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +// TODO: https://github.com/llvm/llvm-project/issues/149911 +LLVM_LIBC_FUNCTION(int, dlinfo, + (void *restrict handle, int request, void *restrict info)) { + return -1; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/dlfcn/dlinfo.h b/libc/src/dlfcn/dlinfo.h new file mode 100644 index 0000000..c2c34f0 --- /dev/null +++ b/libc/src/dlfcn/dlinfo.h @@ -0,0 +1,20 @@ +//===-- Implementation header of dlinfo -------------------------*- 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_DLFCN_DLINFO_H +#define LLVM_LIBC_SRC_DLFCN_DLINFO_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int dlinfo(void *restrict, int, void *restrict); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_DLFCN_DLINFO_H diff --git a/libc/src/wctype/iswalpha.cpp b/libc/src/wctype/iswalpha.cpp index e18f293..09f55d3 100644 --- a/libc/src/wctype/iswalpha.cpp +++ b/libc/src/wctype/iswalpha.cpp @@ -14,6 +14,6 @@ namespace LIBC_NAMESPACE_DECL { -LLVM_LIBC_FUNCTION(bool, iswalpha, (wint_t c)) { return internal::iswalpha(c); } +LLVM_LIBC_FUNCTION(int, iswalpha, (wint_t c)) { return internal::iswalpha(c); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/wctype/iswalpha.h b/libc/src/wctype/iswalpha.h index 681fc6b..0353388 100644 --- a/libc/src/wctype/iswalpha.h +++ b/libc/src/wctype/iswalpha.h @@ -14,7 +14,7 @@ namespace LIBC_NAMESPACE_DECL { -bool iswalpha(wint_t c); +int iswalpha(wint_t c); } // namespace LIBC_NAMESPACE_DECL |