Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions libc/include/llvm-libc-macros/fenv-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
#define FE_INVALID 0x4
#define FE_OVERFLOW 0x8
#define FE_UNDERFLOW 0x10
#define __FE_DENORM 0x20
#define FE_DENORM 0x20
#define FE_ALL_EXCEPT \
(FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
(FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | \
FE_DENORM)

#define FE_DOWNWARD 0x400
#define FE_TONEAREST 0
Expand Down
36 changes: 30 additions & 6 deletions libc/src/__support/CPP/bit.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ namespace cpp {
#define LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE
#endif

template <unsigned N>
LIBC_INLINE static void inline_copy(const char *from, char *to) {
#if __has_builtin(__builtin_memcpy_inline)
__builtin_memcpy_inline(to, from, N);
#else
for (unsigned i = 0; i < N; ++i)
to[i] = from[i];
#endif // __has_builtin(__builtin_memcpy_inline)
}

// This implementation of bit_cast requires trivially-constructible To, to avoid
// UB in the implementation.
template <typename To, typename From>
Expand All @@ -43,16 +53,30 @@ bit_cast(const From &from) {
To to{};
char *dst = reinterpret_cast<char *>(&to);
const char *src = reinterpret_cast<const char *>(&from);
#if __has_builtin(__builtin_memcpy_inline)
__builtin_memcpy_inline(dst, src, sizeof(To));
#else
for (unsigned i = 0; i < sizeof(To); ++i)
dst[i] = src[i];
#endif // __has_builtin(__builtin_memcpy_inline)
inline_copy<sizeof(From)>(src, dst);
return to;
#endif // __has_builtin(__builtin_bit_cast)
}

// The following simple bit copy from a smaller type to maybe-larger type.
template <typename To, typename From>
LIBC_INLINE constexpr cpp::enable_if_t<
(sizeof(To) >= sizeof(From)) &&
cpp::is_trivially_constructible<To>::value &&
cpp::is_trivially_copyable<To>::value &&
cpp::is_trivially_copyable<From>::value,
void>
bit_copy(const From &from, To &to) {
MSAN_UNPOISON(&from, sizeof(From));
if constexpr (sizeof(To) == sizeof(From)) {
to = bit_cast<To>(from);
} else {
char *dst = reinterpret_cast<char *>(&to);
const char *src = reinterpret_cast<const char *>(&from);
inline_copy<sizeof(From)>(src, dst);
}
}

template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>,
bool>
Expand Down
8 changes: 1 addition & 7 deletions libc/src/__support/FPUtil/FEnvImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
// the dummy implementations below. Once a proper x86_64 darwin fenv is set up,
// the apple condition here should be removed.
// TODO: fully support fenv for MSVC.
#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__) && \
!defined(LIBC_COMPILER_IS_MSVC)
#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__)
#include "x86_64/FEnvImpl.h"
#elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP) && \
!defined(LIBC_COMPILER_IS_MSVC)
Expand Down Expand Up @@ -110,12 +109,7 @@ raise_except_if_required([[maybe_unused]] int excepts) {
} else {
#ifndef LIBC_MATH_HAS_NO_EXCEPT
if (math_errhandling & MATH_ERREXCEPT)
#ifdef LIBC_TARGET_ARCH_IS_X86_64
return raise_except</*SKIP_X87_FPU*/ true>(excepts);
#else // !LIBC_TARGET_ARCH_IS_X86
return raise_except(excepts);
#endif // LIBC_TARGET_ARCH_IS_X86

#endif // LIBC_MATH_HAS_NO_EXCEPT
return 0;
}
Expand Down
Loading
Loading