aboutsummaryrefslogtreecommitdiff
path: root/libc/src
diff options
context:
space:
mode:
Diffstat (limited to 'libc/src')
-rw-r--r--libc/src/__support/CMakeLists.txt12
-rw-r--r--libc/src/__support/CPP/CMakeLists.txt3
-rw-r--r--libc/src/__support/CPP/bit.h3
-rw-r--r--libc/src/__support/CPP/functional.h3
-rw-r--r--libc/src/__support/FPUtil/CMakeLists.txt8
-rw-r--r--libc/src/__support/FPUtil/FEnvImpl.h51
-rw-r--r--libc/src/__support/FPUtil/FPBits.h3
-rw-r--r--libc/src/__support/FPUtil/NormalFloat.h3
-rw-r--r--libc/src/__support/FPUtil/aarch64/FEnvImpl.h2
-rw-r--r--libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h2
-rw-r--r--libc/src/__support/FPUtil/arm/FEnvImpl.h2
-rw-r--r--libc/src/__support/FPUtil/bfloat16.h28
-rw-r--r--libc/src/__support/FPUtil/generic/add_sub.h9
-rw-r--r--libc/src/__support/FPUtil/riscv/FEnvImpl.h3
-rw-r--r--libc/src/__support/FPUtil/rounding_mode.h67
-rw-r--r--libc/src/__support/FPUtil/x86_64/FEnvImpl.h3
-rw-r--r--libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h3
-rw-r--r--libc/src/__support/File/CMakeLists.txt7
-rw-r--r--libc/src/__support/File/file.h2
-rw-r--r--libc/src/__support/File/linux/CMakeLists.txt9
-rw-r--r--libc/src/__support/File/linux/lseekImpl.h2
-rw-r--r--libc/src/__support/GPU/CMakeLists.txt1
-rw-r--r--libc/src/__support/GPU/allocator.cpp138
-rw-r--r--libc/src/__support/GPU/allocator.h2
-rw-r--r--libc/src/__support/HashTable/CMakeLists.txt2
-rw-r--r--libc/src/__support/HashTable/bitmask.h2
-rw-r--r--libc/src/__support/HashTable/table.h2
-rw-r--r--libc/src/__support/RPC/rpc_server.h6
-rw-r--r--libc/src/__support/arg_list.h2
-rw-r--r--libc/src/__support/big_int.h2
-rw-r--r--libc/src/__support/block.h3
-rw-r--r--libc/src/__support/blockstore.h2
-rw-r--r--libc/src/__support/detailed_powers_of_ten.h3
-rw-r--r--libc/src/__support/endian_internal.h5
-rw-r--r--libc/src/__support/fixed_point/CMakeLists.txt1
-rw-r--r--libc/src/__support/fixed_point/fx_rep.h3
-rw-r--r--libc/src/__support/float_to_string.h3
-rw-r--r--libc/src/__support/hash.h2
-rw-r--r--libc/src/__support/high_precision_decimal.h2
-rw-r--r--libc/src/__support/integer_literals.h2
-rw-r--r--libc/src/__support/integer_to_string.h3
-rw-r--r--libc/src/__support/macros/CMakeLists.txt1
-rw-r--r--libc/src/__support/macros/null_check.h3
-rw-r--r--libc/src/__support/macros/properties/CMakeLists.txt1
-rw-r--r--libc/src/__support/macros/properties/types.h5
-rw-r--r--libc/src/__support/macros/sanitizer.h10
-rw-r--r--libc/src/__support/math/CMakeLists.txt63
-rw-r--r--libc/src/__support/math/acos.h2
-rw-r--r--libc/src/__support/math/acosf.h2
-rw-r--r--libc/src/__support/math/acosf16.h2
-rw-r--r--libc/src/__support/math/acoshf.h2
-rw-r--r--libc/src/__support/math/acoshf16.h8
-rw-r--r--libc/src/__support/math/acospif16.h147
-rw-r--r--libc/src/__support/math/asin.h297
-rw-r--r--libc/src/__support/math/asinf.h175
-rw-r--r--libc/src/__support/math/erff.h2
-rw-r--r--libc/src/__support/math/exp.h16
-rw-r--r--libc/src/__support/math/exp10.h19
-rw-r--r--libc/src/__support/math/exp10_float16_constants.h2
-rw-r--r--libc/src/__support/math/exp10f.h2
-rw-r--r--libc/src/__support/math/exp10f16.h2
-rw-r--r--libc/src/__support/math/exp10f16_utils.h3
-rw-r--r--libc/src/__support/math/exp10f_utils.h2
-rw-r--r--libc/src/__support/math/exp_utils.h4
-rw-r--r--libc/src/__support/math/expf.h2
-rw-r--r--libc/src/__support/math/expf16.h2
-rw-r--r--libc/src/__support/math/expf16_utils.h3
-rw-r--r--libc/src/__support/math/frexpf.h2
-rw-r--r--libc/src/__support/math/frexpf128.h2
-rw-r--r--libc/src/__support/math/frexpf16.h2
-rw-r--r--libc/src/__support/math/ldexpf.h2
-rw-r--r--libc/src/__support/math/ldexpf128.h2
-rw-r--r--libc/src/__support/math/ldexpf16.h2
-rw-r--r--libc/src/__support/ryu_constants.h2
-rw-r--r--libc/src/__support/ryu_long_double_constants.h2
-rw-r--r--libc/src/__support/str_to_float.h3
-rw-r--r--libc/src/__support/threads/CMakeLists.txt2
-rw-r--r--libc/src/__support/threads/CndVar.h3
-rw-r--r--libc/src/__support/threads/linux/CMakeLists.txt3
-rw-r--r--libc/src/__support/threads/linux/futex_word.h2
-rw-r--r--libc/src/__support/threads/linux/thread.cpp2
-rw-r--r--libc/src/__support/threads/thread.h2
-rw-r--r--libc/src/__support/wchar/CMakeLists.txt20
-rw-r--r--libc/src/__support/wchar/mbstate.h2
-rw-r--r--libc/src/__support/wchar/wcsnrtombs.h69
-rw-r--r--libc/src/arpa/inet/CMakeLists.txt4
-rw-r--r--libc/src/arpa/inet/htonl.h2
-rw-r--r--libc/src/arpa/inet/htons.h2
-rw-r--r--libc/src/arpa/inet/ntohl.h2
-rw-r--r--libc/src/arpa/inet/ntohs.h2
-rw-r--r--libc/src/compiler/generic/CMakeLists.txt1
-rw-r--r--libc/src/compiler/generic/__stack_chk_fail.cpp2
-rw-r--r--libc/src/inttypes/CMakeLists.txt2
-rw-r--r--libc/src/inttypes/strtoimax.h2
-rw-r--r--libc/src/inttypes/strtoumax.h2
-rw-r--r--libc/src/link/CMakeLists.txt2
-rw-r--r--libc/src/math/generic/CMakeLists.txt32
-rw-r--r--libc/src/math/generic/acospif16.cpp122
-rw-r--r--libc/src/math/generic/asin.cpp15
-rw-r--r--libc/src/math/generic/asinf.cpp155
-rw-r--r--libc/src/math/generic/expxf16.h3
-rw-r--r--libc/src/math/generic/range_reduction_double_common.h2
-rw-r--r--libc/src/pthread/CMakeLists.txt1
-rw-r--r--libc/src/pthread/pthread_attr_setstack.cpp2
-rw-r--r--libc/src/sched/linux/CMakeLists.txt1
-rw-r--r--libc/src/sched/linux/sched_getaffinity.cpp2
-rw-r--r--libc/src/setjmp/aarch64/CMakeLists.txt2
-rw-r--r--libc/src/setjmp/arm/CMakeLists.txt2
-rw-r--r--libc/src/setjmp/darwin/CMakeLists.txt2
-rw-r--r--libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp2
-rw-r--r--libc/src/setjmp/linux/CMakeLists.txt2
-rw-r--r--libc/src/setjmp/linux/sigsetjmp_epilogue.cpp2
-rw-r--r--libc/src/setjmp/riscv/CMakeLists.txt2
-rw-r--r--libc/src/setjmp/sigsetjmp.h2
-rw-r--r--libc/src/setjmp/sigsetjmp_epilogue.h4
-rw-r--r--libc/src/setjmp/x86_64/CMakeLists.txt2
-rw-r--r--libc/src/spawn/CMakeLists.txt1
-rw-r--r--libc/src/spawn/file_actions.h2
-rw-r--r--libc/src/stdio/gpu/CMakeLists.txt1
-rw-r--r--libc/src/stdio/gpu/fgets.cpp3
-rw-r--r--libc/src/stdio/printf_core/CMakeLists.txt2
-rw-r--r--libc/src/stdlib/CMakeLists.txt9
-rw-r--r--libc/src/stdlib/a64l.cpp3
-rw-r--r--libc/src/stdlib/bsearch.cpp2
-rw-r--r--libc/src/stdlib/l64a.cpp3
-rw-r--r--libc/src/stdlib/qsort.cpp3
-rw-r--r--libc/src/stdlib/qsort_data.h3
-rw-r--r--libc/src/stdlib/qsort_r.cpp3
-rw-r--r--libc/src/stdlib/quick_sort.h3
-rw-r--r--libc/src/string/CMakeLists.txt1
-rw-r--r--libc/src/string/allocating_string_utils.h6
-rw-r--r--libc/src/string/memory_utils/CMakeLists.txt1
-rw-r--r--libc/src/string/memory_utils/op_generic.h3
-rw-r--r--libc/src/string/memory_utils/utils.h2
-rw-r--r--libc/src/string/memory_utils/x86_64/inline_memcpy.h2
-rw-r--r--libc/src/string/string_utils.h3
-rw-r--r--libc/src/sys/stat/linux/CMakeLists.txt1
-rw-r--r--libc/src/sys/stat/linux/kernel_statx.h2
-rw-r--r--libc/src/time/CMakeLists.txt4
-rw-r--r--libc/src/time/linux/CMakeLists.txt1
-rw-r--r--libc/src/time/linux/nanosleep.cpp2
-rw-r--r--libc/src/time/strftime_core/CMakeLists.txt1
-rw-r--r--libc/src/time/strftime_core/core_structs.h3
-rw-r--r--libc/src/time/time_constants.h2
-rw-r--r--libc/src/time/time_utils.cpp3
-rw-r--r--libc/src/time/time_utils.h3
-rw-r--r--libc/src/unistd/linux/CMakeLists.txt4
-rw-r--r--libc/src/unistd/linux/ftruncate.cpp2
-rw-r--r--libc/src/unistd/linux/pread.cpp2
-rw-r--r--libc/src/unistd/linux/pwrite.cpp2
-rw-r--r--libc/src/unistd/linux/truncate.cpp2
-rw-r--r--libc/src/wchar/CMakeLists.txt100
-rw-r--r--libc/src/wchar/mblen.cpp35
-rw-r--r--libc/src/wchar/mblen.h21
-rw-r--r--libc/src/wchar/mbrlen.cpp37
-rw-r--r--libc/src/wchar/mbrlen.h22
-rw-r--r--libc/src/wchar/mbsinit.cpp26
-rw-r--r--libc/src/wchar/mbsinit.h22
-rw-r--r--libc/src/wchar/wcsdup.cpp27
-rw-r--r--libc/src/wchar/wcsdup.h21
-rw-r--r--libc/src/wchar/wcsnrtombs.cpp40
-rw-r--r--libc/src/wchar/wcsnrtombs.h24
-rw-r--r--libc/src/wchar/wcsrtombs.cpp40
-rw-r--r--libc/src/wchar/wcsrtombs.h24
-rw-r--r--libc/src/wchar/wcstombs.cpp38
-rw-r--r--libc/src/wchar/wcstombs.h22
166 files changed, 1672 insertions, 609 deletions
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index 37a27cc..2196d9e 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -15,6 +15,7 @@ add_header_library(
HDRS
block.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.algorithm
libc.src.__support.CPP.limits
libc.src.__support.CPP.new
@@ -86,6 +87,7 @@ add_header_library(
blockstore.h
DEPENDS
.libc_assert
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.new
)
@@ -97,6 +99,8 @@ add_header_library(
macros/properties/architectures.h
macros/attributes.h
macros/config.h
+ DEPENDS
+ libc.hdr.stdint_proxy
)
add_header_library(
@@ -199,6 +203,7 @@ add_header_library(
integer_to_string.h
DEPENDS
.big_int
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.CPP.algorithm
libc.src.__support.CPP.limits
@@ -215,6 +220,7 @@ add_header_library(
ryu_long_double_constants.h
DEPENDS
.libc_assert
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.type_traits
libc.src.__support.FPUtil.fp_bits
libc.src.__support.common
@@ -226,6 +232,7 @@ add_header_library(
high_precision_decimal.h
DEPENDS
.str_to_integer
+ libc.hdr.stdint_proxy
)
add_header_library(
@@ -240,6 +247,7 @@ add_header_library(
.str_to_num_result
.uint128
libc.hdr.errno_macros
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
@@ -257,6 +265,7 @@ add_header_library(
integer_literals.h
DEPENDS
.uint128
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.limits
)
@@ -290,6 +299,7 @@ add_header_library(
HDRS
arg_list.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.common
)
@@ -329,6 +339,7 @@ add_header_library(
DEPENDS
.math_extras
.number_pair
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.array
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
@@ -361,6 +372,7 @@ add_header_library(
hash.h
DEPENDS
.uint128
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.macros.attributes
diff --git a/libc/src/__support/CPP/CMakeLists.txt b/libc/src/__support/CPP/CMakeLists.txt
index d2ba00a..8b65a8839 100644
--- a/libc/src/__support/CPP/CMakeLists.txt
+++ b/libc/src/__support/CPP/CMakeLists.txt
@@ -17,6 +17,7 @@ add_header_library(
DEPENDS
.limits
.type_traits
+ libc.hdr.stdint_proxy
libc.src.__support.macros.attributes
libc.src.__support.macros.sanitizer
)
@@ -39,6 +40,8 @@ add_header_library(
functional
HDRS
functional.h
+ DEPENDS
+ libc.hdr.stdint_proxy
)
add_header_library(
diff --git a/libc/src/__support/CPP/bit.h b/libc/src/__support/CPP/bit.h
index e491f3e..df1b177 100644
--- a/libc/src/__support/CPP/bit.h
+++ b/libc/src/__support/CPP/bit.h
@@ -11,14 +11,13 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_BIT_H
#define LLVM_LIBC_SRC___SUPPORT_CPP_BIT_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/limits.h" // numeric_limits
#include "src/__support/CPP/type_traits.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/sanitizer.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace cpp {
diff --git a/libc/src/__support/CPP/functional.h b/libc/src/__support/CPP/functional.h
index 50cfa256..5c43d22 100644
--- a/libc/src/__support/CPP/functional.h
+++ b/libc/src/__support/CPP/functional.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_FUNCTIONAL_H
#define LLVM_LIBC_SRC___SUPPORT_CPP_FUNCTIONAL_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/type_traits/enable_if.h"
#include "src/__support/CPP/type_traits/is_convertible.h"
#include "src/__support/CPP/type_traits/is_same.h"
@@ -19,8 +20,6 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace cpp {
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index f157d90..6e447fc 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -6,6 +6,8 @@ add_header_library(
libc.hdr.types.fenv_t
libc.hdr.fenv_macros
libc.hdr.math_macros
+ libc.hdr.stdint_proxy
+ libc.src.__support.CPP.type_traits
libc.src.__support.macros.attributes
libc.src.errno.errno
)
@@ -16,6 +18,7 @@ add_header_library(
rounding_mode.h
DEPENDS
libc.hdr.fenv_macros
+ libc.src.__support.CPP.type_traits
libc.src.__support.macros.attributes
libc.src.__support.macros.properties.architectures
libc.src.__support.macros.sanitizer
@@ -27,6 +30,7 @@ add_header_library(
HDRS
FPBits.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
@@ -71,6 +75,7 @@ add_header_library(
NormalFloat.h
DEPENDS
.fp_bits
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.type_traits
libc.src.__support.common
)
@@ -247,6 +252,7 @@ add_header_library(
.nearest_integer_operations
.normal_float
libc.hdr.math_macros
+ libc.hdr.stdint_proxy
libc.src.errno.errno
libc.src.__support.common
libc.src.__support.CPP.bit
@@ -274,7 +280,9 @@ add_header_library(
bfloat16.h
DEPENDS
.cast
+ .comparison_operations
.dyadic_float
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
libc.src.__support.macros.config
diff --git a/libc/src/__support/FPUtil/FEnvImpl.h b/libc/src/__support/FPUtil/FEnvImpl.h
index 7691088..7bd5643 100644
--- a/libc/src/__support/FPUtil/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/FEnvImpl.h
@@ -12,6 +12,7 @@
#include "hdr/fenv_macros.h"
#include "hdr/math_macros.h"
#include "hdr/types/fenv_t.h"
+#include "src/__support/CPP/type_traits.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h"
@@ -72,40 +73,58 @@ LIBC_INLINE int set_env(const fenv_t *) { return 0; }
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
-LIBC_INLINE static int clear_except_if_required([[maybe_unused]] int excepts) {
+LIBC_INLINE static constexpr int
+clear_except_if_required([[maybe_unused]] int excepts) {
+ if (cpp::is_constant_evaluated()) {
+ return 0;
+ } else {
#ifndef LIBC_MATH_HAS_NO_EXCEPT
- if (math_errhandling & MATH_ERREXCEPT)
- return clear_except(excepts);
+ if (math_errhandling & MATH_ERREXCEPT)
+ return clear_except(excepts);
#endif // LIBC_MATH_HAS_NO_EXCEPT
- return 0;
+ return 0;
+ }
}
-LIBC_INLINE static int set_except_if_required([[maybe_unused]] int excepts) {
+LIBC_INLINE static constexpr int
+set_except_if_required([[maybe_unused]] int excepts) {
+ if (cpp::is_constant_evaluated()) {
+ return 0;
+ } else {
#ifndef LIBC_MATH_HAS_NO_EXCEPT
- if (math_errhandling & MATH_ERREXCEPT)
- return set_except(excepts);
+ if (math_errhandling & MATH_ERREXCEPT)
+ return set_except(excepts);
#endif // LIBC_MATH_HAS_NO_EXCEPT
- return 0;
+ return 0;
+ }
}
-LIBC_INLINE static int raise_except_if_required([[maybe_unused]] int excepts) {
+LIBC_INLINE static constexpr int
+raise_except_if_required([[maybe_unused]] int excepts) {
+ if (cpp::is_constant_evaluated()) {
+ return 0;
+ } else {
#ifndef LIBC_MATH_HAS_NO_EXCEPT
- if (math_errhandling & MATH_ERREXCEPT)
+ if (math_errhandling & MATH_ERREXCEPT)
#ifdef LIBC_TARGET_ARCH_IS_X86_64
- return raise_except</*SKIP_X87_FPU*/ true>(excepts);
+ return raise_except</*SKIP_X87_FPU*/ true>(excepts);
#else // !LIBC_TARGET_ARCH_IS_X86
- return raise_except(excepts);
+ return raise_except(excepts);
#endif // LIBC_TARGET_ARCH_IS_X86
#endif // LIBC_MATH_HAS_NO_EXCEPT
- return 0;
+ return 0;
+ }
}
-LIBC_INLINE static void set_errno_if_required([[maybe_unused]] int err) {
+LIBC_INLINE static constexpr void
+set_errno_if_required([[maybe_unused]] int err) {
+ if (!cpp::is_constant_evaluated()) {
#ifndef LIBC_MATH_HAS_NO_ERRNO
- if (math_errhandling & MATH_ERRNO)
- libc_errno = err;
+ if (math_errhandling & MATH_ERRNO)
+ libc_errno = err;
#endif // LIBC_MATH_HAS_NO_ERRNO
+ }
}
} // namespace fputil
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 9e21136..2f695c1 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -15,6 +15,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
@@ -26,8 +27,6 @@
#include "src/__support/sign.h" // Sign
#include "src/__support/uint128.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
diff --git a/libc/src/__support/FPUtil/NormalFloat.h b/libc/src/__support/FPUtil/NormalFloat.h
index a2f285f..b30e36f 100644
--- a/libc/src/__support/FPUtil/NormalFloat.h
+++ b/libc/src/__support/FPUtil/NormalFloat.h
@@ -11,12 +11,11 @@
#include "FPBits.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
diff --git a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
index 914155a..18182ed 100644
--- a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
@@ -18,9 +18,9 @@
#endif
#include <arm_acle.h>
-#include <stdint.h>
#include "hdr/fenv_macros.h"
+#include "hdr/stdint_proxy.h"
#include "hdr/types/fenv_t.h"
#include "src/__support/FPUtil/FPBits.h"
diff --git a/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h b/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
index dcce76b..a2066d1 100644
--- a/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
+++ b/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
@@ -18,9 +18,9 @@
#endif
#include <arm_acle.h>
-#include <stdint.h>
#include "hdr/fenv_macros.h"
+#include "hdr/stdint_proxy.h"
#include "hdr/types/fenv_t.h"
#include "src/__support/FPUtil/FPBits.h"
diff --git a/libc/src/__support/FPUtil/arm/FEnvImpl.h b/libc/src/__support/FPUtil/arm/FEnvImpl.h
index aaf37c0..64ab4a9 100644
--- a/libc/src/__support/FPUtil/arm/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/arm/FEnvImpl.h
@@ -10,11 +10,11 @@
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_ARM_FENVIMPL_H
#include "hdr/fenv_macros.h"
+#include "hdr/stdint_proxy.h"
#include "hdr/types/fenv_t.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/macros/attributes.h" // For LIBC_INLINE
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index bc0b8b2..fa45d73 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -9,15 +9,15 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_BFLOAT16_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_BFLOAT16_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/comparison_operations.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/types.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
@@ -57,6 +57,30 @@ struct BFloat16 {
uint32_t x_bits = static_cast<uint32_t>(bits) << 16U;
return cpp::bit_cast<float>(x_bits);
}
+
+ LIBC_INLINE bool operator==(BFloat16 other) const {
+ return fputil::equals(*this, other);
+ }
+
+ LIBC_INLINE bool operator!=(BFloat16 other) const {
+ return !fputil::equals(*this, other);
+ }
+
+ LIBC_INLINE bool operator<(BFloat16 other) const {
+ return fputil::less_than(*this, other);
+ }
+
+ LIBC_INLINE bool operator<=(BFloat16 other) const {
+ return fputil::less_than_or_equals(*this, other);
+ }
+
+ LIBC_INLINE bool operator>(BFloat16 other) const {
+ return fputil::greater_than(*this, other);
+ }
+
+ LIBC_INLINE bool operator>=(BFloat16 other) const {
+ return fputil::greater_than_or_equals(*this, other);
+ }
}; // struct BFloat16
} // namespace fputil
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index fda7029..7205d8d 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -153,8 +153,10 @@ add_or_sub(InType x, InType y) {
result_mant <<= GUARD_BITS_LEN;
} else {
- InStorageType max_mant = max_bits.get_explicit_mantissa() << GUARD_BITS_LEN;
- InStorageType min_mant = min_bits.get_explicit_mantissa() << GUARD_BITS_LEN;
+ InStorageType max_mant = static_cast<InStorageType>(
+ max_bits.get_explicit_mantissa() << GUARD_BITS_LEN);
+ InStorageType min_mant = static_cast<InStorageType>(
+ min_bits.get_explicit_mantissa() << GUARD_BITS_LEN);
int alignment = (max_bits.get_biased_exponent() - max_bits.is_normal()) -
(min_bits.get_biased_exponent() - min_bits.is_normal());
@@ -172,7 +174,8 @@ add_or_sub(InType x, InType y) {
(static_cast<InStorageType>(
min_mant << (InFPBits::STORAGE_LEN - alignment))) != 0;
- InStorageType min_mant_sticky(static_cast<int>(aligned_min_mant_sticky));
+ InStorageType min_mant_sticky =
+ static_cast<InStorageType>(static_cast<int>(aligned_min_mant_sticky));
if (is_effectively_add)
result_mant = max_mant + (aligned_min_mant | min_mant_sticky);
diff --git a/libc/src/__support/FPUtil/riscv/FEnvImpl.h b/libc/src/__support/FPUtil/riscv/FEnvImpl.h
index 2f525eb..cb2d2d5 100644
--- a/libc/src/__support/FPUtil/riscv/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/riscv/FEnvImpl.h
@@ -10,13 +10,12 @@
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_RISCV_FENVIMPL_H
#include "hdr/fenv_macros.h"
+#include "hdr/stdint_proxy.h"
#include "hdr/types/fenv_t.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/macros/attributes.h" // For LIBC_INLINE_ASM
#include "src/__support/macros/config.h" // For LIBC_INLINE
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
diff --git a/libc/src/__support/FPUtil/rounding_mode.h b/libc/src/__support/FPUtil/rounding_mode.h
index bc66d09..4ee0a0b 100644
--- a/libc/src/__support/FPUtil/rounding_mode.h
+++ b/libc/src/__support/FPUtil/rounding_mode.h
@@ -10,6 +10,7 @@
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_ROUNDING_MODE_H
#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/type_traits.h" // is_constant_evaluated
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h"
@@ -20,18 +21,26 @@ namespace fputil {
// Using the following observation:
// 1.0f + 2^-25 = 1.0f for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO
// = 0x1.000002f for FE_UPWARD.
-LIBC_INLINE bool fenv_is_round_up() {
- volatile float x = 0x1.0p-25f;
- return (1.0f + x != 1.0f);
+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);
+ }
}
// 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 bool fenv_is_round_down() {
- volatile float x = 0x1.0p-25f;
- return (-1.0f - x != -1.0f);
+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);
+ }
}
// Quick free-standing test whether fegetround() == FE_TONEAREST.
@@ -40,10 +49,14 @@ LIBC_INLINE 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 bool fenv_is_round_to_nearest() {
- static volatile float x = 0x1.0p-24f;
- float y = x;
- return (1.5f + y == 1.5f - y);
+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);
+ }
}
// Quick free-standing test whether fegetround() == FE_TOWARDZERO.
@@ -56,23 +69,31 @@ LIBC_INLINE 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);
+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);
+ }
}
// 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);
+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 + y == 2.0f) ? FE_TONEAREST : FE_UPWARD;
+ 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;
+ }
}
} // namespace fputil
diff --git a/libc/src/__support/FPUtil/x86_64/FEnvImpl.h b/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
index 560727c..5da5097 100644
--- a/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/x86_64/FEnvImpl.h
@@ -17,8 +17,7 @@
#error "Invalid include"
#endif
-#include <stdint.h>
-
+#include "hdr/stdint_proxy.h"
#include "hdr/types/fenv_t.h"
#include "src/__support/macros/sanitizer.h"
diff --git a/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h b/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h
index 2e6b297..74a991d 100644
--- a/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h
+++ b/libc/src/__support/FPUtil/x86_64/NextAfterLongDouble.h
@@ -16,12 +16,11 @@
#error "Invalid include"
#endif
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
diff --git a/libc/src/__support/File/CMakeLists.txt b/libc/src/__support/File/CMakeLists.txt
index 5a4af5e..253243f 100644
--- a/libc/src/__support/File/CMakeLists.txt
+++ b/libc/src/__support/File/CMakeLists.txt
@@ -12,13 +12,14 @@ add_object_library(
HDRS
file.h
DEPENDS
+ libc.hdr.stdio_macros
+ libc.hdr.stdint_proxy
+ libc.hdr.func.realloc
+ libc.hdr.types.off_t
libc.src.__support.CPP.new
libc.src.__support.CPP.span
libc.src.__support.threads.mutex
libc.src.__support.error_or
- libc.hdr.types.off_t
- libc.hdr.stdio_macros
- libc.hdr.func.realloc
)
add_object_library(
diff --git a/libc/src/__support/File/file.h b/libc/src/__support/File/file.h
index 5c97a9c..3652e44 100644
--- a/libc/src/__support/File/file.h
+++ b/libc/src/__support/File/file.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FILE_FILE_H
#define LLVM_LIBC_SRC___SUPPORT_FILE_FILE_H
+#include "hdr/stdint_proxy.h"
#include "hdr/stdio_macros.h"
#include "hdr/types/off_t.h"
#include "src/__support/CPP/new.h"
@@ -18,7 +19,6 @@
#include "src/__support/threads/mutex.h"
#include <stddef.h>
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/File/linux/CMakeLists.txt b/libc/src/__support/File/linux/CMakeLists.txt
index 84e3d56..7a7bd6c 100644
--- a/libc/src/__support/File/linux/CMakeLists.txt
+++ b/libc/src/__support/File/linux/CMakeLists.txt
@@ -8,16 +8,17 @@ add_object_library(
lseekImpl.h
DEPENDS
libc.hdr.fcntl_macros
+ libc.hdr.stdio_macros
+ libc.hdr.stdint_proxy
+ libc.hdr.types.off_t
+ libc.hdr.types.FILE
libc.include.sys_syscall
libc.include.sys_stat
libc.src.__support.CPP.new
libc.src.__support.OSUtil.osutil
- libc.src.errno.errno
libc.src.__support.error_or
libc.src.__support.File.file
- libc.hdr.types.off_t
- libc.hdr.types.FILE
- libc.hdr.stdio_macros
+ libc.src.errno.errno
)
add_object_library(
diff --git a/libc/src/__support/File/linux/lseekImpl.h b/libc/src/__support/File/linux/lseekImpl.h
index 300e5c5..c22a6c5 100644
--- a/libc/src/__support/File/linux/lseekImpl.h
+++ b/libc/src/__support/File/linux/lseekImpl.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FILE_LINUX_LSEEKIMPL_H
#define LLVM_LIBC_SRC___SUPPORT_FILE_LINUX_LSEEKIMPL_H
+#include "hdr/stdint_proxy.h" // For uint64_t.
#include "hdr/types/off_t.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
@@ -16,7 +17,6 @@
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include <stdint.h> // For uint64_t.
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/GPU/CMakeLists.txt b/libc/src/__support/GPU/CMakeLists.txt
index 4ffee01..f8fdfeb 100644
--- a/libc/src/__support/GPU/CMakeLists.txt
+++ b/libc/src/__support/GPU/CMakeLists.txt
@@ -16,6 +16,7 @@ add_object_library(
HDRS
allocator.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.RPC.rpc_client
libc.src.__support.CPP.atomic
diff --git a/libc/src/__support/GPU/allocator.cpp b/libc/src/__support/GPU/allocator.cpp
index 7923fbb..866aea7 100644
--- a/libc/src/__support/GPU/allocator.cpp
+++ b/libc/src/__support/GPU/allocator.cpp
@@ -34,13 +34,12 @@ constexpr static uint32_t BITS_IN_WORD = sizeof(uint32_t) * 8;
constexpr static uint32_t MIN_SIZE = 16;
constexpr static uint32_t MIN_ALIGNMENT = MIN_SIZE - 1;
+// The number of times to attempt claiming an in-progress slab allocation.
+constexpr static uint32_t MAX_TRIES = 128;
+
// A sentinel used to indicate an invalid but non-null pointer value.
constexpr static uint64_t SENTINEL = cpp::numeric_limits<uint64_t>::max();
-// The number of times we will try starting on a single index before skipping
-// past it.
-constexpr static uint32_t MAX_TRIES = 512;
-
static_assert(!(ARRAY_SIZE & (ARRAY_SIZE - 1)), "Must be a power of two");
namespace impl {
@@ -92,20 +91,10 @@ static inline uint32_t xorshift32(uint32_t &state) {
return state * 0x9e3779bb;
}
-// Final stage of murmurhash used to get a unique index for the global array
-static inline uint32_t hash(uint32_t x) {
- x ^= x >> 16;
- x *= 0x85ebca6b;
- x ^= x >> 13;
- x *= 0xc2b2ae35;
- x ^= x >> 16;
- return x;
-}
-
// Rounds the input value to the closest permitted chunk size. Here we accept
// the sum of the closest three powers of two. For a 2MiB slab size this is 48
// different chunk sizes. This gives us average internal fragmentation of 87.5%.
-static inline uint32_t get_chunk_size(uint32_t x) {
+static inline constexpr uint32_t get_chunk_size(uint32_t x) {
uint32_t y = x < MIN_SIZE ? MIN_SIZE : x;
uint32_t pow2 = BITS_IN_WORD - cpp::countl_zero(y - 1);
@@ -123,6 +112,16 @@ static inline uint32_t get_chunk_size(uint32_t x) {
return (s3 + MIN_ALIGNMENT) & ~MIN_ALIGNMENT;
}
+// Converts a chunk size into an index suitable for a statically sized array.
+static inline constexpr uint32_t get_chunk_id(uint32_t x) {
+ if (x <= MIN_SIZE)
+ return 0;
+ uint32_t y = x >> 4;
+ if (x < MIN_SIZE << 2)
+ return cpp::popcount(y);
+ return cpp::popcount(y) + 3 * (BITS_IN_WORD - cpp::countl_zero(y)) - 7;
+}
+
// Rounds to the nearest power of two.
template <uint32_t N, typename T>
static inline constexpr T round_up(const T x) {
@@ -143,6 +142,12 @@ static inline constexpr bool is_pow2(uint64_t x) {
return x && (x & (x - 1)) == 0;
}
+// Where this chunk size should start looking in the global array.
+static inline constexpr uint32_t start_index(uint32_t chunk_index) {
+ return (ARRAY_SIZE * impl::get_chunk_id(chunk_index)) /
+ impl::get_chunk_id(SLAB_SIZE / 2);
+}
+
} // namespace impl
/// A slab allocator used to hand out identically sized slabs of memory.
@@ -251,12 +256,18 @@ struct Slab {
// The uniform mask represents which lanes contain a uniform target pointer.
// We attempt to place these next to each other.
void *result = nullptr;
+ uint32_t after = ~0u;
+ uint32_t old_index = 0;
for (uint64_t mask = lane_mask; mask;
mask = gpu::ballot(lane_mask, !result)) {
if (result)
continue;
- uint32_t start = gpu::broadcast_value(lane_mask, impl::xorshift32(state));
+ // We try using any known empty bits from the previous attempt first.
+ uint32_t start = gpu::shuffle(mask, cpp::countr_zero(uniform & mask),
+ ~after ? (old_index & ~(BITS_IN_WORD - 1)) +
+ cpp::countr_zero(~after)
+ : impl::xorshift32(state));
uint32_t id = impl::lane_count(uniform & mask);
uint32_t index = (start + id) % usable_bits(chunk_size);
@@ -266,8 +277,9 @@ struct Slab {
// Get the mask of bits destined for the same slot and coalesce it.
uint64_t match = uniform & gpu::match_any(mask, slot);
uint32_t length = cpp::popcount(match);
- uint32_t bitmask = static_cast<uint32_t>((uint64_t(1) << length) - 1)
- << bit;
+ uint32_t bitmask = gpu::shuffle(
+ mask, cpp::countr_zero(match),
+ static_cast<uint32_t>((uint64_t(1) << length) - 1) << bit);
uint32_t before = 0;
if (gpu::get_lane_id() == static_cast<uint32_t>(cpp::countr_zero(match)))
@@ -278,6 +290,9 @@ struct Slab {
result = ptr_from_index(index, chunk_size);
else
sleep_briefly();
+
+ after = before | bitmask;
+ old_index = index;
}
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
@@ -451,66 +466,65 @@ public:
// The global array used to search for a valid slab to allocate from.
static GuardPtr slots[ARRAY_SIZE] = {};
+// Keep a cache of the last successful slot for each chunk size. Initialize it
+// to an even spread of the total size. Must be updated if the chunking scheme
+// changes.
+#define S(X) (impl::start_index(X))
+static cpp::Atomic<uint32_t> indices[] = {
+ S(16), S(32), S(48), S(64), S(96), S(112), S(128),
+ S(192), S(224), S(256), S(384), S(448), S(512), S(768),
+ S(896), S(1024), S(1536), S(1792), S(2048), S(3072), S(3584),
+ S(4096), S(6144), S(7168), S(8192), S(12288), S(14336), S(16384),
+ S(24576), S(28672), S(32768), S(49152), S(57344), S(65536), S(98304),
+ S(114688), S(131072), S(196608), S(229376), S(262144), S(393216), S(458752),
+ S(524288), S(786432), S(917504), S(1048576)};
+#undef S
+
// Tries to find a slab in the table that can support the given chunk size.
static Slab *find_slab(uint32_t chunk_size) {
- // We start at a hashed value to spread out different chunk sizes.
- uint32_t start = impl::hash(chunk_size);
- uint64_t lane_mask = gpu::get_lane_mask();
- uint64_t uniform = gpu::match_any(lane_mask, chunk_size);
-
- Slab *result = nullptr;
- uint32_t nudge = 0;
- for (uint64_t mask = lane_mask; mask;
- mask = gpu::ballot(lane_mask, !result), ++nudge) {
- uint32_t index = cpp::numeric_limits<uint32_t>::max();
- for (uint32_t offset = nudge / MAX_TRIES;
- gpu::ballot(lane_mask, index == cpp::numeric_limits<uint32_t>::max());
- offset += cpp::popcount(uniform & lane_mask)) {
- uint32_t candidate =
- (start + offset + impl::lane_count(uniform & lane_mask)) % ARRAY_SIZE;
- uint64_t available =
- gpu::ballot(lane_mask, slots[candidate].use_count() <
- Slab::available_chunks(chunk_size));
- uint32_t new_index = gpu::shuffle(
- lane_mask, cpp::countr_zero(available & uniform), candidate);
-
- // Each uniform group will use the first empty slot they find.
- if ((index == cpp::numeric_limits<uint32_t>::max() &&
- (available & uniform)))
- index = new_index;
-
- // Guaruntees that this loop will eventuall exit if there is no space.
- if (offset >= ARRAY_SIZE) {
- result = reinterpret_cast<Slab *>(SENTINEL);
- index = 0;
- }
- }
+ // We start at the index of the last successful allocation for this kind.
+ uint32_t chunk_id = impl::get_chunk_id(chunk_size);
+ uint32_t start = indices[chunk_id].load(cpp::MemoryOrder::RELAXED);
+ uint64_t uniform = gpu::match_any(gpu::get_lane_mask(), chunk_size);
+
+ for (uint32_t offset = 0; offset < ARRAY_SIZE; ++offset) {
+ uint32_t index =
+ !offset ? start : (impl::start_index(chunk_size) + offset) % ARRAY_SIZE;
- // Try to claim a slot for the found slot.
- if (!result) {
+ if (slots[index].use_count() < Slab::available_chunks(chunk_size)) {
+ uint64_t lane_mask = gpu::get_lane_mask();
uint64_t reserved = 0;
- Slab *slab = slots[index].try_lock(lane_mask & mask, uniform & mask,
+
+ Slab *slab = slots[index].try_lock(lane_mask, uniform & lane_mask,
reserved, chunk_size, index);
+
+ // If there is a slab allocation in progress we retry a few times.
+ for (uint32_t retries = 0;
+ retries < MAX_TRIES && !slab && reserved != SENTINEL; retries++) {
+ uint64_t lane_mask = gpu::get_lane_mask();
+ slab = slots[index].try_lock(lane_mask, uniform & lane_mask, reserved,
+ chunk_size, index);
+ sleep_briefly();
+ }
+
// If we find a slab with a matching chunk size then we store the result.
// Otherwise, we need to free the claimed lock and continue. In the case
- // of out-of-memory we return a sentinel value.
+ // of out-of-memory we receive a sentinel value and return a failure.
if (slab && reserved <= Slab::available_chunks(chunk_size) &&
slab->get_chunk_size() == chunk_size) {
- result = slab;
+ if (index != start)
+ indices[chunk_id].store(index, cpp::MemoryOrder::RELAXED);
+ return slab;
} else if (slab && (reserved > Slab::available_chunks(chunk_size) ||
slab->get_chunk_size() != chunk_size)) {
- if (slab->get_chunk_size() != chunk_size)
- start = index + 1;
slots[index].unlock(gpu::get_lane_mask(),
gpu::get_lane_mask() & uniform);
- } else if (!slab && reserved == cpp::numeric_limits<uint64_t>::max()) {
- result = reinterpret_cast<Slab *>(SENTINEL);
- } else {
- sleep_briefly();
+ } else if (!slab && reserved == SENTINEL) {
+ return nullptr;
}
}
}
- return result;
+ return nullptr;
}
// Release the lock associated with a given slab.
diff --git a/libc/src/__support/GPU/allocator.h b/libc/src/__support/GPU/allocator.h
index a7cf8bc..67a7ff5 100644
--- a/libc/src/__support/GPU/allocator.h
+++ b/libc/src/__support/GPU/allocator.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_GPU_ALLOCATOR_H
#define LLVM_LIBC_SRC___SUPPORT_GPU_ALLOCATOR_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace gpu {
diff --git a/libc/src/__support/HashTable/CMakeLists.txt b/libc/src/__support/HashTable/CMakeLists.txt
index 698b8d0..d5861e7 100644
--- a/libc/src/__support/HashTable/CMakeLists.txt
+++ b/libc/src/__support/HashTable/CMakeLists.txt
@@ -5,6 +5,7 @@ add_header_library(
FLAGS
EXPLICIT_SIMD_OPT
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.macros.properties.cpu_features
@@ -26,6 +27,7 @@ add_header_library(
table.h
DEPENDS
.bitmask
+ libc.hdr.stdint_proxy
libc.hdr.types.ENTRY
libc.src.__support.CPP.bit
libc.src.__support.CPP.new
diff --git a/libc/src/__support/HashTable/bitmask.h b/libc/src/__support/HashTable/bitmask.h
index 3cac481..a4af496 100644
--- a/libc/src/__support/HashTable/bitmask.h
+++ b/libc/src/__support/HashTable/bitmask.h
@@ -9,11 +9,11 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_HASHTABLE_BITMASK_H
#define LLVM_LIBC_SRC___SUPPORT_HASHTABLE_BITMASK_H
+#include "hdr/stdint_proxy.h" // uint8_t, uint64_t
#include "src/__support/CPP/bit.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/cpu_features.h"
#include <stddef.h> // size_t
-#include <stdint.h> // uint8_t, uint64_t
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/__support/HashTable/table.h b/libc/src/__support/HashTable/table.h
index 10dd971..966ee0f 100644
--- a/libc/src/__support/HashTable/table.h
+++ b/libc/src/__support/HashTable/table.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_HASHTABLE_TABLE_H
#define LLVM_LIBC_SRC___SUPPORT_HASHTABLE_TABLE_H
+#include "hdr/stdint_proxy.h"
#include "hdr/types/ENTRY.h"
#include "src/__support/CPP/bit.h" // bit_ceil
#include "src/__support/CPP/new.h"
@@ -21,7 +22,6 @@
#include "src/string/memory_utils/inline_strcmp.h"
#include "src/string/string_utils.h"
#include <stddef.h>
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/__support/RPC/rpc_server.h b/libc/src/__support/RPC/rpc_server.h
index dc3d803..beea4dd 100644
--- a/libc/src/__support/RPC/rpc_server.h
+++ b/libc/src/__support/RPC/rpc_server.h
@@ -15,13 +15,17 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_RPC_RPC_SERVER_H
#define LLVM_LIBC_SRC___SUPPORT_RPC_RPC_SERVER_H
+#include "src/__support/macros/properties/compiler.h"
+
// Workaround for missing __has_builtin in < GCC 10.
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
// Workaround for missing __builtin_is_constant_evaluated in < GCC 10.
-#ifndef __builtin_is_constant_evaluated
+// Also this builtin is defined for GCC 9.
+#if !(__has_builtin(__builtin_is_constant_evaluated) || \
+ (defined(LIBC_COMPILER_IS_GCC) && (LIBC_COMPILER_GCC_VER >= 900)))
#define __builtin_is_constant_evaluated(x) 0
#endif
diff --git a/libc/src/__support/arg_list.h b/libc/src/__support/arg_list.h
index 66afa67..1e26a5e 100644
--- a/libc/src/__support/arg_list.h
+++ b/libc/src/__support/arg_list.h
@@ -9,12 +9,12 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_ARG_LIST_H
#define LLVM_LIBC_SRC___SUPPORT_ARG_LIST_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include <stdarg.h>
#include <stddef.h>
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index 85db31d..10e35ef 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
#define LLVM_LIBC_SRC___SUPPORT_BIG_INT_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/bit.h" // countl_zero
#include "src/__support/CPP/limits.h"
@@ -23,7 +24,6 @@
#include "src/__support/number_pair.h"
#include <stddef.h> // For size_t
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/block.h b/libc/src/__support/block.h
index a58c38b..b0d6576 100644
--- a/libc/src/__support/block.h
+++ b/libc/src/__support/block.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_BLOCK_H
#define LLVM_LIBC_SRC___SUPPORT_BLOCK_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/cstddef.h"
#include "src/__support/CPP/limits.h"
@@ -20,8 +21,6 @@
#include "src/__support/macros/config.h"
#include "src/__support/math_extras.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
/// Returns the value rounded down to the nearest multiple of alignment.
diff --git a/libc/src/__support/blockstore.h b/libc/src/__support/blockstore.h
index efe2234..61ee0ee 100644
--- a/libc/src/__support/blockstore.h
+++ b/libc/src/__support/blockstore.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_BLOCKSTORE_H
#define LLVM_LIBC_SRC___SUPPORT_BLOCKSTORE_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/new.h"
#include "src/__support/CPP/type_traits.h"
@@ -16,7 +17,6 @@
#include "src/__support/macros/config.h"
#include <stddef.h>
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/detailed_powers_of_ten.h b/libc/src/__support/detailed_powers_of_ten.h
index 28741b8..ab6f2be 100644
--- a/libc/src/__support/detailed_powers_of_ten.h
+++ b/libc/src/__support/detailed_powers_of_ten.h
@@ -9,11 +9,10 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_DETAILED_POWERS_OF_TEN_H
#define LLVM_LIBC_SRC___SUPPORT_DETAILED_POWERS_OF_TEN_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/__support/endian_internal.h b/libc/src/__support/endian_internal.h
index 77839ad..c78090a 100644
--- a/libc/src/__support/endian_internal.h
+++ b/libc/src/__support/endian_internal.h
@@ -9,11 +9,10 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_ENDIAN_INTERNAL_H
#define LLVM_LIBC_SRC___SUPPORT_ENDIAN_INTERNAL_H
-#include "common.h"
+#include "hdr/stdint_proxy.h"
+#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
// We rely on compiler preprocessor defines to allow for cross compilation.
diff --git a/libc/src/__support/fixed_point/CMakeLists.txt b/libc/src/__support/fixed_point/CMakeLists.txt
index 235c030..145eedb 100644
--- a/libc/src/__support/fixed_point/CMakeLists.txt
+++ b/libc/src/__support/fixed_point/CMakeLists.txt
@@ -3,6 +3,7 @@ add_header_library(
HDRS
fx_rep.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.llvm-libc-macros.stdfix_macros
libc.src.__support.macros.attributes
libc.src.__support.CPP.type_traits
diff --git a/libc/src/__support/fixed_point/fx_rep.h b/libc/src/__support/fixed_point/fx_rep.h
index 7227fff..e68be57 100644
--- a/libc/src/__support/fixed_point/fx_rep.h
+++ b/libc/src/__support/fixed_point/fx_rep.h
@@ -9,13 +9,12 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_REP_H
#define LLVM_LIBC_SRC___SUPPORT_FIXED_POINT_FX_REP_H
+#include "hdr/stdint_proxy.h"
#include "include/llvm-libc-macros/stdfix-macros.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
#ifdef LIBC_COMPILER_HAS_FIXED_POINT
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/float_to_string.h b/libc/src/__support/float_to_string.h
index d88bf84..cab146a 100644
--- a/libc/src/__support/float_to_string.h
+++ b/libc/src/__support/float_to_string.h
@@ -9,8 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_FLOAT_TO_STRING_H
#define LLVM_LIBC_SRC___SUPPORT_FLOAT_TO_STRING_H
-#include <stdint.h>
-
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FPBits.h"
diff --git a/libc/src/__support/hash.h b/libc/src/__support/hash.h
index 49138b1..6dfaadf 100644
--- a/libc/src/__support/hash.h
+++ b/libc/src/__support/hash.h
@@ -9,12 +9,12 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_HASH_H
#define LLVM_LIBC_SRC___SUPPORT_HASH_H
+#include "hdr/stdint_proxy.h" // For uint64_t
#include "src/__support/CPP/bit.h" // rotl
#include "src/__support/CPP/limits.h" // numeric_limits
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h"
#include "src/__support/uint128.h" // UInt128
-#include <stdint.h> // For uint64_t
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/__support/high_precision_decimal.h b/libc/src/__support/high_precision_decimal.h
index cb4b50c..08af786 100644
--- a/libc/src/__support/high_precision_decimal.h
+++ b/libc/src/__support/high_precision_decimal.h
@@ -15,11 +15,11 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_HIGH_PRECISION_DECIMAL_H
#define LLVM_LIBC_SRC___SUPPORT_HIGH_PRECISION_DECIMAL_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/limits.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_integer.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/__support/integer_literals.h b/libc/src/__support/integer_literals.h
index f68b7ef..67d241d 100644
--- a/libc/src/__support/integer_literals.h
+++ b/libc/src/__support/integer_literals.h
@@ -13,13 +13,13 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_INTEGER_LITERALS_H
#define LLVM_LIBC_SRC___SUPPORT_INTEGER_LITERALS_H
+#include "hdr/stdint_proxy.h" // uintxx_t
#include "src/__support/CPP/limits.h" // CHAR_BIT
#include "src/__support/ctype_utils.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h"
#include "src/__support/uint128.h" // UInt128
#include <stddef.h> // size_t
-#include <stdint.h> // uintxx_t
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/integer_to_string.h b/libc/src/__support/integer_to_string.h
index 65bdcf1..29449bd 100644
--- a/libc/src/__support/integer_to_string.h
+++ b/libc/src/__support/integer_to_string.h
@@ -57,8 +57,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_INTEGER_TO_STRING_H
#define LLVM_LIBC_SRC___SUPPORT_INTEGER_TO_STRING_H
-#include <stdint.h>
-
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/algorithm.h" // max
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/bit.h"
diff --git a/libc/src/__support/macros/CMakeLists.txt b/libc/src/__support/macros/CMakeLists.txt
index 99d4f64..a639d3e 100644
--- a/libc/src/__support/macros/CMakeLists.txt
+++ b/libc/src/__support/macros/CMakeLists.txt
@@ -35,5 +35,4 @@ add_header_library(
DEPENDS
.config
.optimization
- .sanitizer
)
diff --git a/libc/src/__support/macros/null_check.h b/libc/src/__support/macros/null_check.h
index abf65c56..438ba69 100644
--- a/libc/src/__support/macros/null_check.h
+++ b/libc/src/__support/macros/null_check.h
@@ -11,9 +11,8 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
-#include "src/__support/macros/sanitizer.h"
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
#define LIBC_CRASH_ON_NULLPTR(ptr) \
do { \
if (LIBC_UNLIKELY((ptr) == nullptr)) \
diff --git a/libc/src/__support/macros/properties/CMakeLists.txt b/libc/src/__support/macros/properties/CMakeLists.txt
index 80ed63a..dfa2f9c 100644
--- a/libc/src/__support/macros/properties/CMakeLists.txt
+++ b/libc/src/__support/macros/properties/CMakeLists.txt
@@ -34,6 +34,7 @@ add_header_library(
.cpu_features
.os
libc.hdr.float_macros
+ libc.hdr.stdint_proxy
libc.include.llvm-libc-macros.float16_macros
libc.include.llvm-libc-types.float128
)
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index aec4a48..3259c8a 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -10,7 +10,8 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
-#include "hdr/float_macros.h" // LDBL_MANT_DIG
+#include "hdr/float_macros.h" // LDBL_MANT_DIG
+#include "hdr/stdint_proxy.h" // UINT64_MAX, __SIZEOF_INT128__
#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
@@ -19,8 +20,6 @@
#include "src/__support/macros/properties/cpu_features.h"
#include "src/__support/macros/properties/os.h"
-#include <stdint.h> // UINT64_MAX, __SIZEOF_INT128__
-
// 'long double' properties.
#if (LDBL_MANT_DIG == 53)
#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
diff --git a/libc/src/__support/macros/sanitizer.h b/libc/src/__support/macros/sanitizer.h
index c20412e..84268a1 100644
--- a/libc/src/__support/macros/sanitizer.h
+++ b/libc/src/__support/macros/sanitizer.h
@@ -23,16 +23,6 @@
#define LIBC_HAS_MEMORY_SANITIZER
#endif
-#if LIBC_HAS_FEATURE(undefined_behavior_sanitizer)
-#define LIBC_HAS_UNDEFINED_BEHAVIOR_SANITIZER
-#endif
-
-#if defined(LIBC_HAS_ADDRESS_SANITIZER) || \
- defined(LIBC_HAS_MEMORY_SANITIZER) || \
- defined(LIBC_HAS_UNDEFINED_BEHAVIOR_SANITIZER)
-#define LIBC_HAS_SANITIZER
-#endif
-
#ifdef LIBC_HAS_MEMORY_SANITIZER
// Only perform MSAN unpoison in non-constexpr context.
#include <sanitizer/msan_interface.h>
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 9a8a4d1..b096c61 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -4,7 +4,6 @@ add_header_library(
acos.h
DEPENDS
.asin_utils
- libc.src.__support.math.asin_utils
libc.src.__support.FPUtil.double_double
libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
@@ -96,6 +95,21 @@ add_header_library(
)
add_header_library(
+ acospif16
+ HDRS
+ acospif16.h
+ DEPENDS
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.FPUtil.sqrt
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.types
+)
+
+add_header_library(
asin_utils
HDRS
asin_utils.h
@@ -110,6 +124,39 @@ add_header_library(
)
add_header_library(
+ asin
+ HDRS
+ asin.h
+ DEPENDS
+ .asin_utils
+ libc.src.__support.FPUtil.double_double
+ libc.src.__support.FPUtil.dyadic_float
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.FPUtil.sqrt
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
+)
+
+add_header_library(
+ asinf
+ HDRS
+ asinf.h
+ DEPENDS
+ .inv_trigf_utils
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.except_value_utils
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.sqrt
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
+)
+
+add_header_library(
erff
HDRS
erff.h
@@ -337,6 +384,7 @@ add_header_library(
HDRS
exp10_float16_constants.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.array
)
@@ -357,11 +405,10 @@ add_header_library(
DEPENDS
.exp10f16_utils
libc.src.__support.FPUtil.fp_bits
- src.__support.FPUtil.FEnvImpl
- src.__support.FPUtil.FPBits
- src.__support.FPUtil.cast
- src.__support.FPUtil.rounding_mode
- src.__support.FPUtil.except_value_utils
- src.__support.macros.optimization
- src.__support.macros.properties.cpu_features
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.FPUtil.except_value_utils
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
)
diff --git a/libc/src/__support/math/acos.h b/libc/src/__support/math/acos.h
index a52ead7..0e1e413 100644
--- a/libc/src/__support/math/acos.h
+++ b/libc/src/__support/math/acos.h
@@ -24,7 +24,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr double acos(double x) {
+LIBC_INLINE static constexpr double acos(double x) {
using DoubleDouble = fputil::DoubleDouble;
using namespace asin_internal;
using FPBits = fputil::FPBits<double>;
diff --git a/libc/src/__support/math/acosf.h b/libc/src/__support/math/acosf.h
index 153087e..7a0c0e5 100644
--- a/libc/src/__support/math/acosf.h
+++ b/libc/src/__support/math/acosf.h
@@ -45,7 +45,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{
} // namespace acosf_internal
-static constexpr float acosf(float x) {
+LIBC_INLINE static constexpr float acosf(float x) {
using namespace acosf_internal;
using namespace inv_trigf_utils_internal;
using FPBits = typename fputil::FPBits<float>;
diff --git a/libc/src/__support/math/acosf16.h b/libc/src/__support/math/acosf16.h
index 58d3761..3f0e002 100644
--- a/libc/src/__support/math/acosf16.h
+++ b/libc/src/__support/math/acosf16.h
@@ -26,7 +26,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float16 acosf16(float16 x) {
+LIBC_INLINE static constexpr float16 acosf16(float16 x) {
// Generated by Sollya using the following command:
// > round(pi/2, SG, RN);
diff --git a/libc/src/__support/math/acoshf.h b/libc/src/__support/math/acoshf.h
index f18f169..4e00311 100644
--- a/libc/src/__support/math/acoshf.h
+++ b/libc/src/__support/math/acoshf.h
@@ -21,7 +21,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float acoshf(float x) {
+LIBC_INLINE static constexpr float acoshf(float x) {
using namespace acoshf_internal;
using FPBits_t = typename fputil::FPBits<float>;
FPBits_t xbits(x);
diff --git a/libc/src/__support/math/acoshf16.h b/libc/src/__support/math/acoshf16.h
index 15e7f6a..e5be2a8 100644
--- a/libc/src/__support/math/acoshf16.h
+++ b/libc/src/__support/math/acoshf16.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF_H
-#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF16_H
#include "include/llvm-libc-macros/float16-macros.h"
@@ -28,7 +28,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float16 acoshf16(float16 x) {
+LIBC_INLINE static constexpr float16 acoshf16(float16 x) {
using namespace acoshf_internal;
constexpr size_t N_EXCEPTS = 2;
@@ -120,4 +120,4 @@ static constexpr float16 acoshf16(float16 x) {
#endif // LIBC_TYPES_HAS_FLOAT16
-#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF_H
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF16_H
diff --git a/libc/src/__support/math/acospif16.h b/libc/src/__support/math/acospif16.h
new file mode 100644
index 0000000..cf29c76
--- /dev/null
+++ b/libc/src/__support/math/acospif16.h
@@ -0,0 +1,147 @@
+//===-- Implementation header for acospif16 ---------------------*- 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___SUPPORT_MATH_ACOSPIF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSPIF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr float16 acospif16(float16 x) {
+ using FPBits = fputil::FPBits<float16>;
+ FPBits xbits(x);
+
+ uint16_t x_u = xbits.uintval();
+ uint16_t x_abs = x_u & 0x7fff;
+ uint16_t x_sign = x_u >> 15;
+
+ // |x| > 0x1p0, |x| > 1, or x is NaN.
+ if (LIBC_UNLIKELY(x_abs > 0x3c00)) {
+ // acospif16(NaN) = NaN
+ if (xbits.is_nan()) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ return x;
+ }
+
+ // 1 < |x| <= +inf
+ fputil::raise_except_if_required(FE_INVALID);
+ fputil::set_errno_if_required(EDOM);
+
+ return FPBits::quiet_nan().get_val();
+ }
+
+ // |x| == 0x1p0, x is 1 or -1
+ // if x is (-)1, return 1
+ // if x is (+)1, return 0
+ if (LIBC_UNLIKELY(x_abs == 0x3c00))
+ return fputil::cast<float16>(x_sign ? 1.0f : 0.0f);
+
+ float xf = x;
+ float xsq = xf * xf;
+
+ // Degree-6 minimax polynomial coefficients of asin(x) generated by Sollya
+ // with: > P = fpminimax(asin(x)/(pi * x), [|0, 2, 4, 6, 8|], [|SG...|], [0,
+ // 0.5]);
+ constexpr float POLY_COEFFS[5] = {0x1.45f308p-2f, 0x1.b2900cp-5f,
+ 0x1.897e36p-6f, 0x1.9efafcp-7f,
+ 0x1.06d884p-6f};
+ // |x| <= 0x1p-1, |x| <= 0.5
+ if (x_abs <= 0x3800) {
+ // if x is 0, return 0.5
+ if (LIBC_UNLIKELY(x_abs == 0))
+ return fputil::cast<float16>(0.5f);
+
+ // Note that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x), then
+ // acospi(x) = 0.5 - asin(x)/pi
+ float interm =
+ fputil::polyeval(xsq, POLY_COEFFS[0], POLY_COEFFS[1], POLY_COEFFS[2],
+ POLY_COEFFS[3], POLY_COEFFS[4]);
+
+ return fputil::cast<float16>(fputil::multiply_add(-xf, interm, 0.5f));
+ }
+
+ // When |x| > 0.5, assume that 0.5 < |x| <= 1
+ //
+ // Step-by-step range-reduction proof:
+ // 1: Let y = asin(x), such that, x = sin(y)
+ // 2: From complimentary angle identity:
+ // x = sin(y) = cos(pi/2 - y)
+ // 3: Let z = pi/2 - y, such that x = cos(z)
+ // 4: From double angle formula; cos(2A) = 1 - 2 * sin^2(A):
+ // z = 2A, z/2 = A
+ // cos(z) = 1 - 2 * sin^2(z/2)
+ // 5: Make sin(z/2) subject of the formula:
+ // sin(z/2) = sqrt((1 - cos(z))/2)
+ // 6: Recall [3]; x = cos(z). Therefore:
+ // sin(z/2) = sqrt((1 - x)/2)
+ // 7: Let u = (1 - x)/2
+ // 8: Therefore:
+ // asin(sqrt(u)) = z/2
+ // 2 * asin(sqrt(u)) = z
+ // 9: Recall [3]; z = pi/2 - y. Therefore:
+ // y = pi/2 - z
+ // y = pi/2 - 2 * asin(sqrt(u))
+ // 10: Recall [1], y = asin(x). Therefore:
+ // asin(x) = pi/2 - 2 * asin(sqrt(u))
+ // 11: Recall that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x)
+ // Therefore:
+ // acos(x) = pi/2 - (pi/2 - 2 * asin(sqrt(u)))
+ // acos(x) = 2 * asin(sqrt(u))
+ // acospi(x) = 2 * (asin(sqrt(u)) / pi)
+ //
+ // THE RANGE REDUCTION, HOW?
+ // 12: Recall [7], u = (1 - x)/2
+ // 13: Since 0.5 < x <= 1, therefore:
+ // 0 <= u <= 0.25 and 0 <= sqrt(u) <= 0.5
+ //
+ // Hence, we can reuse the same [0, 0.5] domain polynomial approximation for
+ // Step [11] as `sqrt(u)` is in range.
+ // When -1 < x <= -0.5, the identity:
+ // acos(x) = pi - acos(-x)
+ // acospi(x) = 1 - acos(-x)/pi
+ // allows us to compute for the negative x value (lhs)
+ // with a positive x value instead (rhs).
+
+ float xf_abs = (xf < 0 ? -xf : xf);
+ float u = fputil::multiply_add(-0.5f, xf_abs, 0.5f);
+ float sqrt_u = fputil::sqrt<float>(u);
+
+ float asin_sqrt_u =
+ sqrt_u * fputil::polyeval(u, POLY_COEFFS[0], POLY_COEFFS[1],
+ POLY_COEFFS[2], POLY_COEFFS[3], POLY_COEFFS[4]);
+
+ // Same as acos(x), but devided the expression with pi
+ return fputil::cast<float16>(
+ x_sign ? fputil::multiply_add(-2.0f, asin_sqrt_u, 1.0f)
+ : 2.0f * asin_sqrt_u);
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ACOSPIF16_H
diff --git a/libc/src/__support/math/asin.h b/libc/src/__support/math/asin.h
new file mode 100644
index 0000000..5e06d04
--- /dev/null
+++ b/libc/src/__support/math/asin.h
@@ -0,0 +1,297 @@
+//===-- Implementation header for asin --------------------------*- 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___SUPPORT_MATH_ASIN_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ASIN_H
+
+#include "asin_utils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/double_double.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
+#include "src/__support/math/asin_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr double asin(double x) {
+ using namespace asin_internal;
+ using FPBits = fputil::FPBits<double>;
+
+ FPBits xbits(x);
+ int x_exp = xbits.get_biased_exponent();
+
+ // |x| < 0.5.
+ if (x_exp < FPBits::EXP_BIAS - 1) {
+ // |x| < 2^-26.
+ if (LIBC_UNLIKELY(x_exp < FPBits::EXP_BIAS - 26)) {
+ // When |x| < 2^-26, the relative error of the approximation asin(x) ~ x
+ // is:
+ // |asin(x) - x| / |asin(x)| < |x^3| / (6|x|)
+ // = x^2 / 6
+ // < 2^-54
+ // < epsilon(1)/2.
+ // So the correctly rounded values of asin(x) are:
+ // = x + sign(x)*eps(x) if rounding mode = FE_TOWARDZERO,
+ // or (rounding mode = FE_UPWARD and x is
+ // negative),
+ // = x otherwise.
+ // To simplify the rounding decision and make it more efficient, we use
+ // fma(x, 2^-54, x) instead.
+ // Note: to use the formula x + 2^-54*x to decide the correct rounding, we
+ // do need fma(x, 2^-54, x) to prevent underflow caused by 2^-54*x when
+ // |x| < 2^-1022. For targets without FMA instructions, when x is close to
+ // denormal range, we normalize x,
+#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS)
+ return x;
+#elif defined(LIBC_TARGET_CPU_HAS_FMA_DOUBLE)
+ return fputil::multiply_add(x, 0x1.0p-54, x);
+#else
+ if (xbits.abs().uintval() == 0)
+ return x;
+ // Get sign(x) * min_normal.
+ FPBits eps_bits = FPBits::min_normal();
+ eps_bits.set_sign(xbits.sign());
+ double eps = eps_bits.get_val();
+ double normalize_const = (x_exp == 0) ? eps : 0.0;
+ double scaled_normal =
+ fputil::multiply_add(x + normalize_const, 0x1.0p54, eps);
+ return fputil::multiply_add(scaled_normal, 0x1.0p-54, -normalize_const);
+#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ }
+
+#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ return x * asin_eval(x * x);
+#else
+ using Float128 = fputil::DyadicFloat<128>;
+ using DoubleDouble = fputil::DoubleDouble;
+
+ unsigned idx = 0;
+ DoubleDouble x_sq = fputil::exact_mult(x, x);
+ double err = xbits.abs().get_val() * 0x1.0p-51;
+ // Polynomial approximation:
+ // p ~ asin(x)/x
+
+ DoubleDouble p = asin_eval(x_sq, idx, err);
+ // asin(x) ~ x * (ASIN_COEFFS[idx][0] + p)
+ DoubleDouble r0 = fputil::exact_mult(x, p.hi);
+ double r_lo = fputil::multiply_add(x, p.lo, r0.lo);
+
+ // Ziv's accuracy test.
+
+ double r_upper = r0.hi + (r_lo + err);
+ double r_lower = r0.hi + (r_lo - err);
+
+ if (LIBC_LIKELY(r_upper == r_lower))
+ return r_upper;
+
+ // Ziv's accuracy test failed, perform 128-bit calculation.
+
+ // Recalculate mod 1/64.
+ idx = static_cast<unsigned>(fputil::nearest_integer(x_sq.hi * 0x1.0p6));
+
+ // Get x^2 - idx/64 exactly. When FMA is available, double-double
+ // multiplication will be correct for all rounding modes. Otherwise we use
+ // Float128 directly.
+ Float128 x_f128(x);
+
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ // u = x^2 - idx/64
+ Float128 u_hi(
+ fputil::multiply_add(static_cast<double>(idx), -0x1.0p-6, x_sq.hi));
+ Float128 u = fputil::quick_add(u_hi, Float128(x_sq.lo));
+#else
+ Float128 x_sq_f128 = fputil::quick_mul(x_f128, x_f128);
+ Float128 u = fputil::quick_add(
+ x_sq_f128, Float128(static_cast<double>(idx) * (-0x1.0p-6)));
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+
+ Float128 p_f128 = asin_eval(u, idx);
+ Float128 r = fputil::quick_mul(x_f128, p_f128);
+
+ return static_cast<double>(r);
+#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ }
+ // |x| >= 0.5
+
+ double x_abs = xbits.abs().get_val();
+
+ // Maintaining the sign:
+ constexpr double SIGN[2] = {1.0, -1.0};
+ double x_sign = SIGN[xbits.is_neg()];
+
+ // |x| >= 1
+ if (LIBC_UNLIKELY(x_exp >= FPBits::EXP_BIAS)) {
+ // x = +-1, asin(x) = +- pi/2
+ if (x_abs == 1.0) {
+ // return +- pi/2
+ return fputil::multiply_add(x_sign, PI_OVER_TWO.hi,
+ x_sign * PI_OVER_TWO.lo);
+ }
+ // |x| > 1, return NaN.
+ if (xbits.is_quiet_nan())
+ return x;
+
+ // Set domain error for non-NaN input.
+ if (!xbits.is_nan())
+ fputil::set_errno_if_required(EDOM);
+
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ // When |x| >= 0.5, we perform range reduction as follow:
+ //
+ // Assume further that 0.5 <= x < 1, and let:
+ // y = asin(x)
+ // We will use the double angle formula:
+ // cos(2y) = 1 - 2 sin^2(y)
+ // and the complement angle identity:
+ // x = sin(y) = cos(pi/2 - y)
+ // = 1 - 2 sin^2 (pi/4 - y/2)
+ // So:
+ // sin(pi/4 - y/2) = sqrt( (1 - x)/2 )
+ // And hence:
+ // pi/4 - y/2 = asin( sqrt( (1 - x)/2 ) )
+ // Equivalently:
+ // asin(x) = y = pi/2 - 2 * asin( sqrt( (1 - x)/2 ) )
+ // Let u = (1 - x)/2, then:
+ // asin(x) = pi/2 - 2 * asin( sqrt(u) )
+ // Moreover, since 0.5 <= x < 1:
+ // 0 < u <= 1/4, and 0 < sqrt(u) <= 0.5,
+ // And hence we can reuse the same polynomial approximation of asin(x) when
+ // |x| <= 0.5:
+ // asin(x) ~ pi/2 - 2 * sqrt(u) * P(u),
+
+ // u = (1 - |x|)/2
+ double u = fputil::multiply_add(x_abs, -0.5, 0.5);
+ // v_hi + v_lo ~ sqrt(u).
+ // Let:
+ // h = u - v_hi^2 = (sqrt(u) - v_hi) * (sqrt(u) + v_hi)
+ // Then:
+ // sqrt(u) = v_hi + h / (sqrt(u) + v_hi)
+ // ~ v_hi + h / (2 * v_hi)
+ // So we can use:
+ // v_lo = h / (2 * v_hi).
+ // Then,
+ // asin(x) ~ pi/2 - 2*(v_hi + v_lo) * P(u)
+ double v_hi = fputil::sqrt<double>(u);
+
+#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ double p = asin_eval(u);
+ double r = x_sign * fputil::multiply_add(-2.0 * v_hi, p, PI_OVER_TWO.hi);
+ return r;
+#else
+
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ double h = fputil::multiply_add(v_hi, -v_hi, u);
+#else
+ DoubleDouble v_hi_sq = fputil::exact_mult(v_hi, v_hi);
+ double h = (u - v_hi_sq.hi) - v_hi_sq.lo;
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+
+ // Scale v_lo and v_hi by 2 from the formula:
+ // vh = v_hi * 2
+ // vl = 2*v_lo = h / v_hi.
+ double vh = v_hi * 2.0;
+ double vl = h / v_hi;
+
+ // Polynomial approximation:
+ // p ~ asin(sqrt(u))/sqrt(u)
+ unsigned idx = 0;
+ double err = vh * 0x1.0p-51;
+
+ DoubleDouble p = asin_eval(DoubleDouble{0.0, u}, idx, err);
+
+ // Perform computations in double-double arithmetic:
+ // asin(x) = pi/2 - (v_hi + v_lo) * (ASIN_COEFFS[idx][0] + p)
+ DoubleDouble r0 = fputil::quick_mult(DoubleDouble{vl, vh}, p);
+ DoubleDouble r = fputil::exact_add(PI_OVER_TWO.hi, -r0.hi);
+
+ double r_lo = PI_OVER_TWO.lo - r0.lo + r.lo;
+
+ // Ziv's accuracy test.
+
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ double r_upper = fputil::multiply_add(
+ r.hi, x_sign, fputil::multiply_add(r_lo, x_sign, err));
+ double r_lower = fputil::multiply_add(
+ r.hi, x_sign, fputil::multiply_add(r_lo, x_sign, -err));
+#else
+ r_lo *= x_sign;
+ r.hi *= x_sign;
+ double r_upper = r.hi + (r_lo + err);
+ double r_lower = r.hi + (r_lo - err);
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+
+ if (LIBC_LIKELY(r_upper == r_lower))
+ return r_upper;
+
+ // Ziv's accuracy test failed, we redo the computations in Float128.
+ // Recalculate mod 1/64.
+ idx = static_cast<unsigned>(fputil::nearest_integer(u * 0x1.0p6));
+
+ // After the first step of Newton-Raphson approximating v = sqrt(u), we have
+ // that:
+ // sqrt(u) = v_hi + h / (sqrt(u) + v_hi)
+ // v_lo = h / (2 * v_hi)
+ // With error:
+ // sqrt(u) - (v_hi + v_lo) = h * ( 1/(sqrt(u) + v_hi) - 1/(2*v_hi) )
+ // = -h^2 / (2*v * (sqrt(u) + v)^2).
+ // Since:
+ // (sqrt(u) + v_hi)^2 ~ (2sqrt(u))^2 = 4u,
+ // we can add another correction term to (v_hi + v_lo) that is:
+ // v_ll = -h^2 / (2*v_hi * 4u)
+ // = -v_lo * (h / 4u)
+ // = -vl * (h / 8u),
+ // making the errors:
+ // sqrt(u) - (v_hi + v_lo + v_ll) = O(h^3)
+ // well beyond 128-bit precision needed.
+
+ // Get the rounding error of vl = 2 * v_lo ~ h / vh
+ // Get full product of vh * vl
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ double vl_lo = fputil::multiply_add(-v_hi, vl, h) / v_hi;
+#else
+ DoubleDouble vh_vl = fputil::exact_mult(v_hi, vl);
+ double vl_lo = ((h - vh_vl.hi) - vh_vl.lo) / v_hi;
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ // vll = 2*v_ll = -vl * (h / (4u)).
+ double t = h * (-0.25) / u;
+ double vll = fputil::multiply_add(vl, t, vl_lo);
+ // m_v = -(v_hi + v_lo + v_ll).
+ Float128 m_v = fputil::quick_add(
+ Float128(vh), fputil::quick_add(Float128(vl), Float128(vll)));
+ m_v.sign = Sign::NEG;
+
+ // Perform computations in Float128:
+ // asin(x) = pi/2 - (v_hi + v_lo + vll) * P(u).
+ Float128 y_f128(fputil::multiply_add(static_cast<double>(idx), -0x1.0p-6, u));
+
+ Float128 p_f128 = asin_eval(y_f128, idx);
+ Float128 r0_f128 = fputil::quick_mul(m_v, p_f128);
+ Float128 r_f128 = fputil::quick_add(PI_OVER_TWO_F128, r0_f128);
+
+ if (xbits.is_neg())
+ r_f128.sign = Sign::NEG;
+
+ return static_cast<double>(r_f128);
+#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ASIN_H
diff --git a/libc/src/__support/math/asinf.h b/libc/src/__support/math/asinf.h
new file mode 100644
index 0000000..bfa0dc3
--- /dev/null
+++ b/libc/src/__support/math/asinf.h
@@ -0,0 +1,175 @@
+//===-- Implementation header for asinf -------------------------*- 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___SUPPORT_MATH_ASINF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINF_H
+
+#include "inv_trigf_utils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/sqrt.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr float asinf(float x) {
+ using namespace inv_trigf_utils_internal;
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ constexpr size_t N_EXCEPTS = 2;
+
+ // Exceptional values when |x| <= 0.5
+ constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_LO = {{
+ // (inputs, RZ output, RU offset, RD offset, RN offset)
+ // x = 0x1.137f0cp-5, asinf(x) = 0x1.138c58p-5 (RZ)
+ {0x3d09bf86, 0x3d09c62c, 1, 0, 1},
+ // x = 0x1.cbf43cp-4, asinf(x) = 0x1.cced1cp-4 (RZ)
+ {0x3de5fa1e, 0x3de6768e, 1, 0, 0},
+ }};
+
+ // Exceptional values when 0.5 < |x| <= 1
+ constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_HI = {{
+ // (inputs, RZ output, RU offset, RD offset, RN offset)
+ // x = 0x1.107434p-1, asinf(x) = 0x1.1f4b64p-1 (RZ)
+ {0x3f083a1a, 0x3f0fa5b2, 1, 0, 0},
+ // x = 0x1.ee836cp-1, asinf(x) = 0x1.4f0654p0 (RZ)
+ {0x3f7741b6, 0x3fa7832a, 1, 0, 0},
+ }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ using namespace inv_trigf_utils_internal;
+ using FPBits = typename fputil::FPBits<float>;
+
+ FPBits xbits(x);
+ uint32_t x_uint = xbits.uintval();
+ uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU;
+ constexpr double SIGN[2] = {1.0, -1.0};
+ uint32_t x_sign = x_uint >> 31;
+
+ // |x| <= 0.5-ish
+ if (x_abs < 0x3f04'471dU) {
+ // |x| < 0x1.d12edp-12
+ if (LIBC_UNLIKELY(x_abs < 0x39e8'9768U)) {
+ // When |x| < 2^-12, the relative error of the approximation asin(x) ~ x
+ // is:
+ // |asin(x) - x| / |asin(x)| < |x^3| / (6|x|)
+ // = x^2 / 6
+ // < 2^-25
+ // < epsilon(1)/2.
+ // So the correctly rounded values of asin(x) are:
+ // = x + sign(x)*eps(x) if rounding mode = FE_TOWARDZERO,
+ // or (rounding mode = FE_UPWARD and x is
+ // negative),
+ // = x otherwise.
+ // To simplify the rounding decision and make it more efficient, we use
+ // fma(x, 2^-25, x) instead.
+ // An exhaustive test shows that this formula work correctly for all
+ // rounding modes up to |x| < 0x1.d12edp-12.
+ // Note: to use the formula x + 2^-25*x to decide the correct rounding, we
+ // do need fma(x, 2^-25, x) to prevent underflow caused by 2^-25*x when
+ // |x| < 2^-125. For targets without FMA instructions, we simply use
+ // double for intermediate results as it is more efficient than using an
+ // emulated version of FMA.
+#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT)
+ return fputil::multiply_add(x, 0x1.0p-25f, x);
+#else
+ double xd = static_cast<double>(x);
+ return static_cast<float>(fputil::multiply_add(xd, 0x1.0p-25, xd));
+#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
+ }
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Check for exceptional values
+ if (auto r = ASINF_EXCEPTS_LO.lookup_odd(x_abs, x_sign);
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // For |x| <= 0.5, we approximate asinf(x) by:
+ // asin(x) = x * P(x^2)
+ // Where P(X^2) = Q(X) is a degree-20 minimax even polynomial approximating
+ // asin(x)/x on [0, 0.5] generated by Sollya with:
+ // > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|],
+ // [|1, D...|], [0, 0.5]);
+ // An exhaustive test shows that this approximation works well up to a
+ // little more than 0.5.
+ double xd = static_cast<double>(x);
+ double xsq = xd * xd;
+ double x3 = xd * xsq;
+ double r = asin_eval(xsq);
+ return static_cast<float>(fputil::multiply_add(x3, r, xd));
+ }
+
+ // |x| > 1, return NaNs.
+ if (LIBC_UNLIKELY(x_abs > 0x3f80'0000U)) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ if (x_abs <= 0x7f80'0000U) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ }
+
+ return FPBits::quiet_nan().get_val();
+ }
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Check for exceptional values
+ if (auto r = ASINF_EXCEPTS_HI.lookup_odd(x_abs, x_sign);
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // When |x| > 0.5, we perform range reduction as follow:
+ //
+ // Assume further that 0.5 < x <= 1, and let:
+ // y = asin(x)
+ // We will use the double angle formula:
+ // cos(2y) = 1 - 2 sin^2(y)
+ // and the complement angle identity:
+ // x = sin(y) = cos(pi/2 - y)
+ // = 1 - 2 sin^2 (pi/4 - y/2)
+ // So:
+ // sin(pi/4 - y/2) = sqrt( (1 - x)/2 )
+ // And hence:
+ // pi/4 - y/2 = asin( sqrt( (1 - x)/2 ) )
+ // Equivalently:
+ // asin(x) = y = pi/2 - 2 * asin( sqrt( (1 - x)/2 ) )
+ // Let u = (1 - x)/2, then:
+ // asin(x) = pi/2 - 2 * asin( sqrt(u) )
+ // Moreover, since 0.5 < x <= 1:
+ // 0 <= u < 1/4, and 0 <= sqrt(u) < 0.5,
+ // And hence we can reuse the same polynomial approximation of asin(x) when
+ // |x| <= 0.5:
+ // asin(x) ~ pi/2 - 2 * sqrt(u) * P(u),
+
+ xbits.set_sign(Sign::POS);
+ double sign = SIGN[x_sign];
+ double xd = static_cast<double>(xbits.get_val());
+ double u = fputil::multiply_add(-0.5, xd, 0.5);
+ double c1 = sign * (-2 * fputil::sqrt<double>(u));
+ double c2 = fputil::multiply_add(sign, M_MATH_PI_2, c1);
+ double c3 = c1 * u;
+
+ double r = asin_eval(u);
+ return static_cast<float>(fputil::multiply_add(c3, r, c2));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ASINF_H
diff --git a/libc/src/__support/math/erff.h b/libc/src/__support/math/erff.h
index e54ec77..b81be30 100644
--- a/libc/src/__support/math/erff.h
+++ b/libc/src/__support/math/erff.h
@@ -19,7 +19,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float erff(float x) {
+LIBC_INLINE static constexpr float erff(float x) {
// Polynomials approximating erf(x)/x on ( k/8, (k + 1)/8 ) generated by
// Sollya with: > P = fpminimax(erf(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14|],
diff --git a/libc/src/__support/math/exp.h b/libc/src/__support/math/exp.h
index ff59ff7..83638e8 100644
--- a/libc/src/__support/math/exp.h
+++ b/libc/src/__support/math/exp.h
@@ -67,7 +67,7 @@ namespace {
// Return expm1(dx) / x ~ 1 + dx / 2 + dx^2 / 6 + dx^3 / 24.
// For |dx| < 2^-13 + 2^-30:
// | output - expm1(dx) / dx | < 2^-51.
-static double poly_approx_d(double dx) {
+LIBC_INLINE static double poly_approx_d(double dx) {
// dx^2
double dx2 = dx * dx;
// c0 = 1 + dx / 2
@@ -85,7 +85,7 @@ static double poly_approx_d(double dx) {
// Return exp(dx) ~ 1 + dx + dx^2 / 2 + ... + dx^6 / 720
// For |dx| < 2^-13 + 2^-30:
// | output - exp(dx) | < 2^-101
-static DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
+LIBC_INLINE static DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
// Taylor polynomial.
constexpr DoubleDouble COEFFS[] = {
{0, 0x1p0}, // 1
@@ -106,7 +106,7 @@ static DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
// Return exp(dx) ~ 1 + dx + dx^2 / 2 + ... + dx^7 / 5040
// For |dx| < 2^-13 + 2^-30:
// | output - exp(dx) | < 2^-126.
-static Float128 poly_approx_f128(const Float128 &dx) {
+LIBC_INLINE static Float128 poly_approx_f128(const Float128 &dx) {
constexpr Float128 COEFFS_128[]{
{Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
{Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
@@ -127,7 +127,7 @@ static Float128 poly_approx_f128(const Float128 &dx) {
// Compute exp(x) using 128-bit precision.
// TODO(lntue): investigate triple-double precision implementation for this
// step.
-static Float128 exp_f128(double x, double kd, int idx1, int idx2) {
+LIBC_INLINE static Float128 exp_f128(double x, double kd, int idx1, int idx2) {
// Recalculate dx:
double t1 = fputil::multiply_add(kd, MLOG_2_EXP2_M12_HI, x); // exact
@@ -160,8 +160,8 @@ static Float128 exp_f128(double x, double kd, int idx1, int idx2) {
}
// Compute exp(x) with double-double precision.
-static DoubleDouble exp_double_double(double x, double kd,
- const DoubleDouble &exp_mid) {
+LIBC_INLINE static DoubleDouble exp_double_double(double x, double kd,
+ const DoubleDouble &exp_mid) {
// Recalculate dx:
// dx = x - k * 2^-12 * log(2)
double t1 = fputil::multiply_add(kd, MLOG_2_EXP2_M12_HI, x); // exact
@@ -184,7 +184,7 @@ static DoubleDouble exp_double_double(double x, double kd,
// Check for exceptional cases when
// |x| <= 2^-53 or x < log(2^-1075) or x >= 0x1.6232bdd7abcd3p+9
-static double set_exceptional(double x) {
+LIBC_INLINE static double set_exceptional(double x) {
using FPBits = typename fputil::FPBits<double>;
FPBits xbits(x);
@@ -234,7 +234,7 @@ static double set_exceptional(double x) {
namespace math {
-static double exp(double x) {
+LIBC_INLINE static double exp(double x) {
using FPBits = typename fputil::FPBits<double>;
FPBits xbits(x);
diff --git a/libc/src/__support/math/exp10.h b/libc/src/__support/math/exp10.h
index fa60e40c..12a09d7 100644
--- a/libc/src/__support/math/exp10.h
+++ b/libc/src/__support/math/exp10.h
@@ -83,7 +83,8 @@ LIBC_INLINE static double exp10_poly_approx_d(double dx) {
// > P = fpminimax((10^x - 1)/x, 5, [|DD...|], [-2^-14, 2^-14]);
// Error bounds:
// | output - 10^(dx) | < 2^-101
-static constexpr DoubleDouble exp10_poly_approx_dd(const DoubleDouble &dx) {
+LIBC_INLINE static constexpr DoubleDouble
+exp10_poly_approx_dd(const DoubleDouble &dx) {
// Taylor polynomial.
constexpr DoubleDouble COEFFS[] = {
{0, 0x1p0},
@@ -105,7 +106,8 @@ static constexpr DoubleDouble exp10_poly_approx_dd(const DoubleDouble &dx) {
// Return exp(dx) ~ 1 + a0 * dx + a1 * dx^2 + ... + a6 * dx^7
// For |dx| < 2^-14:
// | output - 10^dx | < 1.5 * 2^-124.
-static constexpr Float128 exp10_poly_approx_f128(const Float128 &dx) {
+LIBC_INLINE static constexpr Float128
+exp10_poly_approx_f128(const Float128 &dx) {
constexpr Float128 COEFFS_128[]{
{Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
{Sign::POS, -126, 0x935d8ddd'aaa8ac16'ea56d62b'82d30a2d_u128},
@@ -126,7 +128,8 @@ static constexpr Float128 exp10_poly_approx_f128(const Float128 &dx) {
// Compute 10^(x) using 128-bit precision.
// TODO(lntue): investigate triple-double precision implementation for this
// step.
-static Float128 exp10_f128(double x, double kd, int idx1, int idx2) {
+LIBC_INLINE static Float128 exp10_f128(double x, double kd, int idx1,
+ int idx2) {
double t1 = fputil::multiply_add(kd, MLOG10_2_EXP2_M12_HI, x); // exact
double t2 = kd * MLOG10_2_EXP2_M12_MID_32; // exact
double t3 = kd * MLOG10_2_EXP2_M12_LO; // Error < 2^-144
@@ -157,8 +160,8 @@ static Float128 exp10_f128(double x, double kd, int idx1, int idx2) {
}
// Compute 10^x with double-double precision.
-static DoubleDouble exp10_double_double(double x, double kd,
- const DoubleDouble &exp_mid) {
+LIBC_INLINE static DoubleDouble
+exp10_double_double(double x, double kd, const DoubleDouble &exp_mid) {
// Recalculate dx:
// dx = x - k * 2^-12 * log10(2)
double t1 = fputil::multiply_add(kd, MLOG10_2_EXP2_M12_HI, x); // exact
@@ -180,7 +183,7 @@ static DoubleDouble exp10_double_double(double x, double kd,
#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
// When output is denormal.
-static double exp10_denorm(double x) {
+LIBC_INLINE static double exp10_denorm(double x) {
// Range reduction.
double tmp = fputil::multiply_add(x, LOG2_10, 0x1.8000'0000'4p21);
int k = static_cast<int>(cpp::bit_cast<uint64_t>(tmp) >> 19);
@@ -234,7 +237,7 @@ static double exp10_denorm(double x) {
// * x >= log10(2^1024)
// * x <= log10(2^-1022)
// * x is inf or nan
-static constexpr double exp10_set_exceptional(double x) {
+LIBC_INLINE static constexpr double exp10_set_exceptional(double x) {
using FPBits = typename fputil::FPBits<double>;
FPBits xbits(x);
@@ -285,7 +288,7 @@ static constexpr double exp10_set_exceptional(double x) {
namespace math {
-static constexpr double exp10(double x) {
+LIBC_INLINE static constexpr double exp10(double x) {
using FPBits = typename fputil::FPBits<double>;
FPBits xbits(x);
diff --git a/libc/src/__support/math/exp10_float16_constants.h b/libc/src/__support/math/exp10_float16_constants.h
index f5928db..ef50185 100644
--- a/libc/src/__support/math/exp10_float16_constants.h
+++ b/libc/src/__support/math/exp10_float16_constants.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXP10_FLOAT16_CONSTANTS_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP10_FLOAT16_CONSTANTS_H
+#include "hdr/stdint_proxy.h"
#include "include/llvm-libc-macros/float16-macros.h"
-#include <stdint.h>
#ifdef LIBC_TYPES_HAS_FLOAT16
diff --git a/libc/src/__support/math/exp10f.h b/libc/src/__support/math/exp10f.h
index 807b4f0..76ae197 100644
--- a/libc/src/__support/math/exp10f.h
+++ b/libc/src/__support/math/exp10f.h
@@ -20,7 +20,7 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float exp10f(float x) {
+LIBC_INLINE static constexpr float exp10f(float x) {
using FPBits = typename fputil::FPBits<float>;
FPBits xbits(x);
diff --git a/libc/src/__support/math/exp10f16.h b/libc/src/__support/math/exp10f16.h
index 0d8b125..3eca867 100644
--- a/libc/src/__support/math/exp10f16.h
+++ b/libc/src/__support/math/exp10f16.h
@@ -57,7 +57,7 @@ static constexpr fputil::ExceptValues<float16, N_EXP10F16_EXCEPTS>
}};
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr float16 exp10f16(float16 x) {
+LIBC_INLINE static constexpr float16 exp10f16(float16 x) {
using FPBits = fputil::FPBits<float16>;
FPBits x_bits(x);
diff --git a/libc/src/__support/math/exp10f16_utils.h b/libc/src/__support/math/exp10f16_utils.h
index bffb81b..5952a41 100644
--- a/libc/src/__support/math/exp10f16_utils.h
+++ b/libc/src/__support/math/exp10f16_utils.h
@@ -19,8 +19,7 @@
namespace LIBC_NAMESPACE_DECL {
-LIBC_INLINE static constexpr ExpRangeReduction
-exp10_range_reduction(float16 x) {
+LIBC_INLINE static ExpRangeReduction exp10_range_reduction(float16 x) {
// For -8 < x < 5, to compute 10^x, we perform the following range reduction:
// find hi, mid, lo, such that:
// x = (hi + mid) * log2(10) + lo, in which
diff --git a/libc/src/__support/math/exp10f_utils.h b/libc/src/__support/math/exp10f_utils.h
index c30def9..010a2f1 100644
--- a/libc/src/__support/math/exp10f_utils.h
+++ b/libc/src/__support/math/exp10f_utils.h
@@ -89,7 +89,7 @@ struct Exp10Base : public ExpBase {
0x1.0470591dff149p1, 0x1.2bd7c0a9fbc4dp0,
0x1.1429e74a98f43p-1};
- static double powb_lo(double dx) {
+ LIBC_INLINE static double powb_lo(double dx) {
using fputil::multiply_add;
double dx2 = dx * dx;
// c0 = 1 + COEFFS[0] * dx
diff --git a/libc/src/__support/math/exp_utils.h b/libc/src/__support/math/exp_utils.h
index fc9ab10..ef408ed 100644
--- a/libc/src/__support/math/exp_utils.h
+++ b/libc/src/__support/math/exp_utils.h
@@ -22,8 +22,8 @@ namespace LIBC_NAMESPACE_DECL {
// So if we scale x up by 2^1022, we can use
// double(1.0 + 2^1022 * x) - 1.0 to test how x is rounded in denormal range.
template <bool SKIP_ZIV_TEST = false>
-static constexpr cpp::optional<double> ziv_test_denorm(int hi, double mid,
- double lo, double err) {
+LIBC_INLINE static constexpr cpp::optional<double>
+ziv_test_denorm(int hi, double mid, double lo, double err) {
using FPBits = typename fputil::FPBits<double>;
// Scaling factor = 1/(min normal number) = 2^1022
diff --git a/libc/src/__support/math/expf.h b/libc/src/__support/math/expf.h
index 88c1514..f7e11be 100644
--- a/libc/src/__support/math/expf.h
+++ b/libc/src/__support/math/expf.h
@@ -24,7 +24,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float expf(float x) {
+LIBC_INLINE static constexpr float expf(float x) {
using FPBits = typename fputil::FPBits<float>;
FPBits xbits(x);
diff --git a/libc/src/__support/math/expf16.h b/libc/src/__support/math/expf16.h
index ded28c7..14302a7 100644
--- a/libc/src/__support/math/expf16.h
+++ b/libc/src/__support/math/expf16.h
@@ -31,7 +31,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float16 expf16(float16 x) {
+LIBC_INLINE static constexpr float16 expf16(float16 x) {
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
constexpr fputil::ExceptValues<float16, 2> EXPF16_EXCEPTS_LO = {{
// (input, RZ output, RU offset, RD offset, RN offset)
diff --git a/libc/src/__support/math/expf16_utils.h b/libc/src/__support/math/expf16_utils.h
index 8a2fc94..4204dab7 100644
--- a/libc/src/__support/math/expf16_utils.h
+++ b/libc/src/__support/math/expf16_utils.h
@@ -47,7 +47,8 @@ struct ExpRangeReduction {
float exp_lo;
};
-[[maybe_unused]] static ExpRangeReduction exp_range_reduction(float16 x) {
+[[maybe_unused]] LIBC_INLINE static ExpRangeReduction
+exp_range_reduction(float16 x) {
// For -18 < x < 12, to compute exp(x), we perform the following range
// reduction: find hi, mid, lo, such that:
// x = hi + mid + lo, in which
diff --git a/libc/src/__support/math/frexpf.h b/libc/src/__support/math/frexpf.h
index 4d2f494..7834a12 100644
--- a/libc/src/__support/math/frexpf.h
+++ b/libc/src/__support/math/frexpf.h
@@ -17,7 +17,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float frexpf(float x, int *exp) {
+LIBC_INLINE static constexpr float frexpf(float x, int *exp) {
return fputil::frexp(x, *exp);
}
diff --git a/libc/src/__support/math/frexpf128.h b/libc/src/__support/math/frexpf128.h
index 2fd5bc4..5218b26 100644
--- a/libc/src/__support/math/frexpf128.h
+++ b/libc/src/__support/math/frexpf128.h
@@ -21,7 +21,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float128 frexpf128(float128 x, int *exp) {
+LIBC_INLINE static constexpr float128 frexpf128(float128 x, int *exp) {
return fputil::frexp(x, *exp);
}
diff --git a/libc/src/__support/math/frexpf16.h b/libc/src/__support/math/frexpf16.h
index 8deeba0..530b61a 100644
--- a/libc/src/__support/math/frexpf16.h
+++ b/libc/src/__support/math/frexpf16.h
@@ -21,7 +21,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float16 frexpf16(float16 x, int *exp) {
+LIBC_INLINE static constexpr float16 frexpf16(float16 x, int *exp) {
return fputil::frexp(x, *exp);
}
diff --git a/libc/src/__support/math/ldexpf.h b/libc/src/__support/math/ldexpf.h
index 3a5ec1d..9ef5d96 100644
--- a/libc/src/__support/math/ldexpf.h
+++ b/libc/src/__support/math/ldexpf.h
@@ -17,7 +17,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float ldexpf(float x, int exp) {
+LIBC_INLINE static constexpr float ldexpf(float x, int exp) {
return fputil::ldexp(x, exp);
}
diff --git a/libc/src/__support/math/ldexpf128.h b/libc/src/__support/math/ldexpf128.h
index 3625830..4fba20c 100644
--- a/libc/src/__support/math/ldexpf128.h
+++ b/libc/src/__support/math/ldexpf128.h
@@ -21,7 +21,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float128 ldexpf128(float128 x, int exp) {
+LIBC_INLINE static constexpr float128 ldexpf128(float128 x, int exp) {
return fputil::ldexp(x, exp);
}
diff --git a/libc/src/__support/math/ldexpf16.h b/libc/src/__support/math/ldexpf16.h
index fbead87..d978d22 100644
--- a/libc/src/__support/math/ldexpf16.h
+++ b/libc/src/__support/math/ldexpf16.h
@@ -21,7 +21,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-static constexpr float16 ldexpf16(float16 x, int exp) {
+LIBC_INLINE static constexpr float16 ldexpf16(float16 x, int exp) {
return fputil::ldexp(x, exp);
}
diff --git a/libc/src/__support/ryu_constants.h b/libc/src/__support/ryu_constants.h
index 1ecb34e..09bc235 100644
--- a/libc/src/__support/ryu_constants.h
+++ b/libc/src/__support/ryu_constants.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_RYU_CONSTANTS_H
#define LLVM_LIBC_SRC___SUPPORT_RYU_CONSTANTS_H
+#include "hdr/stdint_proxy.h"
#include <stddef.h>
-#include <stdint.h>
constexpr size_t TABLE_SHIFT_CONST = 120;
constexpr size_t IDX_SIZE = 16;
diff --git a/libc/src/__support/ryu_long_double_constants.h b/libc/src/__support/ryu_long_double_constants.h
index 8ebb297..487fd4a 100644
--- a/libc/src/__support/ryu_long_double_constants.h
+++ b/libc/src/__support/ryu_long_double_constants.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_RYU_LONG_DOUBLE_CONSTANTS_H
#define LLVM_LIBC_SRC___SUPPORT_RYU_LONG_DOUBLE_CONSTANTS_H
+#include "hdr/stdint_proxy.h"
#include <stddef.h>
-#include <stdint.h>
constexpr size_t TABLE_SHIFT_CONST = 120;
constexpr size_t IDX_SIZE = 128;
diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h
index a7dd7ce..3d35d8a 100644
--- a/libc/src/__support/str_to_float.h
+++ b/libc/src/__support/str_to_float.h
@@ -16,6 +16,7 @@
#define LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H
#include "hdr/errno_macros.h" // For ERANGE
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/optional.h"
@@ -33,8 +34,6 @@
#include "src/__support/str_to_num_result.h"
#include "src/__support/uint128.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/__support/threads/CMakeLists.txt b/libc/src/__support/threads/CMakeLists.txt
index bd49bbb..b084346 100644
--- a/libc/src/__support/threads/CMakeLists.txt
+++ b/libc/src/__support/threads/CMakeLists.txt
@@ -49,6 +49,7 @@ add_header_library(
HDRS
thread.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.CPP.atomic
libc.src.__support.CPP.optional
@@ -64,6 +65,7 @@ if(TARGET libc.src.__support.threads.${LIBC_TARGET_OS}.thread)
DEPENDS
.mutex
.${LIBC_TARGET_OS}.thread
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.fixedvector
libc.src.__support.CPP.array
diff --git a/libc/src/__support/threads/CndVar.h b/libc/src/__support/threads/CndVar.h
index e42fa14..7b2a712 100644
--- a/libc/src/__support/threads/CndVar.h
+++ b/libc/src/__support/threads/CndVar.h
@@ -9,13 +9,12 @@
#ifndef LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_CNDVAR_H
#define LLVM_LIBC___SUPPORT_SRC_THREADS_LINUX_CNDVAR_H
+#include "hdr/stdint_proxy.h" // uint32_t
#include "src/__support/macros/config.h"
#include "src/__support/threads/linux/futex_utils.h" // Futex
#include "src/__support/threads/linux/raw_mutex.h" // RawMutex
#include "src/__support/threads/mutex.h" // Mutex
-#include <stdint.h> // uint32_t
-
namespace LIBC_NAMESPACE_DECL {
class CndVar {
diff --git a/libc/src/__support/threads/linux/CMakeLists.txt b/libc/src/__support/threads/linux/CMakeLists.txt
index 364e7e2..cbb7886 100644
--- a/libc/src/__support/threads/linux/CMakeLists.txt
+++ b/libc/src/__support/threads/linux/CMakeLists.txt
@@ -2,6 +2,8 @@ add_header_library(
futex_word_type
HDRS
futex_word.h
+ DEPENDS
+ libc.hdr.stdint_proxy
)
if(NOT TARGET libc.src.__support.OSUtil.osutil)
@@ -114,6 +116,7 @@ add_object_library(
HDRS
../CndVar.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.__support.threads.linux.futex_word_type
diff --git a/libc/src/__support/threads/linux/futex_word.h b/libc/src/__support/threads/linux/futex_word.h
index a5a6a0c..1cf7bef 100644
--- a/libc/src/__support/threads/linux/futex_word.h
+++ b/libc/src/__support/threads/linux/futex_word.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_FUTEX_WORD_H
#define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_FUTEX_WORD_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
#include <sys/syscall.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index baad26a..d9e479ee 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -23,10 +23,10 @@
#endif
#include "hdr/fcntl_macros.h"
+#include "hdr/stdint_proxy.h"
#include <linux/param.h> // For EXEC_PAGESIZE.
#include <linux/prctl.h> // For PR_SET_NAME
#include <linux/sched.h> // For CLONE_* flags.
-#include <stdint.h>
#include <sys/mman.h> // For PROT_* and MAP_* definitions.
#include <sys/syscall.h> // For syscall numbers.
diff --git a/libc/src/__support/threads/thread.h b/libc/src/__support/threads/thread.h
index f2b1f6b..114ab49 100644
--- a/libc/src/__support/threads/thread.h
+++ b/libc/src/__support/threads/thread.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_THREAD_H
#define LLVM_LIBC_SRC___SUPPORT_THREADS_THREAD_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/CPP/string_view.h"
@@ -21,7 +22,6 @@
#include <linux/param.h> // for exec_pagesize.
#include <stddef.h> // For size_t
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/wchar/CMakeLists.txt b/libc/src/__support/wchar/CMakeLists.txt
index 802441d..e363ad3 100644
--- a/libc/src/__support/wchar/CMakeLists.txt
+++ b/libc/src/__support/wchar/CMakeLists.txt
@@ -3,7 +3,8 @@ add_header_library(
HDRS
mbstate.h
DEPENDS
- libc.hdr.types.char32_t
+ libc.hdr.stdint_proxy
+ libc.hdr.types.char32_t
)
add_header_library(
@@ -68,3 +69,20 @@ add_object_library(
.character_converter
.mbstate
)
+
+add_header_library(
+ wcsnrtombs
+ HDRS
+ wcsnrtombs.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.types.char8_t
+ libc.hdr.types.char32_t
+ libc.hdr.types.size_t
+ libc.hdr.types.wchar_t
+ libc.src.__support.error_or
+ libc.src.__support.common
+ .string_converter
+ .character_converter
+ .mbstate
+)
diff --git a/libc/src/__support/wchar/mbstate.h b/libc/src/__support/wchar/mbstate.h
index 32304a5..96256ca 100644
--- a/libc/src/__support/wchar/mbstate.h
+++ b/libc/src/__support/wchar/mbstate.h
@@ -9,9 +9,9 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MBSTATE_H
#define LLVM_LIBC_SRC___SUPPORT_MBSTATE_H
+#include "hdr/stdint_proxy.h"
#include "hdr/types/char32_t.h"
#include "src/__support/common.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/__support/wchar/wcsnrtombs.h b/libc/src/__support/wchar/wcsnrtombs.h
new file mode 100644
index 0000000..433097c
--- /dev/null
+++ b/libc/src/__support/wchar/wcsnrtombs.h
@@ -0,0 +1,69 @@
+//===-- Implementation header for wcsnrtombs ------------------------------===//
+//
+// 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__SUPPORT_WCHAR_WCSNRTOMBS_H
+#define LLVM_LIBC_SRC__SUPPORT_WCHAR_WCSNRTOMBS_H
+
+#include "hdr/types/char32_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+#include "src/__support/wchar/mbstate.h"
+#include "src/__support/wchar/string_converter.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+LIBC_INLINE static ErrorOr<size_t>
+wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src,
+ size_t num_src_widechars, size_t dest_len, mbstate *ps) {
+ LIBC_CRASH_ON_NULLPTR(ptr_to_src);
+ LIBC_CRASH_ON_NULLPTR(ps);
+
+ CharacterConverter cr(ps);
+ if (!cr.isValidState())
+ return Error(EINVAL);
+
+ if (dest == nullptr)
+ dest_len = SIZE_MAX;
+
+ StringConverter<char32_t> str_conv(
+ 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();
+ while (converted.has_value()) {
+ if (dest != nullptr)
+ dest[dst_idx] = converted.value();
+
+ if (converted.value() == '\0') {
+ if (dest != nullptr)
+ *ptr_to_src = nullptr;
+ return dst_idx;
+ }
+
+ dst_idx++;
+ converted = str_conv.popUTF8();
+ }
+
+ if (dest != nullptr)
+ *ptr_to_src += str_conv.getSourceIndex();
+
+ if (converted.error() == -1) // if we hit conversion limit
+ return dst_idx;
+
+ return Error(converted.error());
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC__SUPPORT_WCHAR_WCSNRTOMBS_H
diff --git a/libc/src/arpa/inet/CMakeLists.txt b/libc/src/arpa/inet/CMakeLists.txt
index cdd53e9..1f39a07 100644
--- a/libc/src/arpa/inet/CMakeLists.txt
+++ b/libc/src/arpa/inet/CMakeLists.txt
@@ -5,6 +5,7 @@ add_entrypoint_object(
HDRS
htonl.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.arpa_inet
libc.src.__support.common
)
@@ -16,6 +17,7 @@ add_entrypoint_object(
HDRS
htons.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.arpa_inet
libc.src.__support.common
)
@@ -27,6 +29,7 @@ add_entrypoint_object(
HDRS
ntohl.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.arpa_inet
libc.src.__support.common
)
@@ -38,6 +41,7 @@ add_entrypoint_object(
HDRS
ntohs.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.arpa_inet
libc.src.__support.common
)
diff --git a/libc/src/arpa/inet/htonl.h b/libc/src/arpa/inet/htonl.h
index e444972..34f017d 100644
--- a/libc/src/arpa/inet/htonl.h
+++ b/libc/src/arpa/inet/htonl.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC_ARPA_INET_HTONL_H
#define LLVM_LIBC_SRC_ARPA_INET_HTONL_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/arpa/inet/htons.h b/libc/src/arpa/inet/htons.h
index 35c2acdc..5e283cd 100644
--- a/libc/src/arpa/inet/htons.h
+++ b/libc/src/arpa/inet/htons.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC_ARPA_INET_HTONS_H
#define LLVM_LIBC_SRC_ARPA_INET_HTONS_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/arpa/inet/ntohl.h b/libc/src/arpa/inet/ntohl.h
index 4007965..76ba02b 100644
--- a/libc/src/arpa/inet/ntohl.h
+++ b/libc/src/arpa/inet/ntohl.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC_ARPA_INET_NTOHL_H
#define LLVM_LIBC_SRC_ARPA_INET_NTOHL_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/arpa/inet/ntohs.h b/libc/src/arpa/inet/ntohs.h
index 5fe3ebc..b98c852 100644
--- a/libc/src/arpa/inet/ntohs.h
+++ b/libc/src/arpa/inet/ntohs.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC_ARPA_INET_NTOHS_H
#define LLVM_LIBC_SRC_ARPA_INET_NTOHS_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/compiler/generic/CMakeLists.txt b/libc/src/compiler/generic/CMakeLists.txt
index 2fc8f7f..d9ad42e 100644
--- a/libc/src/compiler/generic/CMakeLists.txt
+++ b/libc/src/compiler/generic/CMakeLists.txt
@@ -5,6 +5,7 @@ add_entrypoint_object(
HDRS
../__stack_chk_fail.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.OSUtil.osutil
libc.src.stdlib.abort
)
diff --git a/libc/src/compiler/generic/__stack_chk_fail.cpp b/libc/src/compiler/generic/__stack_chk_fail.cpp
index 00e976a..7edd16c 100644
--- a/libc/src/compiler/generic/__stack_chk_fail.cpp
+++ b/libc/src/compiler/generic/__stack_chk_fail.cpp
@@ -7,9 +7,9 @@
//===----------------------------------------------------------------------===//
#include "src/compiler/__stack_chk_fail.h"
+#include "hdr/stdint_proxy.h" // For uintptr_t
#include "src/__support/OSUtil/io.h"
#include "src/stdlib/abort.h"
-#include <stdint.h> // For uintptr_t
extern "C" {
diff --git a/libc/src/inttypes/CMakeLists.txt b/libc/src/inttypes/CMakeLists.txt
index c3111ed..3a48c9a 100644
--- a/libc/src/inttypes/CMakeLists.txt
+++ b/libc/src/inttypes/CMakeLists.txt
@@ -5,6 +5,7 @@ add_entrypoint_object(
HDRS
strtoimax.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.str_to_integer
libc.src.errno.errno
)
@@ -16,6 +17,7 @@ add_entrypoint_object(
HDRS
strtoumax.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.str_to_integer
libc.src.errno.errno
)
diff --git a/libc/src/inttypes/strtoimax.h b/libc/src/inttypes/strtoimax.h
index 804d07c..fedc458b 100644
--- a/libc/src/inttypes/strtoimax.h
+++ b/libc/src/inttypes/strtoimax.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC_INTTYPES_STRTOIMAX_H
#define LLVM_LIBC_SRC_INTTYPES_STRTOIMAX_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/inttypes/strtoumax.h b/libc/src/inttypes/strtoumax.h
index 4c53c03..d5b82af 100644
--- a/libc/src/inttypes/strtoumax.h
+++ b/libc/src/inttypes/strtoumax.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_SRC_INTTYPES_STRTOUMAX_H
#define LLVM_LIBC_SRC_INTTYPES_STRTOUMAX_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/link/CMakeLists.txt b/libc/src/link/CMakeLists.txt
index f68950e..55f5edf 100644
--- a/libc/src/link/CMakeLists.txt
+++ b/libc/src/link/CMakeLists.txt
@@ -4,4 +4,6 @@ add_entrypoint_object(
dl_iterate_phdr.cpp
HDRS
dl_iterate_phdr.h
+ DEPENDS
+ libc.hdr.stdint_proxy
)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 408f99e..ecf0967 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3958,13 +3958,7 @@ add_entrypoint_object(
HDRS
../asinf.h
DEPENDS
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.sqrt
- libc.src.__support.macros.optimization
- libc.src.__support.math.inv_trigf_utils
+ libc.src.__support.math.asinf
)
add_entrypoint_object(
@@ -3993,16 +3987,7 @@ add_entrypoint_object(
HDRS
../asin.h
DEPENDS
- libc.src.__support.math.asin_utils
- libc.src.__support.FPUtil.double_double
- libc.src.__support.FPUtil.dyadic_float
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.sqrt
- libc.src.__support.macros.optimization
- libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.math.asin
)
add_entrypoint_object(
@@ -4043,16 +4028,8 @@ add_entrypoint_object(
HDRS
../acospif16.h
DEPENDS
- libc.hdr.errno_macros
- libc.hdr.fenv_macros
- libc.src.__support.FPUtil.cast
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.sqrt
- libc.src.__support.macros.optimization
- libc.src.__support.macros.properties.types
+ libc.src.__support.math.acospif16
+ libc.src.errno.errno
)
add_header_library(
@@ -4942,6 +4919,7 @@ add_header_library(
HDRS
expxf16.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.multiply_add
diff --git a/libc/src/math/generic/acospif16.cpp b/libc/src/math/generic/acospif16.cpp
index bfdf169..09cbd99 100644
--- a/libc/src/math/generic/acospif16.cpp
+++ b/libc/src/math/generic/acospif16.cpp
@@ -7,128 +7,12 @@
//===----------------------------------------------------------------------===//
#include "src/math/acospif16.h"
-#include "hdr/errno_macros.h"
-#include "hdr/fenv_macros.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/cast.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/macros/optimization.h"
+#include "src/__support/math/acospif16.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float16, acospif16, (float16 x)) {
- using FPBits = fputil::FPBits<float16>;
- FPBits xbits(x);
-
- uint16_t x_u = xbits.uintval();
- uint16_t x_abs = x_u & 0x7fff;
- uint16_t x_sign = x_u >> 15;
-
- // |x| > 0x1p0, |x| > 1, or x is NaN.
- if (LIBC_UNLIKELY(x_abs > 0x3c00)) {
- // acospif16(NaN) = NaN
- if (xbits.is_nan()) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- return x;
- }
-
- // 1 < |x| <= +inf
- fputil::raise_except_if_required(FE_INVALID);
- fputil::set_errno_if_required(EDOM);
-
- return FPBits::quiet_nan().get_val();
- }
-
- // |x| == 0x1p0, x is 1 or -1
- // if x is (-)1, return 1
- // if x is (+)1, return 0
- if (LIBC_UNLIKELY(x_abs == 0x3c00))
- return fputil::cast<float16>(x_sign ? 1.0f : 0.0f);
-
- float xf = x;
- float xsq = xf * xf;
-
- // Degree-6 minimax polynomial coefficients of asin(x) generated by Sollya
- // with: > P = fpminimax(asin(x)/(pi * x), [|0, 2, 4, 6, 8|], [|SG...|], [0,
- // 0.5]);
- constexpr float POLY_COEFFS[5] = {0x1.45f308p-2f, 0x1.b2900cp-5f,
- 0x1.897e36p-6f, 0x1.9efafcp-7f,
- 0x1.06d884p-6f};
- // |x| <= 0x1p-1, |x| <= 0.5
- if (x_abs <= 0x3800) {
- // if x is 0, return 0.5
- if (LIBC_UNLIKELY(x_abs == 0))
- return fputil::cast<float16>(0.5f);
-
- // Note that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x), then
- // acospi(x) = 0.5 - asin(x)/pi
- float interm =
- fputil::polyeval(xsq, POLY_COEFFS[0], POLY_COEFFS[1], POLY_COEFFS[2],
- POLY_COEFFS[3], POLY_COEFFS[4]);
-
- return fputil::cast<float16>(fputil::multiply_add(-xf, interm, 0.5f));
- }
-
- // When |x| > 0.5, assume that 0.5 < |x| <= 1
- //
- // Step-by-step range-reduction proof:
- // 1: Let y = asin(x), such that, x = sin(y)
- // 2: From complimentary angle identity:
- // x = sin(y) = cos(pi/2 - y)
- // 3: Let z = pi/2 - y, such that x = cos(z)
- // 4: From double angle formula; cos(2A) = 1 - 2 * sin^2(A):
- // z = 2A, z/2 = A
- // cos(z) = 1 - 2 * sin^2(z/2)
- // 5: Make sin(z/2) subject of the formula:
- // sin(z/2) = sqrt((1 - cos(z))/2)
- // 6: Recall [3]; x = cos(z). Therefore:
- // sin(z/2) = sqrt((1 - x)/2)
- // 7: Let u = (1 - x)/2
- // 8: Therefore:
- // asin(sqrt(u)) = z/2
- // 2 * asin(sqrt(u)) = z
- // 9: Recall [3]; z = pi/2 - y. Therefore:
- // y = pi/2 - z
- // y = pi/2 - 2 * asin(sqrt(u))
- // 10: Recall [1], y = asin(x). Therefore:
- // asin(x) = pi/2 - 2 * asin(sqrt(u))
- // 11: Recall that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x)
- // Therefore:
- // acos(x) = pi/2 - (pi/2 - 2 * asin(sqrt(u)))
- // acos(x) = 2 * asin(sqrt(u))
- // acospi(x) = 2 * (asin(sqrt(u)) / pi)
- //
- // THE RANGE REDUCTION, HOW?
- // 12: Recall [7], u = (1 - x)/2
- // 13: Since 0.5 < x <= 1, therefore:
- // 0 <= u <= 0.25 and 0 <= sqrt(u) <= 0.5
- //
- // Hence, we can reuse the same [0, 0.5] domain polynomial approximation for
- // Step [11] as `sqrt(u)` is in range.
- // When -1 < x <= -0.5, the identity:
- // acos(x) = pi - acos(-x)
- // acospi(x) = 1 - acos(-x)/pi
- // allows us to compute for the negative x value (lhs)
- // with a positive x value instead (rhs).
-
- float xf_abs = (xf < 0 ? -xf : xf);
- float u = fputil::multiply_add(-0.5f, xf_abs, 0.5f);
- float sqrt_u = fputil::sqrt<float>(u);
-
- float asin_sqrt_u =
- sqrt_u * fputil::polyeval(u, POLY_COEFFS[0], POLY_COEFFS[1],
- POLY_COEFFS[2], POLY_COEFFS[3], POLY_COEFFS[4]);
-
- // Same as acos(x), but devided the expression with pi
- return fputil::cast<float16>(
- x_sign ? fputil::multiply_add(-2.0f, asin_sqrt_u, 1.0f)
- : 2.0f * asin_sqrt_u);
+ return math::acospif16(x);
}
+
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/asin.cpp b/libc/src/math/generic/asin.cpp
index d286fce..b5ba9ea 100644
--- a/libc/src/math/generic/asin.cpp
+++ b/libc/src/math/generic/asin.cpp
@@ -7,23 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/asin.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/double_double.h"
-#include "src/__support/FPUtil/dyadic_float.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
-#include "src/__support/math/asin_utils.h"
+#include "src/__support/math/asin.h"
namespace LIBC_NAMESPACE_DECL {
-using DoubleDouble = fputil::DoubleDouble;
-using Float128 = fputil::DyadicFloat<128>;
-
LLVM_LIBC_FUNCTION(double, asin, (double x)) {
using namespace asin_internal;
using FPBits = fputil::FPBits<double>;
diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp
index 77d6de9..9c6766f 100644
--- a/libc/src/math/generic/asinf.cpp
+++ b/libc/src/math/generic/asinf.cpp
@@ -7,161 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/asinf.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
-
-#include "src/__support/math/inv_trigf_utils.h"
+#include "src/__support/math/asinf.h"
namespace LIBC_NAMESPACE_DECL {
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr size_t N_EXCEPTS = 2;
-
-// Exceptional values when |x| <= 0.5
-static constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_LO = {{
- // (inputs, RZ output, RU offset, RD offset, RN offset)
- // x = 0x1.137f0cp-5, asinf(x) = 0x1.138c58p-5 (RZ)
- {0x3d09bf86, 0x3d09c62c, 1, 0, 1},
- // x = 0x1.cbf43cp-4, asinf(x) = 0x1.cced1cp-4 (RZ)
- {0x3de5fa1e, 0x3de6768e, 1, 0, 0},
-}};
-
-// Exceptional values when 0.5 < |x| <= 1
-static constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_HI = {{
- // (inputs, RZ output, RU offset, RD offset, RN offset)
- // x = 0x1.107434p-1, asinf(x) = 0x1.1f4b64p-1 (RZ)
- {0x3f083a1a, 0x3f0fa5b2, 1, 0, 0},
- // x = 0x1.ee836cp-1, asinf(x) = 0x1.4f0654p0 (RZ)
- {0x3f7741b6, 0x3fa7832a, 1, 0, 0},
-}};
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
- using namespace inv_trigf_utils_internal;
- using FPBits = typename fputil::FPBits<float>;
-
- FPBits xbits(x);
- uint32_t x_uint = xbits.uintval();
- uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU;
- constexpr double SIGN[2] = {1.0, -1.0};
- uint32_t x_sign = x_uint >> 31;
-
- // |x| <= 0.5-ish
- if (x_abs < 0x3f04'471dU) {
- // |x| < 0x1.d12edp-12
- if (LIBC_UNLIKELY(x_abs < 0x39e8'9768U)) {
- // When |x| < 2^-12, the relative error of the approximation asin(x) ~ x
- // is:
- // |asin(x) - x| / |asin(x)| < |x^3| / (6|x|)
- // = x^2 / 6
- // < 2^-25
- // < epsilon(1)/2.
- // So the correctly rounded values of asin(x) are:
- // = x + sign(x)*eps(x) if rounding mode = FE_TOWARDZERO,
- // or (rounding mode = FE_UPWARD and x is
- // negative),
- // = x otherwise.
- // To simplify the rounding decision and make it more efficient, we use
- // fma(x, 2^-25, x) instead.
- // An exhaustive test shows that this formula work correctly for all
- // rounding modes up to |x| < 0x1.d12edp-12.
- // Note: to use the formula x + 2^-25*x to decide the correct rounding, we
- // do need fma(x, 2^-25, x) to prevent underflow caused by 2^-25*x when
- // |x| < 2^-125. For targets without FMA instructions, we simply use
- // double for intermediate results as it is more efficient than using an
- // emulated version of FMA.
-#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT)
- return fputil::multiply_add(x, 0x1.0p-25f, x);
-#else
- double xd = static_cast<double>(x);
- return static_cast<float>(fputil::multiply_add(xd, 0x1.0p-25, xd));
-#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
- }
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Check for exceptional values
- if (auto r = ASINF_EXCEPTS_LO.lookup_odd(x_abs, x_sign);
- LIBC_UNLIKELY(r.has_value()))
- return r.value();
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // For |x| <= 0.5, we approximate asinf(x) by:
- // asin(x) = x * P(x^2)
- // Where P(X^2) = Q(X) is a degree-20 minimax even polynomial approximating
- // asin(x)/x on [0, 0.5] generated by Sollya with:
- // > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|],
- // [|1, D...|], [0, 0.5]);
- // An exhaustive test shows that this approximation works well up to a
- // little more than 0.5.
- double xd = static_cast<double>(x);
- double xsq = xd * xd;
- double x3 = xd * xsq;
- double r = asin_eval(xsq);
- return static_cast<float>(fputil::multiply_add(x3, r, xd));
- }
-
- // |x| > 1, return NaNs.
- if (LIBC_UNLIKELY(x_abs > 0x3f80'0000U)) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- if (x_abs <= 0x7f80'0000U) {
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- }
-
- return FPBits::quiet_nan().get_val();
- }
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Check for exceptional values
- if (auto r = ASINF_EXCEPTS_HI.lookup_odd(x_abs, x_sign);
- LIBC_UNLIKELY(r.has_value()))
- return r.value();
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // When |x| > 0.5, we perform range reduction as follow:
- //
- // Assume further that 0.5 < x <= 1, and let:
- // y = asin(x)
- // We will use the double angle formula:
- // cos(2y) = 1 - 2 sin^2(y)
- // and the complement angle identity:
- // x = sin(y) = cos(pi/2 - y)
- // = 1 - 2 sin^2 (pi/4 - y/2)
- // So:
- // sin(pi/4 - y/2) = sqrt( (1 - x)/2 )
- // And hence:
- // pi/4 - y/2 = asin( sqrt( (1 - x)/2 ) )
- // Equivalently:
- // asin(x) = y = pi/2 - 2 * asin( sqrt( (1 - x)/2 ) )
- // Let u = (1 - x)/2, then:
- // asin(x) = pi/2 - 2 * asin( sqrt(u) )
- // Moreover, since 0.5 < x <= 1:
- // 0 <= u < 1/4, and 0 <= sqrt(u) < 0.5,
- // And hence we can reuse the same polynomial approximation of asin(x) when
- // |x| <= 0.5:
- // asin(x) ~ pi/2 - 2 * sqrt(u) * P(u),
-
- xbits.set_sign(Sign::POS);
- double sign = SIGN[x_sign];
- double xd = static_cast<double>(xbits.get_val());
- double u = fputil::multiply_add(-0.5, xd, 0.5);
- double c1 = sign * (-2 * fputil::sqrt<double>(u));
- double c2 = fputil::multiply_add(sign, M_MATH_PI_2, c1);
- double c3 = c1 * u;
-
- double r = asin_eval(u);
- return static_cast<float>(fputil::multiply_add(c3, r, c2));
-}
+LLVM_LIBC_FUNCTION(float, asinf, (float x)) { return math::asinf(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/expxf16.h b/libc/src/math/generic/expxf16.h
index b17b14f..562a427 100644
--- a/libc/src/math/generic/expxf16.h
+++ b/libc/src/math/generic/expxf16.h
@@ -9,14 +9,13 @@
#ifndef LLVM_LIBC_SRC_MATH_GENERIC_EXPXF16_H
#define LLVM_LIBC_SRC_MATH_GENERIC_EXPXF16_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/FPUtil/nearest_integer.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
#include "src/__support/math/exp10_float16_constants.h"
#include "src/__support/math/expf16_utils.h"
diff --git a/libc/src/math/generic/range_reduction_double_common.h b/libc/src/math/generic/range_reduction_double_common.h
index f3dcdb9..a93ee25 100644
--- a/libc/src/math/generic/range_reduction_double_common.h
+++ b/libc/src/math/generic/range_reduction_double_common.h
@@ -278,7 +278,7 @@ private:
};
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static Float128 range_reduction_small_f128(double x) {
+LIBC_INLINE static Float128 range_reduction_small_f128(double x) {
constexpr Float128 PI_OVER_128_F128 = {
Sign::POS, -133, 0xc90f'daa2'2168'c234'c4c6'628b'80dc'1cd1_u128};
constexpr double ONE_TWENTY_EIGHT_OVER_PI_D = 0x1.45f306dc9c883p5;
diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt
index c8c6680..c5db6fa 100644
--- a/libc/src/pthread/CMakeLists.txt
+++ b/libc/src/pthread/CMakeLists.txt
@@ -99,6 +99,7 @@ add_entrypoint_object(
HDRS
pthread_attr_setstack.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.pthread
libc.src.pthread.pthread_attr_setstacksize
libc.src.errno.errno
diff --git a/libc/src/pthread/pthread_attr_setstack.cpp b/libc/src/pthread/pthread_attr_setstack.cpp
index 767f959..b66072c 100644
--- a/libc/src/pthread/pthread_attr_setstack.cpp
+++ b/libc/src/pthread/pthread_attr_setstack.cpp
@@ -9,13 +9,13 @@
#include "pthread_attr_setstack.h"
#include "pthread_attr_setstacksize.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/threads/thread.h" // For STACK_ALIGNMENT
#include <pthread.h>
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/sched/linux/CMakeLists.txt b/libc/src/sched/linux/CMakeLists.txt
index 4852c90..e690e76 100644
--- a/libc/src/sched/linux/CMakeLists.txt
+++ b/libc/src/sched/linux/CMakeLists.txt
@@ -5,6 +5,7 @@ add_entrypoint_object(
HDRS
../sched_getaffinity.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.sched
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
diff --git a/libc/src/sched/linux/sched_getaffinity.cpp b/libc/src/sched/linux/sched_getaffinity.cpp
index e005819..4a5e91a 100644
--- a/libc/src/sched/linux/sched_getaffinity.cpp
+++ b/libc/src/sched/linux/sched_getaffinity.cpp
@@ -8,13 +8,13 @@
#include "src/sched/sched_getaffinity.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include <sched.h>
-#include <stdint.h>
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/setjmp/aarch64/CMakeLists.txt b/libc/src/setjmp/aarch64/CMakeLists.txt
index 1078af8..1299110 100644
--- a/libc/src/setjmp/aarch64/CMakeLists.txt
+++ b/libc/src/setjmp/aarch64/CMakeLists.txt
@@ -34,7 +34,7 @@ add_entrypoint_object(
HDRS
../sigsetjmp.h
DEPENDS
- libc.hdr.types.jmp_buf
+ libc.hdr.types.sigjmp_buf
libc.hdr.types.sigset_t
libc.hdr.offsetof_macros
libc.src.setjmp.sigsetjmp_epilogue
diff --git a/libc/src/setjmp/arm/CMakeLists.txt b/libc/src/setjmp/arm/CMakeLists.txt
index 77f8471..7a48da3 100644
--- a/libc/src/setjmp/arm/CMakeLists.txt
+++ b/libc/src/setjmp/arm/CMakeLists.txt
@@ -16,7 +16,7 @@ if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
HDRS
../sigsetjmp.h
DEPENDS
- libc.hdr.types.jmp_buf
+ libc.hdr.types.sigjmp_buf
libc.hdr.types.sigset_t
libc.hdr.offsetof_macros
libc.src.setjmp.sigsetjmp_epilogue
diff --git a/libc/src/setjmp/darwin/CMakeLists.txt b/libc/src/setjmp/darwin/CMakeLists.txt
index b844c8c..62acec0 100644
--- a/libc/src/setjmp/darwin/CMakeLists.txt
+++ b/libc/src/setjmp/darwin/CMakeLists.txt
@@ -7,6 +7,6 @@ add_object_library(
DEPENDS
libc.src.__support.common
libc.src.__support.OSUtil.osutil
- libc.hdr.types.jmp_buf
+ libc.hdr.types.sigjmp_buf
libc.hdr.types.sigset_t
)
diff --git a/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp b/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
index b2ca4d9..568545a 100644
--- a/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
+++ b/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
@@ -12,7 +12,7 @@
#include "src/signal/sigprocmask.h"
namespace LIBC_NAMESPACE_DECL {
-[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval) {
+[[gnu::returns_twice]] int sigsetjmp_epilogue(sigjmp_buf buffer, int retval) {
syscall_impl<long>(sigprocmask, SIG_SETMASK,
/* set= */ retval ? &buffer->sigmask : nullptr,
/* old_set= */ retval ? nullptr : &buffer->sigmask);
diff --git a/libc/src/setjmp/linux/CMakeLists.txt b/libc/src/setjmp/linux/CMakeLists.txt
index b844c8c..62acec0 100644
--- a/libc/src/setjmp/linux/CMakeLists.txt
+++ b/libc/src/setjmp/linux/CMakeLists.txt
@@ -7,6 +7,6 @@ add_object_library(
DEPENDS
libc.src.__support.common
libc.src.__support.OSUtil.osutil
- libc.hdr.types.jmp_buf
+ libc.hdr.types.sigjmp_buf
libc.hdr.types.sigset_t
)
diff --git a/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp b/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
index 4718623..7e14312 100644
--- a/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
+++ b/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
@@ -12,7 +12,7 @@
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
-[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval) {
+[[gnu::returns_twice]] int sigsetjmp_epilogue(sigjmp_buf buffer, int retval) {
// If set is NULL, then the signal mask is unchanged (i.e., how is
// ignored), but the current value of the signal mask is nevertheless
// returned in oldset (if it is not NULL).
diff --git a/libc/src/setjmp/riscv/CMakeLists.txt b/libc/src/setjmp/riscv/CMakeLists.txt
index 1959e9c..ee3ea28 100644
--- a/libc/src/setjmp/riscv/CMakeLists.txt
+++ b/libc/src/setjmp/riscv/CMakeLists.txt
@@ -19,7 +19,7 @@ if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
HDRS
../sigsetjmp.h
DEPENDS
- libc.hdr.types.jmp_buf
+ libc.hdr.types.sigjmp_buf
libc.hdr.types.sigset_t
libc.hdr.offsetof_macros
libc.src.setjmp.sigsetjmp_epilogue
diff --git a/libc/src/setjmp/sigsetjmp.h b/libc/src/setjmp/sigsetjmp.h
index ef060c8..6e08bd6 100644
--- a/libc/src/setjmp/sigsetjmp.h
+++ b/libc/src/setjmp/sigsetjmp.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H
#define LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H
-#include "hdr/types/jmp_buf.h"
+#include "hdr/types/sigjmp_buf.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/compiler.h"
diff --git a/libc/src/setjmp/sigsetjmp_epilogue.h b/libc/src/setjmp/sigsetjmp_epilogue.h
index 88702b7..7508d4a 100644
--- a/libc/src/setjmp/sigsetjmp_epilogue.h
+++ b/libc/src/setjmp/sigsetjmp_epilogue.h
@@ -9,11 +9,11 @@
#ifndef LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
#define LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
-#include "hdr/types/jmp_buf.h"
+#include "hdr/types/sigjmp_buf.h"
#include "src/__support/common.h"
namespace LIBC_NAMESPACE_DECL {
-[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval);
+[[gnu::returns_twice]] int sigsetjmp_epilogue(sigjmp_buf buffer, int retval);
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
diff --git a/libc/src/setjmp/x86_64/CMakeLists.txt b/libc/src/setjmp/x86_64/CMakeLists.txt
index 03ed5fb..5f87bc6 100644
--- a/libc/src/setjmp/x86_64/CMakeLists.txt
+++ b/libc/src/setjmp/x86_64/CMakeLists.txt
@@ -16,7 +16,7 @@ if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
HDRS
../sigsetjmp.h
DEPENDS
- libc.hdr.types.jmp_buf
+ libc.hdr.types.sigjmp_buf
libc.hdr.types.sigset_t
libc.hdr.offsetof_macros
libc.src.setjmp.sigsetjmp_epilogue
diff --git a/libc/src/spawn/CMakeLists.txt b/libc/src/spawn/CMakeLists.txt
index 11621da7..fe5f81e 100644
--- a/libc/src/spawn/CMakeLists.txt
+++ b/libc/src/spawn/CMakeLists.txt
@@ -7,6 +7,7 @@ add_header_library(
HDRS
file_actions.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.spawn
)
diff --git a/libc/src/spawn/file_actions.h b/libc/src/spawn/file_actions.h
index 80b9295..c69640a3d 100644
--- a/libc/src/spawn/file_actions.h
+++ b/libc/src/spawn/file_actions.h
@@ -9,9 +9,9 @@
#ifndef LLVM_LIBC_SRC_SPAWN_FILE_ACTIONS_H
#define LLVM_LIBC_SRC_SPAWN_FILE_ACTIONS_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
#include <spawn.h> // For mode_t
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/stdio/gpu/CMakeLists.txt b/libc/src/stdio/gpu/CMakeLists.txt
index bea1134..8412153 100644
--- a/libc/src/stdio/gpu/CMakeLists.txt
+++ b/libc/src/stdio/gpu/CMakeLists.txt
@@ -259,6 +259,7 @@ add_entrypoint_object(
HDRS
../fgets.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.hdr.types.FILE
.gpu_file
)
diff --git a/libc/src/stdio/gpu/fgets.cpp b/libc/src/stdio/gpu/fgets.cpp
index 5447e86..e1c6088 100644
--- a/libc/src/stdio/gpu/fgets.cpp
+++ b/libc/src/stdio/gpu/fgets.cpp
@@ -9,12 +9,11 @@
#include "src/stdio/fgets.h"
#include "file.h"
+#include "hdr/stdint_proxy.h"
#include "hdr/stdio_macros.h" // for EOF.
#include "hdr/types/FILE.h"
#include "src/__support/common.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(char *, fgets,
diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index c22f985..76eb0a2 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -44,6 +44,7 @@ add_header_library(
HDRS
core_structs.h
DEPENDS
+ libc.include.inttypes
libc.src.__support.CPP.string_view
libc.src.__support.FPUtil.fp_bits
)
@@ -97,6 +98,7 @@ add_header_library(
.core_structs
.printf_config
.writer
+ libc.include.inttypes
libc.src.__support.big_int
libc.src.__support.common
libc.src.__support.CPP.limits
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 74ae864..aa653c3 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -191,8 +191,9 @@ add_entrypoint_object(
HDRS
a64l.h
DEPENDS
- libc.src.__support.ctype_utils
+ libc.hdr.stdint_proxy
libc.hdr.types.size_t
+ libc.src.__support.ctype_utils
)
add_entrypoint_object(
@@ -202,8 +203,9 @@ add_entrypoint_object(
HDRS
l64a.h
DEPENDS
- libc.src.__support.ctype_utils
+ libc.hdr.stdint_proxy
libc.hdr.types.size_t
+ libc.src.__support.ctype_utils
)
add_entrypoint_object(
@@ -287,6 +289,7 @@ add_header_library(
heap_sort.h
quick_sort.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.stdlib
libc.src.__support.CPP.cstddef
)
@@ -299,6 +302,7 @@ add_entrypoint_object(
qsort.h
DEPENDS
.qsort_util
+ libc.hdr.stdint_proxy
libc.hdr.types.size_t
)
@@ -310,6 +314,7 @@ add_entrypoint_object(
qsort_r.h
DEPENDS
.qsort_util
+ libc.hdr.stdint_proxy
libc.hdr.types.size_t
)
diff --git a/libc/src/stdlib/a64l.cpp b/libc/src/stdlib/a64l.cpp
index 84be2d2..690b70d 100644
--- a/libc/src/stdlib/a64l.cpp
+++ b/libc/src/stdlib/a64l.cpp
@@ -7,13 +7,12 @@
//===----------------------------------------------------------------------===//
#include "src/stdlib/a64l.h"
+#include "hdr/stdint_proxy.h"
#include "hdr/types/size_t.h"
#include "src/__support/common.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
// I'm not sure this should go in ctype_utils since the specific ordering of
diff --git a/libc/src/stdlib/bsearch.cpp b/libc/src/stdlib/bsearch.cpp
index 69b3e74..f084805 100644
--- a/libc/src/stdlib/bsearch.cpp
+++ b/libc/src/stdlib/bsearch.cpp
@@ -10,7 +10,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/stdlib/l64a.cpp b/libc/src/stdlib/l64a.cpp
index b5506c3e..d59e65e 100644
--- a/libc/src/stdlib/l64a.cpp
+++ b/libc/src/stdlib/l64a.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "src/stdlib/l64a.h"
+#include "hdr/stdint_proxy.h"
#include "hdr/types/size_t.h"
#include "src/__support/common.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/libc_assert.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
// the standard says to only use up to 6 characters. Null terminator is
diff --git a/libc/src/stdlib/qsort.cpp b/libc/src/stdlib/qsort.cpp
index 0bf5fc7..f66b686 100644
--- a/libc/src/stdlib/qsort.cpp
+++ b/libc/src/stdlib/qsort.cpp
@@ -7,12 +7,11 @@
//===----------------------------------------------------------------------===//
#include "src/stdlib/qsort.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/stdlib/qsort_util.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(void, qsort,
diff --git a/libc/src/stdlib/qsort_data.h b/libc/src/stdlib/qsort_data.h
index aa6d9bb..739fce8 100644
--- a/libc/src/stdlib/qsort_data.h
+++ b/libc/src/stdlib/qsort_data.h
@@ -9,11 +9,10 @@
#ifndef LLVM_LIBC_SRC_STDLIB_QSORT_DATA_H
#define LLVM_LIBC_SRC_STDLIB_QSORT_DATA_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/cstddef.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/stdlib/qsort_r.cpp b/libc/src/stdlib/qsort_r.cpp
index 4e60998..4744820 100644
--- a/libc/src/stdlib/qsort_r.cpp
+++ b/libc/src/stdlib/qsort_r.cpp
@@ -7,12 +7,11 @@
//===----------------------------------------------------------------------===//
#include "src/stdlib/qsort_r.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/stdlib/qsort_util.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(void, qsort_r,
diff --git a/libc/src/stdlib/quick_sort.h b/libc/src/stdlib/quick_sort.h
index 8ba0098..00115bd 100644
--- a/libc/src/stdlib/quick_sort.h
+++ b/libc/src/stdlib/quick_sort.h
@@ -9,13 +9,12 @@
#ifndef LLVM_LIBC_SRC_STDLIB_QUICK_SORT_H
#define LLVM_LIBC_SRC_STDLIB_QUICK_SORT_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/cstddef.h"
#include "src/__support/macros/config.h"
#include "src/stdlib/qsort_pivot.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index 8784bc3..809decf 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -17,6 +17,7 @@ add_header_library(
DEPENDS
libc.hdr.types.size_t
libc.hdr.limits_macros
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.bitset
libc.src.__support.CPP.type_traits
libc.src.__support.common
diff --git a/libc/src/string/allocating_string_utils.h b/libc/src/string/allocating_string_utils.h
index 1dece51..e2f61f7 100644
--- a/libc/src/string/allocating_string_utils.h
+++ b/libc/src/string/allocating_string_utils.h
@@ -20,15 +20,15 @@
namespace LIBC_NAMESPACE_DECL {
namespace internal {
-LIBC_INLINE cpp::optional<char *> strdup(const char *src) {
+template <typename T> LIBC_INLINE cpp::optional<T *> strdup(const T *src) {
if (src == nullptr)
return cpp::nullopt;
size_t len = string_length(src) + 1;
AllocChecker ac;
- char *newstr = new (ac) char[len];
+ T *newstr = new (ac) T[len];
if (!ac)
return cpp::nullopt;
- inline_memcpy(newstr, src, len);
+ inline_memcpy(newstr, src, len * sizeof(T));
return newstr;
}
diff --git a/libc/src/string/memory_utils/CMakeLists.txt b/libc/src/string/memory_utils/CMakeLists.txt
index 8ab1c9f..670db30 100644
--- a/libc/src/string/memory_utils/CMakeLists.txt
+++ b/libc/src/string/memory_utils/CMakeLists.txt
@@ -34,6 +34,7 @@ add_header_library(
x86_64/inline_memmove.h
x86_64/inline_memset.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.cstddef
diff --git a/libc/src/string/memory_utils/op_generic.h b/libc/src/string/memory_utils/op_generic.h
index 9349cfdd..3760341 100644
--- a/libc/src/string/memory_utils/op_generic.h
+++ b/libc/src/string/memory_utils/op_generic.h
@@ -23,6 +23,7 @@
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_GENERIC_H
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_GENERIC_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
@@ -34,8 +35,6 @@
#include "src/string/memory_utils/op_builtin.h"
#include "src/string/memory_utils/utils.h"
-#include <stdint.h>
-
static_assert((UINTPTR_MAX == 4294967295U) ||
(UINTPTR_MAX == 18446744073709551615UL),
"We currently only support 32- or 64-bit platforms");
diff --git a/libc/src/string/memory_utils/utils.h b/libc/src/string/memory_utils/utils.h
index c08608c..0f9c9e3 100644
--- a/libc/src/string/memory_utils/utils.h
+++ b/libc/src/string/memory_utils/utils.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_UTILS_H
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_UTILS_H
+#include "hdr/stdint_proxy.h" // intptr_t / uintptr_t / INT32_MAX / INT32_MIN
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/cstddef.h"
#include "src/__support/CPP/type_traits.h"
@@ -18,7 +19,6 @@
#include "src/__support/macros/properties/architectures.h"
#include <stddef.h> // size_t
-#include <stdint.h> // intptr_t / uintptr_t / INT32_MAX / INT32_MIN
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/string/memory_utils/x86_64/inline_memcpy.h b/libc/src/string/memory_utils/x86_64/inline_memcpy.h
index 68f64fb..bf3aa1f 100644
--- a/libc/src/string/memory_utils/x86_64/inline_memcpy.h
+++ b/libc/src/string/memory_utils/x86_64/inline_memcpy.h
@@ -8,6 +8,7 @@
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_X86_64_INLINE_MEMCPY_H
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_X86_64_INLINE_MEMCPY_H
+#include "hdr/stdint_proxy.h" // SIZE_MAX
#include "src/__support/macros/attributes.h" // LIBC_INLINE_VAR
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/string/memory_utils/op_builtin.h"
@@ -15,7 +16,6 @@
#include "src/string/memory_utils/utils.h"
#include <stddef.h> // size_t
-#include <stdint.h> // SIZE_MAX
#ifdef LLVM_LIBC_MEMCPY_X86_USE_ONLY_REPMOVSB
#error LLVM_LIBC_MEMCPY_X86_USE_ONLY_REPMOVSB is deprecated use LIBC_COPT_MEMCPY_X86_USE_REPMOVSB_FROM_SIZE=0 instead.
diff --git a/libc/src/string/string_utils.h b/libc/src/string/string_utils.h
index 1231117..80e5783 100644
--- a/libc/src/string/string_utils.h
+++ b/libc/src/string/string_utils.h
@@ -15,14 +15,13 @@
#define LLVM_LIBC_SRC_STRING_STRING_UTILS_H
#include "hdr/limits_macros.h"
+#include "hdr/stdint_proxy.h" // uintptr_t
#include "hdr/types/size_t.h"
#include "src/__support/CPP/bitset.h"
#include "src/__support/CPP/type_traits.h" // cpp::is_same_v
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include <stdint.h> // uintptr_t
-
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/src/sys/stat/linux/CMakeLists.txt b/libc/src/sys/stat/linux/CMakeLists.txt
index 9aeb146..c99872c 100644
--- a/libc/src/sys/stat/linux/CMakeLists.txt
+++ b/libc/src/sys/stat/linux/CMakeLists.txt
@@ -73,6 +73,7 @@ add_header_library(
HDRS
kernel_statx.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.sys_stat
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
diff --git a/libc/src/sys/stat/linux/kernel_statx.h b/libc/src/sys/stat/linux/kernel_statx.h
index d0e223a..455ab17 100644
--- a/libc/src/sys/stat/linux/kernel_statx.h
+++ b/libc/src/sys/stat/linux/kernel_statx.h
@@ -9,11 +9,11 @@
#ifndef LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H
#define LLVM_LIBC_SRC_SYS_STAT_LINUX_KERNEL_STATX_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
#include <sys/stat.h>
#include <sys/syscall.h> // For syscall numbers.
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 3b951df..304b3f2 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -7,10 +7,11 @@ add_header_library(
HDRS
time_constants.h
DEPENDS
+ libc.hdr.stdint_proxy
+ libc.hdr.types.time_t
libc.include.time
libc.src.__support.CPP.array
libc.src.__support.CPP.string_view
- libc.hdr.types.time_t
)
add_object_library(
@@ -29,6 +30,7 @@ add_object_library(
libc.hdr.types.time_t
libc.hdr.types.size_t
libc.hdr.types.struct_tm
+ libc.hdr.stdint_proxy
)
add_entrypoint_object(
diff --git a/libc/src/time/linux/CMakeLists.txt b/libc/src/time/linux/CMakeLists.txt
index 314623f..a6ec7c7 100644
--- a/libc/src/time/linux/CMakeLists.txt
+++ b/libc/src/time/linux/CMakeLists.txt
@@ -34,6 +34,7 @@ add_entrypoint_object(
../nanosleep.h
DEPENDS
libc.hdr.types.struct_timespec
+ libc.hdr.stdint_proxy
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.__support.CPP.limits
diff --git a/libc/src/time/linux/nanosleep.cpp b/libc/src/time/linux/nanosleep.cpp
index 6b97041..e5df158 100644
--- a/libc/src/time/linux/nanosleep.cpp
+++ b/libc/src/time/linux/nanosleep.cpp
@@ -7,13 +7,13 @@
//===----------------------------------------------------------------------===//
#include "src/time/nanosleep.h"
+#include "hdr/stdint_proxy.h" // For int64_t.
#include "hdr/time_macros.h"
#include "src/__support/OSUtil/syscall.h" // For syscall functions.
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include <stdint.h> // For int64_t.
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/time/strftime_core/CMakeLists.txt b/libc/src/time/strftime_core/CMakeLists.txt
index 5e40e66..3ffd283 100644
--- a/libc/src/time/strftime_core/CMakeLists.txt
+++ b/libc/src/time/strftime_core/CMakeLists.txt
@@ -5,6 +5,7 @@ add_header_library(
DEPENDS
libc.src.__support.CPP.string_view
libc.hdr.types.struct_tm
+ libc.hdr.stdint_proxy
)
add_header_library(
diff --git a/libc/src/time/strftime_core/core_structs.h b/libc/src/time/strftime_core/core_structs.h
index 25bf5e6..9da57aa 100644
--- a/libc/src/time/strftime_core/core_structs.h
+++ b/libc/src/time/strftime_core/core_structs.h
@@ -9,11 +9,10 @@
#ifndef LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CORE_STRUCTS_H
#define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CORE_STRUCTS_H
+#include "hdr/stdint_proxy.h"
#include "hdr/types/struct_tm.h"
#include "src/__support/CPP/string_view.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace strftime_core {
diff --git a/libc/src/time/time_constants.h b/libc/src/time/time_constants.h
index 0fcb7ff..32eb0a1 100644
--- a/libc/src/time/time_constants.h
+++ b/libc/src/time/time_constants.h
@@ -9,10 +9,10 @@
#ifndef LLVM_LIBC_SRC_TIME_TIME_CONSTANTS_H
#define LLVM_LIBC_SRC_TIME_TIME_CONSTANTS_H
+#include "hdr/stdint_proxy.h"
#include "hdr/types/time_t.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/string_view.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace time_constants {
diff --git a/libc/src/time/time_utils.cpp b/libc/src/time/time_utils.cpp
index 1c519c3..1d0daea 100644
--- a/libc/src/time/time_utils.cpp
+++ b/libc/src/time/time_utils.cpp
@@ -7,13 +7,12 @@
//===----------------------------------------------------------------------===//
#include "src/time/time_utils.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/limits.h" // INT_MIN, INT_MAX
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/time/time_constants.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace time_utils {
diff --git a/libc/src/time/time_utils.h b/libc/src/time/time_utils.h
index 0541c24..84d412c 100644
--- a/libc/src/time/time_utils.h
+++ b/libc/src/time/time_utils.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_SRC_TIME_TIME_UTILS_H
#define LLVM_LIBC_SRC_TIME_TIME_UTILS_H
+#include "hdr/stdint_proxy.h"
#include "hdr/types/size_t.h"
#include "hdr/types/struct_tm.h"
#include "hdr/types/time_t.h"
@@ -19,8 +20,6 @@
#include "src/__support/macros/config.h"
#include "time_constants.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace time_utils {
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index 368593a..382a61f 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -172,6 +172,7 @@ add_entrypoint_object(
DEPENDS
libc.hdr.types.off_t
libc.hdr.fcntl_macros
+ libc.hdr.stdint_proxy
libc.include.unistd
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
@@ -385,6 +386,7 @@ add_entrypoint_object(
libc.hdr.types.size_t
libc.hdr.types.ssize_t
libc.hdr.fcntl_macros
+ libc.hdr.stdint_proxy
libc.include.unistd
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
@@ -403,6 +405,7 @@ add_entrypoint_object(
libc.hdr.types.size_t
libc.hdr.types.ssize_t
libc.hdr.fcntl_macros
+ libc.hdr.stdint_proxy
libc.include.unistd
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
@@ -546,6 +549,7 @@ add_entrypoint_object(
DEPENDS
libc.hdr.types.off_t
libc.hdr.fcntl_macros
+ libc.hdr.stdint_proxy
libc.include.unistd
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
diff --git a/libc/src/unistd/linux/ftruncate.cpp b/libc/src/unistd/linux/ftruncate.cpp
index f6aa6f8..b4729f8 100644
--- a/libc/src/unistd/linux/ftruncate.cpp
+++ b/libc/src/unistd/linux/ftruncate.cpp
@@ -11,10 +11,10 @@
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
+#include "hdr/stdint_proxy.h" // For uint64_t.
#include "hdr/unistd_macros.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include <stdint.h> // For uint64_t.
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/unistd/linux/pread.cpp b/libc/src/unistd/linux/pread.cpp
index 2f86e39..cf3152d 100644
--- a/libc/src/unistd/linux/pread.cpp
+++ b/libc/src/unistd/linux/pread.cpp
@@ -8,12 +8,12 @@
#include "src/unistd/pread.h"
+#include "hdr/stdint_proxy.h" // For uint64_t.
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
-#include <stdint.h> // For uint64_t.
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/unistd/linux/pwrite.cpp b/libc/src/unistd/linux/pwrite.cpp
index f4cf8e1..7672063 100644
--- a/libc/src/unistd/linux/pwrite.cpp
+++ b/libc/src/unistd/linux/pwrite.cpp
@@ -11,9 +11,9 @@
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
+#include "hdr/stdint_proxy.h" // For uint64_t.
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include <stdint.h> // For uint64_t.
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/unistd/linux/truncate.cpp b/libc/src/unistd/linux/truncate.cpp
index 6103d4b..204b27f7 100644
--- a/libc/src/unistd/linux/truncate.cpp
+++ b/libc/src/unistd/linux/truncate.cpp
@@ -13,8 +13,8 @@
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
+#include "hdr/stdint_proxy.h" // For uint64_t.
#include "hdr/unistd_macros.h"
-#include <stdint.h> // For uint64_t.
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/wchar/CMakeLists.txt b/libc/src/wchar/CMakeLists.txt
index 159778d..49f4a1b 100644
--- a/libc/src/wchar/CMakeLists.txt
+++ b/libc/src/wchar/CMakeLists.txt
@@ -137,6 +137,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ mbsinit
+ SRCS
+ mbsinit.cpp
+ HDRS
+ mbsinit.h
+ DEPENDS
+ libc.hdr.types.wchar_t
+ libc.hdr.types.mbstate_t
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.wchar.character_converter
+ libc.src.__support.wchar.mbstate
+)
+
+add_entrypoint_object(
mbrtowc
SRCS
mbrtowc.cpp
@@ -170,6 +185,78 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ wcstombs
+ SRCS
+ wcstombs.cpp
+ HDRS
+ wcstombs.h
+ DEPENDS
+ libc.hdr.types.wchar_t
+ libc.src.__support.wchar.mbstate
+ libc.src.__support.wchar.wcsnrtombs
+ libc.src.__support.libc_errno
+)
+
+add_entrypoint_object(
+ wcsrtombs
+ SRCS
+ wcsrtombs.cpp
+ HDRS
+ wcsrtombs.h
+ DEPENDS
+ libc.hdr.types.wchar_t
+ libc.hdr.types.mbstate_t
+ libc.src.__support.wchar.mbstate
+ libc.src.__support.wchar.wcsnrtombs
+ libc.src.__support.libc_errno
+)
+
+add_entrypoint_object(
+ wcsnrtombs
+ SRCS
+ wcsnrtombs.cpp
+ HDRS
+ wcsnrtombs.h
+ DEPENDS
+ libc.hdr.types.wchar_t
+ libc.hdr.types.mbstate_t
+ libc.src.__support.wchar.mbstate
+ libc.src.__support.wchar.wcsnrtombs
+ libc.src.__support.libc_errno
+)
+
+add_entrypoint_object(
+ mblen
+ SRCS
+ mblen.cpp
+ HDRS
+ mblen.h
+ DEPENDS
+ libc.hdr.types.size_t
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.libc_errno
+ libc.src.__support.wchar.mbrtowc
+ libc.src.__support.wchar.mbstate
+)
+
+add_entrypoint_object(
+ mbrlen
+ SRCS
+ mbrlen.cpp
+ HDRS
+ mbrlen.h
+ DEPENDS
+ libc.hdr.types.size_t
+ libc.hdr.types.mbstate_t
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.wchar.mbrtowc
+ libc.src.__support.libc_errno
+ libc.src.__support.wchar.mbstate
+)
+
+add_entrypoint_object(
wmemset
SRCS
wmemset.cpp
@@ -225,6 +312,19 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ wcsdup
+ SRCS
+ wcsdup.cpp
+ HDRS
+ wcsdup.h
+ DEPENDS
+ libc.hdr.types.wchar_t
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
+ libc.src.string.allocating_string_utils
+)
+
+add_entrypoint_object(
wcspbrk
SRCS
wcspbrk.cpp
diff --git a/libc/src/wchar/mblen.cpp b/libc/src/wchar/mblen.cpp
new file mode 100644
index 0000000..2d15b3e
--- /dev/null
+++ b/libc/src/wchar/mblen.cpp
@@ -0,0 +1,35 @@
+//===-- Implementation of mblen -------------------------------------------===//
+//
+// 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 "src/wchar/mblen.h"
+
+#include "hdr/types/size_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbrtowc.h"
+#include "src/__support/wchar/mbstate.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, mblen, (const char *s, size_t n)) {
+ // returns 0 since UTF-8 encoding is not state-dependent
+ if (s == nullptr)
+ return 0;
+ internal::mbstate internal_mbstate;
+ auto ret = internal::mbrtowc(nullptr, s, n, &internal_mbstate);
+ if (!ret.has_value() || static_cast<int>(ret.value()) == -2) {
+ // Encoding failure
+ if (!ret.has_value())
+ libc_errno = EILSEQ;
+ return -1;
+ }
+ return static_cast<int>(ret.value());
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/mblen.h b/libc/src/wchar/mblen.h
new file mode 100644
index 0000000..a315a2f
--- /dev/null
+++ b/libc/src/wchar/mblen.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for mblen -----------------------------------===//
+//
+// 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_WCHAR_MBLEN_H
+#define LLVM_LIBC_SRC_WCHAR_MBLEN_H
+
+#include "hdr/types/size_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int mblen(const char *s, size_t n);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_MBLEN_H
diff --git a/libc/src/wchar/mbrlen.cpp b/libc/src/wchar/mbrlen.cpp
new file mode 100644
index 0000000..8de78e0
--- /dev/null
+++ b/libc/src/wchar/mbrlen.cpp
@@ -0,0 +1,37 @@
+//===-- Implementation of mbrlen ------------------------------------------===//
+//
+// 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 "src/wchar/mbrlen.h"
+
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbrtowc.h"
+#include "src/__support/wchar/mbstate.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(size_t, mbrlen,
+ (const char *__restrict s, size_t n,
+ mbstate_t *__restrict ps)) {
+ static internal::mbstate internal_mbstate;
+ auto ret = internal::mbrtowc(nullptr, s, n,
+ ps == nullptr
+ ? &internal_mbstate
+ : reinterpret_cast<internal::mbstate *>(ps));
+ if (!ret.has_value()) {
+ // Encoding failure
+ libc_errno = ret.error();
+ return -1;
+ }
+ return ret.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/mbrlen.h b/libc/src/wchar/mbrlen.h
new file mode 100644
index 0000000..08b59cf
--- /dev/null
+++ b/libc/src/wchar/mbrlen.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for mbrlen ----------------------------------===//
+//
+// 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_WCHAR_MBRLEN_H
+#define LLVM_LIBC_SRC_WCHAR_MBRLEN_H
+
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+size_t mbrlen(const char *__restrict s, size_t n, mbstate_t *__restrict ps);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_MBRLEN_H
diff --git a/libc/src/wchar/mbsinit.cpp b/libc/src/wchar/mbsinit.cpp
new file mode 100644
index 0000000..23ba542
--- /dev/null
+++ b/libc/src/wchar/mbsinit.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of mbsinit -----------------------------------------===//
+//
+// 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 "src/wchar/mbsinit.h"
+
+#include "hdr/types/mbstate_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/character_converter.h"
+#include "src/__support/wchar/mbstate.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, mbsinit, (mbstate_t * ps)) {
+ if (ps == nullptr)
+ return true;
+ internal::CharacterConverter cr(reinterpret_cast<internal::mbstate *>(ps));
+ return cr.isValidState() && cr.isEmpty();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/mbsinit.h b/libc/src/wchar/mbsinit.h
new file mode 100644
index 0000000..fa6be0f
--- /dev/null
+++ b/libc/src/wchar/mbsinit.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for mbsinit ---------------------------------===//
+//
+// 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_WCHAR_MBSINIT_H
+#define LLVM_LIBC_SRC_WCHAR_MBSINIT_H
+
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int mbsinit(mbstate_t *ps);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_MBSINIT_H
diff --git a/libc/src/wchar/wcsdup.cpp b/libc/src/wchar/wcsdup.cpp
new file mode 100644
index 0000000..d4a13d3
--- /dev/null
+++ b/libc/src/wchar/wcsdup.cpp
@@ -0,0 +1,27 @@
+//===-- Implementation of wcsdup -----------------------------------------===//
+//
+// 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 "src/wchar/wcsdup.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/string/allocating_string_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(wchar_t *, wcsdup, (const wchar_t *wcs)) {
+ auto dup = internal::strdup(wcs);
+ if (dup)
+ return *dup;
+ if (wcs != nullptr)
+ libc_errno = ENOMEM;
+ return nullptr;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wcsdup.h b/libc/src/wchar/wcsdup.h
new file mode 100644
index 0000000..80b3e52
--- /dev/null
+++ b/libc/src/wchar/wcsdup.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for wcsdup ----------------------------------===//
+//
+// 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_WCHAR_WCSDUP_H
+#define LLVM_LIBC_SRC_WCHAR_WCSDUP_H
+
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+wchar_t *wcsdup(const wchar_t *wcs);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSDUP_H
diff --git a/libc/src/wchar/wcsnrtombs.cpp b/libc/src/wchar/wcsnrtombs.cpp
new file mode 100644
index 0000000..7f25b24
--- /dev/null
+++ b/libc/src/wchar/wcsnrtombs.cpp
@@ -0,0 +1,40 @@
+//===-- Implementation of wcsnrtombs --------------------------------------===//
+//
+// 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 "src/wchar/wcsnrtombs.h"
+
+#include "hdr/types/char32_t.h"
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbstate.h"
+#include "src/__support/wchar/wcsnrtombs.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(size_t, wcsnrtombs,
+ (char *__restrict s, const wchar_t **__restrict pwcs,
+ size_t nwc, size_t len, mbstate_t *ps)) {
+ LIBC_CRASH_ON_NULLPTR(pwcs);
+ static internal::mbstate internal_mbstate;
+ auto result = internal::wcsnrtombs(
+ s, pwcs, nwc, len,
+ ps == nullptr ? &internal_mbstate
+ : reinterpret_cast<internal::mbstate *>(ps));
+ if (!result.has_value()) {
+ libc_errno = result.error();
+ return -1;
+ }
+
+ return result.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wcsnrtombs.h b/libc/src/wchar/wcsnrtombs.h
new file mode 100644
index 0000000..bf8add7
--- /dev/null
+++ b/libc/src/wchar/wcsnrtombs.h
@@ -0,0 +1,24 @@
+//===-- Implementation header for wcsnrtombs ------------------------------===//
+//
+// 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_WCHAR_WCSNRTOMBS_H
+#define LLVM_LIBC_SRC_WCHAR_WCSNRTOMBS_H
+
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+size_t wcsnrtombs(char *__restrict s, const wchar_t **__restrict pwcs,
+ size_t nwc, size_t len, mbstate_t *ps);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSNRTOMBS_H
diff --git a/libc/src/wchar/wcsrtombs.cpp b/libc/src/wchar/wcsrtombs.cpp
new file mode 100644
index 0000000..9d2508c
--- /dev/null
+++ b/libc/src/wchar/wcsrtombs.cpp
@@ -0,0 +1,40 @@
+//===-- Implementation of wcsrtombs ---------------------------------------===//
+//
+// 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 "src/wchar/wcsrtombs.h"
+
+#include "hdr/types/char32_t.h"
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbstate.h"
+#include "src/__support/wchar/wcsnrtombs.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(size_t, wcsrtombs,
+ (char *__restrict s, const wchar_t **__restrict pwcs,
+ size_t n, mbstate_t *ps)) {
+ LIBC_CRASH_ON_NULLPTR(pwcs);
+ static internal::mbstate internal_mbstate;
+ auto result = internal::wcsnrtombs(
+ s, pwcs, SIZE_MAX, n,
+ ps == nullptr ? &internal_mbstate
+ : reinterpret_cast<internal::mbstate *>(ps));
+ if (!result.has_value()) {
+ libc_errno = result.error();
+ return -1;
+ }
+
+ return result.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wcsrtombs.h b/libc/src/wchar/wcsrtombs.h
new file mode 100644
index 0000000..d23573f
--- /dev/null
+++ b/libc/src/wchar/wcsrtombs.h
@@ -0,0 +1,24 @@
+//===-- Implementation header for wcsrtombs -------------------------------===//
+//
+// 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_WCHAR_WCSRTOMBS_H
+#define LLVM_LIBC_SRC_WCHAR_WCSRTOMBS_H
+
+#include "hdr/types/mbstate_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+size_t wcsrtombs(char *__restrict s, const wchar_t **__restrict pwcs, size_t n,
+ mbstate_t *ps);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSRTOMBS_H
diff --git a/libc/src/wchar/wcstombs.cpp b/libc/src/wchar/wcstombs.cpp
new file mode 100644
index 0000000..c3793cb
--- /dev/null
+++ b/libc/src/wchar/wcstombs.cpp
@@ -0,0 +1,38 @@
+//===-- Implementation of wcstombs ----------------------------------------===//
+//
+// 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 "src/wchar/wcstombs.h"
+
+#include "hdr/types/char32_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/wchar/mbstate.h"
+#include "src/__support/wchar/wcsnrtombs.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(size_t, wcstombs,
+ (char *__restrict s, const wchar_t *__restrict wcs,
+ size_t n)) {
+ LIBC_CRASH_ON_NULLPTR(wcs);
+ static internal::mbstate internal_mbstate;
+ const wchar_t *wcs_ptr_copy = wcs;
+ auto result =
+ internal::wcsnrtombs(s, &wcs_ptr_copy, SIZE_MAX, n, &internal_mbstate);
+ if (!result.has_value()) {
+ libc_errno = result.error();
+ return -1;
+ }
+
+ return result.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wcstombs.h b/libc/src/wchar/wcstombs.h
new file mode 100644
index 0000000..cd0008a
--- /dev/null
+++ b/libc/src/wchar/wcstombs.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for wcstombs --------------------------------===//
+//
+// 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_WCHAR_WCSTOMBS_H
+#define LLVM_LIBC_SRC_WCHAR_WCSTOMBS_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+size_t wcstombs(char *__restrict s, const wchar_t *__restrict pwcs, size_t n);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCSTOMBS_H