Skip to content

Commit d8dfeae

Browse files
committed
[libc][fenv] Refactor x86 fenv implementations to make it work for various fenv_t.
1 parent e876540 commit d8dfeae

File tree

9 files changed

+972
-613
lines changed

9 files changed

+972
-613
lines changed

libc/src/__support/CPP/bit.h

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ namespace cpp {
2626
#define LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE
2727
#endif
2828

29+
template <unsigned N>
30+
LIBC_INLINE static void inline_copy(const char *from, char *to) {
31+
#if __has_builtin(__builtin_memcpy_inline)
32+
__builtin_memcpy_inline(to, from, N);
33+
#else
34+
for (unsigned i = 0; i < N; ++i)
35+
to[i] = from[i];
36+
#endif // __has_builtin(__builtin_memcpy_inline)
37+
}
38+
2939
// This implementation of bit_cast requires trivially-constructible To, to avoid
3040
// UB in the implementation.
3141
template <typename To, typename From>
@@ -43,16 +53,30 @@ bit_cast(const From &from) {
4353
To to{};
4454
char *dst = reinterpret_cast<char *>(&to);
4555
const char *src = reinterpret_cast<const char *>(&from);
46-
#if __has_builtin(__builtin_memcpy_inline)
47-
__builtin_memcpy_inline(dst, src, sizeof(To));
48-
#else
49-
for (unsigned i = 0; i < sizeof(To); ++i)
50-
dst[i] = src[i];
51-
#endif // __has_builtin(__builtin_memcpy_inline)
56+
inline_copy<sizeof(From)>(src, dst);
5257
return to;
5358
#endif // __has_builtin(__builtin_bit_cast)
5459
}
5560

61+
// The following simple bit copy from a smaller type to maybe-larger type.
62+
template <typename To, typename From>
63+
LIBC_INLINE constexpr cpp::enable_if_t<
64+
(sizeof(To) >= sizeof(From)) &&
65+
cpp::is_trivially_constructible<To>::value &&
66+
cpp::is_trivially_copyable<To>::value &&
67+
cpp::is_trivially_copyable<From>::value,
68+
void>
69+
bit_copy(const From &from, To &to) {
70+
MSAN_UNPOISON(&from, sizeof(From));
71+
if constexpr (sizeof(To) == sizeof(From)) {
72+
to = bit_cast<To>(from);
73+
} else {
74+
char *dst = reinterpret_cast<char *>(&to);
75+
const char *src = reinterpret_cast<const char *>(&from);
76+
inline_copy<sizeof(From)>(src, dst);
77+
}
78+
}
79+
5680
template <typename T>
5781
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>,
5882
bool>

libc/src/__support/FPUtil/FEnvImpl.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131
// the dummy implementations below. Once a proper x86_64 darwin fenv is set up,
3232
// the apple condition here should be removed.
3333
// TODO: fully support fenv for MSVC.
34-
#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__) && \
35-
!defined(LIBC_COMPILER_IS_MSVC)
34+
#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__)
3635
#include "x86_64/FEnvImpl.h"
3736
#elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP) && \
3837
!defined(LIBC_COMPILER_IS_MSVC)
@@ -110,12 +109,7 @@ raise_except_if_required([[maybe_unused]] int excepts) {
110109
} else {
111110
#ifndef LIBC_MATH_HAS_NO_EXCEPT
112111
if (math_errhandling & MATH_ERREXCEPT)
113-
#ifdef LIBC_TARGET_ARCH_IS_X86_64
114-
return raise_except</*SKIP_X87_FPU*/ true>(excepts);
115-
#else // !LIBC_TARGET_ARCH_IS_X86
116112
return raise_except(excepts);
117-
#endif // LIBC_TARGET_ARCH_IS_X86
118-
119113
#endif // LIBC_MATH_HAS_NO_EXCEPT
120114
return 0;
121115
}

0 commit comments

Comments
 (0)