Skip to content

Commit 5621fa1

Browse files
authored
[libc] Some more MSVC compatibility in src/__support. (#158108)
1 parent 2508851 commit 5621fa1

File tree

7 files changed

+66
-15
lines changed

7 files changed

+66
-15
lines changed

libc/src/__support/CPP/bit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ bit_cast(const From &from) {
3939
#if __has_builtin(__builtin_bit_cast)
4040
return __builtin_bit_cast(To, from);
4141
#else
42-
To to;
42+
To to{};
4343
char *dst = reinterpret_cast<char *>(&to);
4444
const char *src = reinterpret_cast<const char *>(&from);
4545
#if __has_builtin(__builtin_memcpy_inline)

libc/src/__support/CPP/type_traits/is_destructible.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace LIBC_NAMESPACE_DECL {
2222
namespace cpp {
2323

2424
// is_destructible
25-
#if __has_builtin(__is_destructible)
25+
#if __has_builtin(__is_destructible) || defined(LIBC_COMPILER_IS_MSVC)
2626
template <typename T>
2727
struct is_destructible : bool_constant<__is_destructible(T)> {};
2828
#else

libc/src/__support/FPUtil/FEnvImpl.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "src/__support/macros/config.h"
1919
#include "src/__support/macros/optimization.h"
2020
#include "src/__support/macros/properties/architectures.h"
21+
#include "src/__support/macros/properties/compiler.h"
2122

2223
#if defined(LIBC_TARGET_ARCH_IS_AARCH64) && defined(__ARM_FP)
2324
#if defined(__APPLE__)
@@ -29,9 +30,12 @@
2930
// The extra !defined(APPLE) condition is to cause x86_64 MacOS builds to use
3031
// the dummy implementations below. Once a proper x86_64 darwin fenv is set up,
3132
// the apple condition here should be removed.
32-
#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__)
33+
// TODO: fully support fenv for MSVC.
34+
#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__) && \
35+
!defined(LIBC_COMPILER_IS_MSVC)
3336
#include "x86_64/FEnvImpl.h"
34-
#elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP)
37+
#elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP) && \
38+
!defined(LIBC_COMPILER_IS_MSVC)
3539
#include "arm/FEnvImpl.h"
3640
#elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) && defined(__riscv_flen)
3741
#include "riscv/FEnvImpl.h"

libc/src/__support/FPUtil/FPBits.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -789,16 +789,16 @@ struct FPRep : public FPRepImpl<fp_type, FPRep<fp_type>> {
789789
// Returns the FPType corresponding to C++ type T on the host.
790790
template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
791791
using UnqualT = cpp::remove_cv_t<T>;
792-
if constexpr (cpp::is_same_v<UnqualT, float> && __FLT_MANT_DIG__ == 24)
792+
if constexpr (cpp::is_same_v<UnqualT, float> && FLT_MANT_DIG == 24)
793793
return FPType::IEEE754_Binary32;
794-
else if constexpr (cpp::is_same_v<UnqualT, double> && __DBL_MANT_DIG__ == 53)
794+
else if constexpr (cpp::is_same_v<UnqualT, double> && DBL_MANT_DIG == 53)
795795
return FPType::IEEE754_Binary64;
796796
else if constexpr (cpp::is_same_v<UnqualT, long double>) {
797-
if constexpr (__LDBL_MANT_DIG__ == 53)
797+
if constexpr (LDBL_MANT_DIG == 53)
798798
return FPType::IEEE754_Binary64;
799-
else if constexpr (__LDBL_MANT_DIG__ == 64)
799+
else if constexpr (LDBL_MANT_DIG == 64)
800800
return FPType::X86_Binary80;
801-
else if constexpr (__LDBL_MANT_DIG__ == 113)
801+
else if constexpr (LDBL_MANT_DIG == 113)
802802
return FPType::IEEE754_Binary128;
803803
}
804804
#if defined(LIBC_TYPES_HAS_FLOAT16)

libc/src/__support/endian_internal.h

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,49 @@
1616
namespace LIBC_NAMESPACE_DECL {
1717

1818
// We rely on compiler preprocessor defines to allow for cross compilation.
19+
#ifdef LIBC_COMPILER_IS_MSVC
20+
#define __BYTE_ORDER__ 0
21+
#define __ORDER_LITTLE_ENDIAN__ 0
22+
#define __ORDER_BIG_ENDIAN__ 1
23+
#else // !LIBC_COMPILER_IS_MSVC
1924
#if !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__) || \
2025
!defined(__ORDER_BIG_ENDIAN__)
2126
#error "Missing preprocessor definitions for endianness detection."
2227
#endif
28+
#endif // LIBC_COMPILER_IS_MSVC
2329

2430
namespace internal {
2531

32+
template <typename T> LIBC_INLINE T byte_swap(T value);
33+
34+
template <> LIBC_INLINE uint16_t byte_swap<uint16_t>(uint16_t value) {
35+
#if __has_builtin(__builtin_bswap16)
36+
return __builtin_bswap16(value);
37+
#else
38+
return (v << 8) | (v >> 8);
39+
#endif // __builtin_bswap16
40+
}
41+
42+
template <> LIBC_INLINE uint32_t byte_swap<uint32_t>(uint32_t value) {
43+
#if __has_builtin(__builtin_bswap32)
44+
return __builtin_bswap32(value);
45+
#else
46+
return byte_swap<uint16_t>(static_cast<uint16>(v >> 16)) ||
47+
(static_cast<uint32_t>(byte_swap<uint16_t>(static_cast<uint16_t>(v)))
48+
<< 16);
49+
#endif // __builtin_bswap64
50+
}
51+
52+
template <> LIBC_INLINE uint64_t byte_swap<uint64_t>(uint64_t value) {
53+
#if __has_builtin(__builtin_bswap64)
54+
return __builtin_bswap64(value);
55+
#else
56+
return byte_swap<uint32_t>(static_cast<uint32>(v >> 32)) ||
57+
(static_cast<uint64_t>(byte_swap<uint32_t>(static_cast<uint32_t>(v)))
58+
<< 32);
59+
#endif // __builtin_bswap64
60+
}
61+
2662
// Converts uint8_t, uint16_t, uint32_t, uint64_t to its big or little endian
2763
// counterpart.
2864
// We use explicit template specialization:
@@ -53,7 +89,7 @@ template <>
5389
template <>
5490
LIBC_INLINE uint16_t
5591
Endian<__ORDER_LITTLE_ENDIAN__>::to_big_endian<uint16_t>(uint16_t v) {
56-
return __builtin_bswap16(v);
92+
return byte_swap<uint16_t>(v);
5793
}
5894
template <>
5995
template <>
@@ -65,7 +101,7 @@ template <>
65101
template <>
66102
LIBC_INLINE uint32_t
67103
Endian<__ORDER_LITTLE_ENDIAN__>::to_big_endian<uint32_t>(uint32_t v) {
68-
return __builtin_bswap32(v);
104+
return byte_swap<uint32_t>(v);
69105
}
70106
template <>
71107
template <>
@@ -77,7 +113,7 @@ template <>
77113
template <>
78114
LIBC_INLINE uint64_t
79115
Endian<__ORDER_LITTLE_ENDIAN__>::to_big_endian<uint64_t>(uint64_t v) {
80-
return __builtin_bswap64(v);
116+
return byte_swap<uint64_t>(v);
81117
}
82118
template <>
83119
template <>
@@ -109,7 +145,7 @@ template <>
109145
template <>
110146
LIBC_INLINE uint16_t
111147
Endian<__ORDER_BIG_ENDIAN__>::to_little_endian<uint16_t>(uint16_t v) {
112-
return __builtin_bswap16(v);
148+
return byte_swap<uint16_t>(v);
113149
}
114150
template <>
115151
template <>
@@ -121,7 +157,7 @@ template <>
121157
template <>
122158
LIBC_INLINE uint32_t
123159
Endian<__ORDER_BIG_ENDIAN__>::to_little_endian<uint32_t>(uint32_t v) {
124-
return __builtin_bswap32(v);
160+
return byte_swap<uint32_t>(v);
125161
}
126162
template <>
127163
template <>
@@ -133,7 +169,7 @@ template <>
133169
template <>
134170
LIBC_INLINE uint64_t
135171
Endian<__ORDER_BIG_ENDIAN__>::to_little_endian<uint64_t>(uint64_t v) {
136-
return __builtin_bswap64(v);
172+
return byte_swap<uint64_t>(v);
137173
}
138174

139175
} // namespace internal

libc/src/__support/macros/config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#endif
4545

4646
#define __builtin_expect(value, expectation) (value)
47+
#define __builtin_unreachable() __assume(0)
4748

4849
#endif // LIBC_COMPILER_IS_MSVC
4950

libc/src/__support/math_extras.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,23 @@ mask_leading_zeros() {
5555
// Returns whether 'a + b' overflows, the result is stored in 'res'.
5656
template <typename T>
5757
[[nodiscard]] LIBC_INLINE constexpr bool add_overflow(T a, T b, T &res) {
58+
#if __has_builtin(__builtin_add_overflow)
5859
return __builtin_add_overflow(a, b, &res);
60+
#else
61+
res = a + b;
62+
return (res < a) || (res < b);
63+
#endif // __builtin_add_overflow
5964
}
6065

6166
// Returns whether 'a - b' overflows, the result is stored in 'res'.
6267
template <typename T>
6368
[[nodiscard]] LIBC_INLINE constexpr bool sub_overflow(T a, T b, T &res) {
69+
#if __has_builtin(__builtin_sub_overflow)
6470
return __builtin_sub_overflow(a, b, &res);
71+
#else
72+
res = a - b;
73+
return (res > a);
74+
#endif // __builtin_sub_overflow
6575
}
6676

6777
#define RETURN_IF(TYPE, BUILTIN) \

0 commit comments

Comments
 (0)