aboutsummaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/benchmarks/gpu/BenchmarkLogger.cpp3
-rw-r--r--libc/benchmarks/gpu/CMakeLists.txt1
-rw-r--r--libc/benchmarks/gpu/LibcGpuBenchmark.h3
-rw-r--r--libc/benchmarks/gpu/src/math/CMakeLists.txt2
-rw-r--r--libc/benchmarks/gpu/src/math/platform.h3
-rw-r--r--libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt1
-rw-r--r--libc/benchmarks/gpu/timing/amdgpu/timing.h3
-rw-r--r--libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt1
-rw-r--r--libc/benchmarks/gpu/timing/nvptx/timing.h3
-rw-r--r--libc/cmake/modules/LLVMLibCArchitectures.cmake2
-rw-r--r--libc/cmake/modules/LLVMLibCCompileOptionRules.cmake4
-rw-r--r--libc/cmake/modules/LLVMLibCFlagRules.cmake2
-rw-r--r--libc/cmake/modules/LLVMLibCTestRules.cmake2
-rw-r--r--libc/config/CMakeLists.txt1
-rw-r--r--libc/config/gpu/app.h3
-rw-r--r--libc/config/linux/app.h3
-rw-r--r--libc/config/linux/x86_64/entrypoints.txt7
-rw-r--r--libc/config/uefi/app.h3
-rw-r--r--libc/fuzzing/math/CMakeLists.txt36
-rw-r--r--libc/fuzzing/math/cbrt_fuzz.cpp50
-rw-r--r--libc/fuzzing/math/f16sqrt_fuzz.cpp56
-rw-r--r--libc/fuzzing/math/fsqrt_fuzz.cpp53
-rw-r--r--libc/fuzzing/math/hypot_fuzz.cpp64
-rw-r--r--libc/hdr/CMakeLists.txt9
-rw-r--r--libc/hdr/stdint_proxy.h18
-rw-r--r--libc/hdr/types/CMakeLists.txt13
-rw-r--r--libc/hdr/types/jmp_buf.h2
-rw-r--r--libc/hdr/types/sigjmp_buf.h22
-rw-r--r--libc/include/CMakeLists.txt19
-rw-r--r--libc/include/llvm-libc-types/CMakeLists.txt4
-rw-r--r--libc/include/llvm-libc-types/__jmp_buf.h78
-rw-r--r--libc/include/llvm-libc-types/jmp_buf.h70
-rw-r--r--libc/include/llvm-libc-types/sigjmp_buf.h16
-rw-r--r--libc/include/math.yaml4
-rw-r--r--libc/include/wchar.yaml54
-rw-r--r--libc/shared/math.h10
-rw-r--r--libc/shared/math/acosf.h23
-rw-r--r--libc/shared/math/acosf16.h29
-rw-r--r--libc/shared/math/acoshf.h23
-rw-r--r--libc/shared/math/acoshf16.h29
-rw-r--r--libc/shared/math/acospif16.h29
-rw-r--r--libc/shared/math/asin.h23
-rw-r--r--libc/shared/math/asinf.h23
-rw-r--r--libc/shared/math/asinf16.h28
-rw-r--r--libc/shared/math/asinhf.h23
-rw-r--r--libc/shared/math/erff.h23
-rw-r--r--libc/shared/math/exp10f16.h8
-rw-r--r--libc/shared/sign.h23
-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.txt19
-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/comparison_operations.h114
-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.cpp228
-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/cpu_features.h2
-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.txt191
-rw-r--r--libc/src/__support/math/acos.h7
-rw-r--r--libc/src/__support/math/acosf.h147
-rw-r--r--libc/src/__support/math/acosf16.h164
-rw-r--r--libc/src/__support/math/acosh_float_constants.h114
-rw-r--r--libc/src/__support/math/acoshf.h86
-rw-r--r--libc/src/__support/math/acoshf16.h123
-rw-r--r--libc/src/__support/math/acoshf_utils.h60
-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/asin_utils.h4
-rw-r--r--libc/src/__support/math/asinf.h175
-rw-r--r--libc/src/__support/math/asinf16.h146
-rw-r--r--libc/src/__support/math/asinhf.h125
-rw-r--r--libc/src/__support/math/erff.h193
-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/inv_trigf_utils.h (renamed from libc/src/math/generic/inv_trigf_utils.cpp)104
-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/mbrtowc.cpp3
-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/docs/add_math_function.md4
-rw-r--r--libc/src/math/generic/CMakeLists.txt119
-rw-r--r--libc/src/math/generic/acosf.cpp121
-rw-r--r--libc/src/math/generic/acosf16.cpp138
-rw-r--r--libc/src/math/generic/acoshf.cpp68
-rw-r--r--libc/src/math/generic/acoshf16.cpp98
-rw-r--r--libc/src/math/generic/acospif16.cpp122
-rw-r--r--libc/src/math/generic/asin.cpp16
-rw-r--r--libc/src/math/generic/asinf.cpp154
-rw-r--r--libc/src/math/generic/asinf16.cpp121
-rw-r--r--libc/src/math/generic/asinhf.cpp105
-rw-r--r--libc/src/math/generic/asinhf16.cpp1
-rw-r--r--libc/src/math/generic/atan2f.cpp3
-rw-r--r--libc/src/math/generic/atanf.cpp3
-rw-r--r--libc/src/math/generic/atanhf.cpp1
-rw-r--r--libc/src/math/generic/common_constants.cpp92
-rw-r--r--libc/src/math/generic/common_constants.h7
-rw-r--r--libc/src/math/generic/erff.cpp174
-rw-r--r--libc/src/math/generic/explogxf.h36
-rw-r--r--libc/src/math/generic/expxf16.h3
-rw-r--r--libc/src/math/generic/inv_trigf_utils.h110
-rw-r--r--libc/src/math/generic/log1pf.cpp1
-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/baremetal/CMakeLists.txt1
-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/stdio/scanf_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.h1
-rw-r--r--libc/src/sys/epoll/linux/epoll_create.cpp5
-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/sys/time/linux/setitimer.cpp4
-rw-r--r--libc/src/sys/time/linux/utimes.cpp6
-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.txt114
-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/mbtowc.cpp5
-rw-r--r--libc/src/wchar/wchar_utils.h42
-rw-r--r--libc/src/wchar/wcschr.cpp9
-rw-r--r--libc/src/wchar/wcscspn.cpp18
-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/wcspbrk.cpp11
-rw-r--r--libc/src/wchar/wcsrtombs.cpp40
-rw-r--r--libc/src/wchar/wcsrtombs.h24
-rw-r--r--libc/src/wchar/wcsspn.cpp18
-rw-r--r--libc/src/wchar/wcstok.cpp23
-rw-r--r--libc/src/wchar/wcstombs.cpp38
-rw-r--r--libc/src/wchar/wcstombs.h22
-rw-r--r--libc/startup/baremetal/CMakeLists.txt6
-rw-r--r--libc/startup/baremetal/fini.cpp2
-rw-r--r--libc/startup/baremetal/init.cpp2
-rw-r--r--libc/startup/linux/CMakeLists.txt1
-rw-r--r--libc/startup/linux/do_start.cpp2
-rw-r--r--libc/test/CMakeLists.txt1
-rw-r--r--libc/test/IntegrationTest/CMakeLists.txt1
-rw-r--r--libc/test/IntegrationTest/test.cpp2
-rw-r--r--libc/test/UnitTest/CMakeLists.txt7
-rw-r--r--libc/test/UnitTest/ExecuteFunction.h2
-rw-r--r--libc/test/UnitTest/HermeticTestUtils.cpp2
-rw-r--r--libc/test/UnitTest/PrintfMatcher.cpp3
-rw-r--r--libc/test/UnitTest/RoundingModeUtils.h2
-rw-r--r--libc/test/UnitTest/ScanfMatcher.cpp3
-rw-r--r--libc/test/UnitTest/Test.h9
-rw-r--r--libc/test/UnitTest/TestLogger.cpp7
-rw-r--r--libc/test/integration/src/pthread/CMakeLists.txt5
-rw-r--r--libc/test/integration/src/pthread/pthread_equal_test.cpp3
-rw-r--r--libc/test/integration/src/pthread/pthread_mutex_test.cpp8
-rw-r--r--libc/test/integration/src/pthread/pthread_name_test.cpp3
-rw-r--r--libc/test/integration/src/pthread/pthread_once_test.cpp3
-rw-r--r--libc/test/integration/src/pthread/pthread_test.cpp2
-rw-r--r--libc/test/integration/src/spawn/CMakeLists.txt1
-rw-r--r--libc/test/integration/src/spawn/posix_spawn_test.cpp2
-rw-r--r--libc/test/integration/src/stdlib/gpu/malloc_stress.cpp28
-rw-r--r--libc/test/shared/CMakeLists.txt33
-rw-r--r--libc/test/shared/shared_math_test.cpp80
-rw-r--r--libc/test/src/CMakeLists.txt4
-rw-r--r--libc/test/src/__support/CMakeLists.txt1
-rw-r--r--libc/test/src/__support/CPP/CMakeLists.txt1
-rw-r--r--libc/test/src/__support/CPP/bit_test.cpp3
-rw-r--r--libc/test/src/__support/FPUtil/CMakeLists.txt18
-rw-r--r--libc/test/src/__support/FPUtil/comparison_operations_test.cpp350
-rw-r--r--libc/test/src/__support/File/platform_file_test.cpp20
-rw-r--r--libc/test/src/__support/HashTable/CMakeLists.txt1
-rw-r--r--libc/test/src/__support/HashTable/group_test.cpp2
-rw-r--r--libc/test/src/__support/str_to_float_comparison_test.cpp2
-rw-r--r--libc/test/src/__support/wchar/CMakeLists.txt17
-rw-r--r--libc/test/src/__support/wchar/wcsnrtombs_test.cpp213
-rw-r--r--libc/test/src/fenv/feclearexcept_test.cpp1
-rw-r--r--libc/test/src/math/FmaTest.h7
-rw-r--r--libc/test/src/math/HypotTest.h5
-rw-r--r--libc/test/src/math/LdExpTest.h2
-rw-r--r--libc/test/src/math/acosf_test.cpp3
-rw-r--r--libc/test/src/math/acoshf16_test.cpp2
-rw-r--r--libc/test/src/math/acoshf_test.cpp3
-rw-r--r--libc/test/src/math/asinf_test.cpp3
-rw-r--r--libc/test/src/math/asinhf_test.cpp3
-rw-r--r--libc/test/src/math/atanf_test.cpp3
-rw-r--r--libc/test/src/math/atanhf16_test.cpp2
-rw-r--r--libc/test/src/math/atanhf_test.cpp3
-rw-r--r--libc/test/src/math/cosf_test.cpp3
-rw-r--r--libc/test/src/math/coshf_test.cpp3
-rw-r--r--libc/test/src/math/erff_test.cpp2
-rw-r--r--libc/test/src/math/exp10_test.cpp2
-rw-r--r--libc/test/src/math/exp10f_test.cpp2
-rw-r--r--libc/test/src/math/exp10m1f_test.cpp2
-rw-r--r--libc/test/src/math/exp2_test.cpp2
-rw-r--r--libc/test/src/math/exp2f_test.cpp2
-rw-r--r--libc/test/src/math/exp2m1f_test.cpp2
-rw-r--r--libc/test/src/math/exp_test.cpp2
-rw-r--r--libc/test/src/math/expf_test.cpp2
-rw-r--r--libc/test/src/math/explogxf_test.cpp5
-rw-r--r--libc/test/src/math/expm1_test.cpp2
-rw-r--r--libc/test/src/math/expm1f_test.cpp2
-rw-r--r--libc/test/src/math/in_float_range_test_helper.h2
-rw-r--r--libc/test/src/math/log10_test.cpp2
-rw-r--r--libc/test/src/math/log10f_test.cpp2
-rw-r--r--libc/test/src/math/log1p_test.cpp2
-rw-r--r--libc/test/src/math/log1pf_test.cpp2
-rw-r--r--libc/test/src/math/log2_test.cpp2
-rw-r--r--libc/test/src/math/log2f_test.cpp2
-rw-r--r--libc/test/src/math/log_test.cpp2
-rw-r--r--libc/test/src/math/logf_test.cpp2
-rw-r--r--libc/test/src/math/performance_testing/Timer.h2
-rw-r--r--libc/test/src/math/performance_testing/fmodf16_perf.cpp2
-rw-r--r--libc/test/src/math/powf_test.cpp2
-rw-r--r--libc/test/src/math/sdcomp26094.h3
-rw-r--r--libc/test/src/math/sincosf_test.cpp2
-rw-r--r--libc/test/src/math/sinf_test.cpp2
-rw-r--r--libc/test/src/math/sinhf_test.cpp2
-rw-r--r--libc/test/src/math/sinpif_test.cpp2
-rw-r--r--libc/test/src/math/smoke/CMakeLists.txt5
-rw-r--r--libc/test/src/math/smoke/LdExpTest.h3
-rw-r--r--libc/test/src/math/smoke/acosf_test.cpp2
-rw-r--r--libc/test/src/math/smoke/acoshf_test.cpp2
-rw-r--r--libc/test/src/math/smoke/asinf_test.cpp2
-rw-r--r--libc/test/src/math/smoke/asinhf_test.cpp2
-rw-r--r--libc/test/src/math/smoke/atanf_test.cpp2
-rw-r--r--libc/test/src/math/smoke/atanhf_test.cpp2
-rw-r--r--libc/test/src/math/smoke/cosf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/coshf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/cospif_test.cpp3
-rw-r--r--libc/test/src/math/smoke/erff_test.cpp3
-rw-r--r--libc/test/src/math/smoke/exp10_test.cpp3
-rw-r--r--libc/test/src/math/smoke/exp10f_test.cpp3
-rw-r--r--libc/test/src/math/smoke/exp2_test.cpp3
-rw-r--r--libc/test/src/math/smoke/exp2f_test.cpp3
-rw-r--r--libc/test/src/math/smoke/exp_test.cpp3
-rw-r--r--libc/test/src/math/smoke/expf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/expm1_test.cpp3
-rw-r--r--libc/test/src/math/smoke/expm1f_test.cpp3
-rw-r--r--libc/test/src/math/smoke/log10_test.cpp3
-rw-r--r--libc/test/src/math/smoke/log10f_test.cpp3
-rw-r--r--libc/test/src/math/smoke/log1pf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/log2_test.cpp3
-rw-r--r--libc/test/src/math/smoke/log2f_test.cpp3
-rw-r--r--libc/test/src/math/smoke/log_test.cpp3
-rw-r--r--libc/test/src/math/smoke/logf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/nan_test.cpp5
-rw-r--r--libc/test/src/math/smoke/nanf128_test.cpp5
-rw-r--r--libc/test/src/math/smoke/nanf16_test.cpp5
-rw-r--r--libc/test/src/math/smoke/nanf_test.cpp5
-rw-r--r--libc/test/src/math/smoke/nanl_test.cpp5
-rw-r--r--libc/test/src/math/smoke/powf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/sincosf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/sinf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/sinhf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/sinpif_test.cpp3
-rw-r--r--libc/test/src/math/smoke/tanf_test.cpp3
-rw-r--r--libc/test/src/math/smoke/tanhf_test.cpp3
-rw-r--r--libc/test/src/math/tanf_test.cpp2
-rw-r--r--libc/test/src/math/tanhf_test.cpp2
-rw-r--r--libc/test/src/signal/CMakeLists.txt1
-rw-r--r--libc/test/src/signal/sigaltstack_test.cpp2
-rw-r--r--libc/test/src/spawn/CMakeLists.txt1
-rw-r--r--libc/test/src/spawn/posix_spawn_file_actions_test.cpp2
-rw-r--r--libc/test/src/stdfix/IdivTest.h4
-rw-r--r--libc/test/src/stdio/fdopen_test.cpp9
-rw-r--r--libc/test/src/stdio/fgetc_test.cpp5
-rw-r--r--libc/test/src/stdio/fgetc_unlocked_test.cpp5
-rw-r--r--libc/test/src/stdio/fgets_test.cpp2
-rw-r--r--libc/test/src/stdio/fileop_test.cpp7
-rw-r--r--libc/test/src/stdio/fopen_test.cpp6
-rw-r--r--libc/test/src/stdio/fprintf_test.cpp2
-rw-r--r--libc/test/src/stdio/fscanf_test.cpp2
-rw-r--r--libc/test/src/stdio/ftell_test.cpp2
-rw-r--r--libc/test/src/stdio/putc_test.cpp2
-rw-r--r--libc/test/src/stdio/remove_test.cpp4
-rw-r--r--libc/test/src/stdio/rename_test.cpp6
-rw-r--r--libc/test/src/stdio/setbuf_test.cpp6
-rw-r--r--libc/test/src/stdio/setvbuf_test.cpp7
-rw-r--r--libc/test/src/stdio/ungetc_test.cpp2
-rw-r--r--libc/test/src/stdio/unlocked_fileop_test.cpp3
-rw-r--r--libc/test/src/stdio/vfprintf_test.cpp2
-rw-r--r--libc/test/src/stdio/vfscanf_test.cpp2
-rw-r--r--libc/test/src/stdlib/CMakeLists.txt3
-rw-r--r--libc/test/src/stdlib/memalignment_test.cpp3
-rw-r--r--libc/test/src/stdlib/strtoint32_test.cpp3
-rw-r--r--libc/test/src/stdlib/strtoint64_test.cpp3
-rw-r--r--libc/test/src/string/memchr_test.cpp4
-rw-r--r--libc/test/src/string/memcmp_test.cpp4
-rw-r--r--libc/test/src/string/memcpy_test.cpp4
-rw-r--r--libc/test/src/string/memmove_test.cpp4
-rw-r--r--libc/test/src/string/memory_utils/CMakeLists.txt1
-rw-r--r--libc/test/src/string/memory_utils/memory_check_utils.h2
-rw-r--r--libc/test/src/string/memory_utils/protected_pages.h2
-rw-r--r--libc/test/src/string/mempcpy_test.cpp4
-rw-r--r--libc/test/src/string/memrchr_test.cpp4
-rw-r--r--libc/test/src/string/memset_test.cpp4
-rw-r--r--libc/test/src/string/stpncpy_test.cpp4
-rw-r--r--libc/test/src/string/strcat_test.cpp4
-rw-r--r--libc/test/src/string/strcoll_test.cpp4
-rw-r--r--libc/test/src/string/strcpy_test.cpp4
-rw-r--r--libc/test/src/string/strsep_test.cpp4
-rw-r--r--libc/test/src/string/strspn_test.cpp4
-rw-r--r--libc/test/src/sys/epoll/linux/epoll_create_test.cpp3
-rw-r--r--libc/test/src/wchar/CMakeLists.txt93
-rw-r--r--libc/test/src/wchar/mblen_test.cpp104
-rw-r--r--libc/test/src/wchar/mbrlen_test.cpp139
-rw-r--r--libc/test/src/wchar/mbrtowc_test.cpp12
-rw-r--r--libc/test/src/wchar/mbsinit_test.cpp33
-rw-r--r--libc/test/src/wchar/wcpncpy_test.cpp4
-rw-r--r--libc/test/src/wchar/wcscmp_test.cpp4
-rw-r--r--libc/test/src/wchar/wcsdup_test.cpp48
-rw-r--r--libc/test/src/wchar/wcsncmp_test.cpp4
-rw-r--r--libc/test/src/wchar/wcsnrtombs_test.cpp192
-rw-r--r--libc/test/src/wchar/wcspbrk_test.cpp4
-rw-r--r--libc/test/src/wchar/wcsrchr_test.cpp4
-rw-r--r--libc/test/src/wchar/wcsrtombs_test.cpp150
-rw-r--r--libc/test/src/wchar/wcstol_test.cpp2
-rw-r--r--libc/test/src/wchar/wcstoll_test.cpp2
-rw-r--r--libc/test/src/wchar/wcstombs_test.cpp84
-rw-r--r--libc/test/src/wchar/wcstoul_test.cpp2
-rw-r--r--libc/test/src/wchar/wcstoull_test.cpp2
-rw-r--r--libc/test/src/wchar/wmemcmp_test.cpp4
-rw-r--r--libc/test/src/wchar/wmemmove_test.cpp4
-rw-r--r--libc/utils/MPCWrapper/CMakeLists.txt1
-rw-r--r--libc/utils/MPCWrapper/MPCUtils.cpp3
-rw-r--r--libc/utils/MPCWrapper/MPCUtils.h3
-rw-r--r--libc/utils/MPFRWrapper/CMakeLists.txt2
-rw-r--r--libc/utils/MPFRWrapper/MPCommon.h3
-rw-r--r--libc/utils/MPFRWrapper/MPFRUtils.h3
445 files changed, 6054 insertions, 2211 deletions
diff --git a/libc/benchmarks/gpu/BenchmarkLogger.cpp b/libc/benchmarks/gpu/BenchmarkLogger.cpp
index 0d644fa..d5996a7 100644
--- a/libc/benchmarks/gpu/BenchmarkLogger.cpp
+++ b/libc/benchmarks/gpu/BenchmarkLogger.cpp
@@ -1,4 +1,5 @@
#include "benchmarks/gpu/BenchmarkLogger.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/string.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/OSUtil/io.h" // write_to_stderr
@@ -7,8 +8,6 @@
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "src/__support/uint128.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace benchmarks {
diff --git a/libc/benchmarks/gpu/CMakeLists.txt b/libc/benchmarks/gpu/CMakeLists.txt
index b58f4fd..6ec64bf2 100644
--- a/libc/benchmarks/gpu/CMakeLists.txt
+++ b/libc/benchmarks/gpu/CMakeLists.txt
@@ -45,6 +45,7 @@ add_unittest_framework_library(
LibcGpuBenchmark.h
BenchmarkLogger.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.big_int
libc.src.__support.c_string
libc.src.__support.CPP.string
diff --git a/libc/benchmarks/gpu/LibcGpuBenchmark.h b/libc/benchmarks/gpu/LibcGpuBenchmark.h
index f2cfbfb..a6cf62d 100644
--- a/libc/benchmarks/gpu/LibcGpuBenchmark.h
+++ b/libc/benchmarks/gpu/LibcGpuBenchmark.h
@@ -3,6 +3,7 @@
#include "benchmarks/gpu/BenchmarkLogger.h"
#include "benchmarks/gpu/timing/timing.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/functional.h"
#include "src/__support/CPP/limits.h"
@@ -13,8 +14,6 @@
#include "src/stdlib/rand.h"
#include "src/time/clock.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace benchmarks {
diff --git a/libc/benchmarks/gpu/src/math/CMakeLists.txt b/libc/benchmarks/gpu/src/math/CMakeLists.txt
index 6870c02..7a12ce4e 100644
--- a/libc/benchmarks/gpu/src/math/CMakeLists.txt
+++ b/libc/benchmarks/gpu/src/math/CMakeLists.txt
@@ -31,6 +31,7 @@ add_benchmark(
SRCS
sin_benchmark.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.math.sin
libc.src.math.sinf
libc.src.stdlib.srand
@@ -51,6 +52,7 @@ add_benchmark(
SRCS
atan2_benchmark.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.math.atan2
libc.src.stdlib.srand
libc.src.stdlib.rand
diff --git a/libc/benchmarks/gpu/src/math/platform.h b/libc/benchmarks/gpu/src/math/platform.h
index bb7825d..2dfa9f2 100644
--- a/libc/benchmarks/gpu/src/math/platform.h
+++ b/libc/benchmarks/gpu/src/math/platform.h
@@ -7,9 +7,10 @@
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_MATH_AMDGPU_PLATFORM_H
#define LLVM_LIBC_SRC_MATH_AMDGPU_PLATFORM_H
+
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt b/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt
index aa5dcd3..dd7c2d3 100644
--- a/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt
+++ b/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt
@@ -3,6 +3,7 @@ add_header_library(
HDRS
timing.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.macros.config
libc.src.__support.macros.attributes
diff --git a/libc/benchmarks/gpu/timing/amdgpu/timing.h b/libc/benchmarks/gpu/timing/amdgpu/timing.h
index 0f2c04c..37dbb9a 100644
--- a/libc/benchmarks/gpu/timing/amdgpu/timing.h
+++ b/libc/benchmarks/gpu/timing/amdgpu/timing.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_UTILS_GPU_TIMING_AMDGPU
#define LLVM_LIBC_UTILS_GPU_TIMING_AMDGPU
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/type_traits.h"
@@ -17,8 +18,6 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
// Returns the overhead associated with calling the profiling region. This
diff --git a/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt b/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt
index 2723c89..a19c16e 100644
--- a/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt
+++ b/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt
@@ -3,6 +3,7 @@ add_header_library(
HDRS
timing.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.macros.config
libc.src.__support.macros.attributes
diff --git a/libc/benchmarks/gpu/timing/nvptx/timing.h b/libc/benchmarks/gpu/timing/nvptx/timing.h
index 3ed9764..3c72963 100644
--- a/libc/benchmarks/gpu/timing/nvptx/timing.h
+++ b/libc/benchmarks/gpu/timing/nvptx/timing.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_UTILS_GPU_TIMING_NVPTX
#define LLVM_LIBC_UTILS_GPU_TIMING_NVPTX
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/type_traits.h"
@@ -17,8 +18,6 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
// Returns the overhead associated with calling the profiling region. This
diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake
index c94a407..d4103f8 100644
--- a/libc/cmake/modules/LLVMLibCArchitectures.cmake
+++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake
@@ -153,9 +153,11 @@ elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "x86_64")
elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "i386")
set(LIBC_TARGET_ARCHITECTURE_IS_X86 TRUE)
elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv64")
+ set(LIBC_TARGET_ARCHITECTURE_IS_ANY_RISCV TRUE)
set(LIBC_TARGET_ARCHITECTURE_IS_RISCV64 TRUE)
set(LIBC_TARGET_ARCHITECTURE "riscv")
elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv32")
+ set(LIBC_TARGET_ARCHITECTURE_IS_ANY_RISCV TRUE)
set(LIBC_TARGET_ARCHITECTURE_IS_RISCV32 TRUE)
set(LIBC_TARGET_ARCHITECTURE "riscv")
elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "amdgpu")
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index 82d06e2..2478fde 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -13,7 +13,7 @@ endif()
function(_get_compile_options_from_flags output_var)
set(compile_options "")
- if(LIBC_TARGET_ARCHITECTURE_IS_RISCV64 OR(LIBC_CPU_FEATURES MATCHES "FMA"))
+ if(LIBC_CPU_FEATURES MATCHES "FMA")
check_flag(ADD_FMA_FLAG ${FMA_OPT_FLAG} ${ARGN})
endif()
check_flag(ADD_ROUND_OPT_FLAG ${ROUND_OPT_FLAG} ${ARGN})
@@ -25,8 +25,6 @@ function(_get_compile_options_from_flags output_var)
if(LIBC_TARGET_ARCHITECTURE_IS_X86_64)
list(APPEND compile_options "-mavx2")
list(APPEND compile_options "-mfma")
- elseif(LIBC_TARGET_ARCHITECTURE_IS_RISCV64)
- list(APPEND compile_options "-D__LIBC_RISCV_USE_FMA")
endif()
# For clang, we will build the math functions with `-fno-math-errno` so that
# __builtin_fma* will generate the fused-mutliply-add instructions. We
diff --git a/libc/cmake/modules/LLVMLibCFlagRules.cmake b/libc/cmake/modules/LLVMLibCFlagRules.cmake
index 7d5e73c..4bbd21a 100644
--- a/libc/cmake/modules/LLVMLibCFlagRules.cmake
+++ b/libc/cmake/modules/LLVMLibCFlagRules.cmake
@@ -270,7 +270,7 @@ set(MISC_MATH_BASIC_OPS_OPT_FLAG "MISC_MATH_BASIC_OPS_OPT")
# Skip FMA_OPT flag for targets that don't support fma.
if(NOT DEFINED SKIP_FLAG_EXPANSION_FMA_OPT)
if(NOT((LIBC_TARGET_ARCHITECTURE_IS_X86_64 AND (LIBC_CPU_FEATURES MATCHES "FMA")) OR
- LIBC_TARGET_ARCHITECTURE_IS_RISCV64))
+ LIBC_TARGET_ARCHITECTURE_IS_ANY_RISCV))
set(SKIP_FLAG_EXPANSION_FMA_OPT TRUE)
endif()
endif()
diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
index 3fb6278..267c32e 100644
--- a/libc/cmake/modules/LLVMLibCTestRules.cmake
+++ b/libc/cmake/modules/LLVMLibCTestRules.cmake
@@ -71,6 +71,7 @@ endfunction()
function(_get_hermetic_test_compile_options output_var)
_get_common_test_compile_options(compile_options "" "")
+ list(APPEND compile_options "-DLIBC_TEST=HERMETIC")
# null check tests are death tests, remove from hermetic tests for now.
if(LIBC_ADD_NULL_CHECKS)
@@ -232,6 +233,7 @@ function(create_libc_unittest fq_target_name)
_get_common_test_compile_options(compile_options "${LIBC_UNITTEST_C_TEST}"
"${LIBC_UNITTEST_FLAGS}")
+ list(APPEND compile_options "-DLIBC_TEST=UNIT")
# TODO: Ideally we would have a separate function for link options.
set(link_options
${compile_options}
diff --git a/libc/config/CMakeLists.txt b/libc/config/CMakeLists.txt
index cf38ae3..4758276 100644
--- a/libc/config/CMakeLists.txt
+++ b/libc/config/CMakeLists.txt
@@ -3,5 +3,6 @@ add_header_library(
HDRS
app.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.common
)
diff --git a/libc/config/gpu/app.h b/libc/config/gpu/app.h
index 148c51b..17ef3ae 100644
--- a/libc/config/gpu/app.h
+++ b/libc/config/gpu/app.h
@@ -9,11 +9,10 @@
#ifndef LLVM_LIBC_CONFIG_GPU_APP_H
#define LLVM_LIBC_CONFIG_GPU_APP_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
// TODO: Move other global values here and export them to the host.
diff --git a/libc/config/linux/app.h b/libc/config/linux/app.h
index 188d348..f3d11da 100644
--- a/libc/config/linux/app.h
+++ b/libc/config/linux/app.h
@@ -9,11 +9,10 @@
#ifndef LLVM_LIBC_CONFIG_LINUX_APP_H
#define LLVM_LIBC_CONFIG_LINUX_APP_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
// Data structure to capture properties of the linux/ELF TLS image.
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 381359c..5e8278e 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -377,6 +377,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.wchar.wcsrchr
libc.src.wchar.wcsspn
libc.src.wchar.wcscspn
+ libc.src.wchar.wcsdup
libc.src.wchar.wmemcmp
libc.src.wchar.wmempcpy
libc.src.wchar.wmemcpy
@@ -1261,10 +1262,16 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.sys.socket.recvmsg
# wchar.h entrypoints
+ libc.src.wchar.mblen
+ libc.src.wchar.mbrlen
+ libc.src.wchar.mbsinit
libc.src.wchar.mbrtowc
libc.src.wchar.mbtowc
libc.src.wchar.wcrtomb
libc.src.wchar.wctomb
+ libc.src.wchar.wcstombs
+ libc.src.wchar.wcsrtombs
+ libc.src.wchar.wcsnrtombs
)
endif()
diff --git a/libc/config/uefi/app.h b/libc/config/uefi/app.h
index 0374a47..1f181ed 100644
--- a/libc/config/uefi/app.h
+++ b/libc/config/uefi/app.h
@@ -9,13 +9,12 @@
#ifndef LLVM_LIBC_CONFIG_UEFI_APP_H
#define LLVM_LIBC_CONFIG_UEFI_APP_H
+#include "hdr/stdint_proxy.h"
#include "include/llvm-libc-types/EFI_HANDLE.h"
#include "include/llvm-libc-types/EFI_SYSTEM_TABLE.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
// Data structure which captures properties of a UEFI application.
diff --git a/libc/fuzzing/math/CMakeLists.txt b/libc/fuzzing/math/CMakeLists.txt
index c1a9305..19416fc 100644
--- a/libc/fuzzing/math/CMakeLists.txt
+++ b/libc/fuzzing/math/CMakeLists.txt
@@ -196,3 +196,39 @@ add_libc_fuzzer(
DEPENDS
libc.src.__support.FPUtil.generic.sqrt
)
+
+add_libc_fuzzer(
+ cbrt_fuzz
+ NEED_MPFR
+ SRCS
+ cbrt_fuzz.cpp
+ DEPENDS
+ libc.src.math.cbrt
+)
+
+add_libc_fuzzer(
+ fsqrt_fuzz
+ NEED_MPFR
+ SRCS
+ fsqrt_fuzz.cpp
+ DEPENDS
+ libc.src.math.fsqrt
+)
+
+add_libc_fuzzer(
+ f16sqrt_fuzz
+ NEED_MPFR
+ SRCS
+ f16sqrt_fuzz.cpp
+ DEPENDS
+ libc.src.math.f16sqrt
+)
+
+add_libc_fuzzer(
+ hypot_fuzz
+ NEED_MPFR
+ SRCS
+ hypot_fuzz.cpp
+ DEPENDS
+ libc.src.math.hypot
+)
diff --git a/libc/fuzzing/math/cbrt_fuzz.cpp b/libc/fuzzing/math/cbrt_fuzz.cpp
new file mode 100644
index 0000000..95f1df1
--- /dev/null
+++ b/libc/fuzzing/math/cbrt_fuzz.cpp
@@ -0,0 +1,50 @@
+//===-- cbrt_fuzz.cpp -----------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Fuzzing test for llvm-libc cbrt implementation.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/math/cbrt.h"
+#include "utils/MPFRWrapper/mpfr_inc.h"
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+#include <math.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ mpfr_t input;
+ mpfr_init2(input, 53);
+ for (size_t i = 0; i < size / sizeof(double); ++i) {
+ double x;
+ std::memcpy(&x, data, sizeof(double));
+ data += sizeof(double);
+ // remove NaN and inf
+ if (isnan(x) || isinf(x))
+ continue;
+ // signed zeros already tested in unit tests
+ if (signbit(x) && x == 0.0)
+ continue;
+
+ mpfr_set_d(input, x, MPFR_RNDN);
+ int output = mpfr_cbrt(input, input, MPFR_RNDN);
+ mpfr_subnormalize(input, output, MPFR_RNDN);
+ double to_compare = mpfr_get_d(input, MPFR_RNDN);
+
+ double result = LIBC_NAMESPACE::cbrt(x);
+
+ if (result != to_compare) {
+ std::cout << std::hexfloat << "Failing input: " << x << std::endl;
+ std::cout << std::hexfloat << "Failing output: " << result << std::endl;
+ std::cout << std::hexfloat << "Expected: " << to_compare << std::endl;
+ __builtin_trap();
+ }
+ }
+ mpfr_clear(input);
+ return 0;
+}
diff --git a/libc/fuzzing/math/f16sqrt_fuzz.cpp b/libc/fuzzing/math/f16sqrt_fuzz.cpp
new file mode 100644
index 0000000..9a097a5
--- /dev/null
+++ b/libc/fuzzing/math/f16sqrt_fuzz.cpp
@@ -0,0 +1,56 @@
+//===-- f16sqrt_fuzz.cpp --------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Fuzzing test for llvm-libc f16sqrt implementation.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/math/f16sqrt.h"
+#include "utils/MPFRWrapper/mpfr_inc.h"
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+#include <math.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ mpfr_t input;
+ mpfr_t out;
+ mpfr_init2(input, 53);
+ mpfr_init2(out, 128);
+ for (size_t i = 0; i < size / sizeof(double); ++i) {
+ double x;
+ std::memcpy(&x, data, sizeof(double));
+ data += sizeof(double);
+
+ // remove NaN, inf, and values outside the accepted range
+ if (isnan(x) || isinf(x) || x < 0)
+ continue;
+ // signed zeros already tested in unit tests
+ if (signbit(x) && x == 0.0)
+ continue;
+
+ mpfr_set_d(input, x, MPFR_RNDN);
+ mpfr_sqrt(out, input, MPFR_RNDN);
+ float16 to_compare = mpfr_get_d(out, MPFR_RNDN);
+
+ float16 result = LIBC_NAMESPACE::f16sqrt(x);
+
+ if (result != to_compare) {
+ std::cout << std::hexfloat << "Failing input: " << x << std::endl;
+ std::cout << std::hexfloat
+ << "Failing output: " << static_cast<float>(result)
+ << std::endl;
+ std::cout << std::hexfloat
+ << "Expected: " << static_cast<float>(to_compare) << std::endl;
+ __builtin_trap();
+ }
+ }
+ mpfr_clear(input);
+ mpfr_clear(out);
+ return 0;
+}
diff --git a/libc/fuzzing/math/fsqrt_fuzz.cpp b/libc/fuzzing/math/fsqrt_fuzz.cpp
new file mode 100644
index 0000000..06bb231
--- /dev/null
+++ b/libc/fuzzing/math/fsqrt_fuzz.cpp
@@ -0,0 +1,53 @@
+//===-- fsqrt_fuzz.cpp ----------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Fuzzing test for llvm-libc fsqrt implementation.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/math/fsqrt.h"
+#include "utils/MPFRWrapper/mpfr_inc.h"
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+#include <math.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ mpfr_t input;
+ mpfr_t out;
+ mpfr_init2(input, 53);
+ mpfr_init2(out, 128);
+ for (size_t i = 0; i < size / sizeof(double); ++i) {
+ double x;
+ std::memcpy(&x, data, sizeof(double));
+ data += sizeof(double);
+
+ // remove NaN, inf, and values outside the accepted range
+ if (isnan(x) || isinf(x) || x < 0)
+ continue;
+ // signed zeros already tested in unit tests
+ if (signbit(x) && x == 0.0)
+ continue;
+
+ mpfr_set_d(input, x, MPFR_RNDN);
+ mpfr_sqrt(out, input, MPFR_RNDN);
+ float to_compare = mpfr_get_flt(out, MPFR_RNDN);
+
+ float result = LIBC_NAMESPACE::fsqrt(x);
+
+ if (result != to_compare) {
+ std::cout << std::hexfloat << "Failing input: " << x << std::endl;
+ std::cout << std::hexfloat << "Failing output: " << result << std::endl;
+ std::cout << std::hexfloat << "Expected: " << to_compare << std::endl;
+ __builtin_trap();
+ }
+ }
+ mpfr_clear(input);
+ mpfr_clear(out);
+ return 0;
+}
diff --git a/libc/fuzzing/math/hypot_fuzz.cpp b/libc/fuzzing/math/hypot_fuzz.cpp
new file mode 100644
index 0000000..6129e41
--- /dev/null
+++ b/libc/fuzzing/math/hypot_fuzz.cpp
@@ -0,0 +1,64 @@
+//===-- hypot_fuzz.cpp ----------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Fuzzing test for llvm-libc hypot implementation.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/math/hypot.h"
+#include "utils/MPFRWrapper/mpfr_inc.h"
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+#include <math.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ mpfr_t in_x;
+ mpfr_t in_y;
+ mpfr_t out;
+ mpfr_init2(in_x, 53);
+ mpfr_init2(in_y, 53);
+ mpfr_init2(out, 128);
+
+ for (size_t i = 0; i < size / (2 * sizeof(double)); ++i) {
+ double x;
+ double y;
+
+ std::memcpy(&x, data, sizeof(double));
+ data += sizeof(double);
+ std::memcpy(&y, data, sizeof(double));
+ data += sizeof(double);
+
+ // remove NaN, inf, and signed zeros
+ if (isnan(x) || isinf(x) || (signbit(x) && x == 0.0))
+ return 0;
+ if (isnan(y) || isinf(y) || (signbit(y) && y == 0.0))
+ return 0;
+
+ mpfr_set_d(in_x, x, MPFR_RNDN);
+ mpfr_set_d(in_y, y, MPFR_RNDN);
+
+ int output = mpfr_hypot(out, in_x, in_y, MPFR_RNDN);
+ mpfr_subnormalize(out, output, MPFR_RNDN);
+ double to_compare = mpfr_get_d(out, MPFR_RNDN);
+
+ double result = LIBC_NAMESPACE::hypot(x, y);
+
+ if (result != to_compare) {
+ std::cout << std::hexfloat << "Failing x: " << x << std::endl;
+ std::cout << std::hexfloat << "Failing y: " << y << std::endl;
+ std::cout << std::hexfloat << "Failing output: " << result << std::endl;
+ std::cout << std::hexfloat << "Expected: " << to_compare << std::endl;
+ __builtin_trap();
+ }
+ }
+ mpfr_clear(in_x);
+ mpfr_clear(in_y);
+ mpfr_clear(out);
+ return 0;
+}
diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt
index 052a773..5fc25d0 100644
--- a/libc/hdr/CMakeLists.txt
+++ b/libc/hdr/CMakeLists.txt
@@ -243,5 +243,14 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.offsetof_macro
)
+# stdint.h header.
+add_proxy_header_library(
+ stdint_proxy
+ HDRS
+ stdint_proxy.h
+ FULL_BUILD_DEPENDS
+ libc.include.stdint
+)
+
add_subdirectory(types)
add_subdirectory(func)
diff --git a/libc/hdr/stdint_proxy.h b/libc/hdr/stdint_proxy.h
new file mode 100644
index 0000000..8e81567
--- /dev/null
+++ b/libc/hdr/stdint_proxy.h
@@ -0,0 +1,18 @@
+//===-- stdint.h ----------------------------------------------------------===//
+//
+// 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_HDR_STDINT_PROXY_H
+#define LLVM_LIBC_HDR_STDINT_PROXY_H
+
+// This target is to make sure we have correct build order in full build mode,
+// that is `libc.include.stdint` is added to the dependency of all targets
+// that use <stdint.h> header.
+
+#include <stdint.h>
+
+#endif // LLVM_LIBC_HDR_STDINT_PROXY_H
diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index e4b3cb0..c212363 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -26,6 +26,8 @@ add_proxy_header_library(
mbstate_t.h
DEPENDS
libc.include.llvm-libc-types.mbstate_t
+ FULL_BUILD_DEPENDS
+ libc.include.uchar
)
add_proxy_header_library(
@@ -92,6 +94,7 @@ add_proxy_header_library(
DEPENDS
libc.hdr.fcntl_overlay
FULL_BUILD_DEPENDS
+ libc.hdr.stdint_proxy
libc.include.llvm-libc-types.struct_flock
)
@@ -102,6 +105,7 @@ add_proxy_header_library(
DEPENDS
libc.hdr.fcntl_overlay
FULL_BUILD_DEPENDS
+ libc.hdr.stdint_proxy
libc.include.llvm-libc-types.struct_flock64
)
@@ -316,6 +320,15 @@ add_proxy_header_library(
)
add_proxy_header_library(
+ sigjmp_buf
+ HDRS
+ sigjmp_buf.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.sigjmp_buf
+ libc.include.setjmp
+)
+
+add_proxy_header_library(
struct_msghdr
HDRS
struct_msghdr.h
diff --git a/libc/hdr/types/jmp_buf.h b/libc/hdr/types/jmp_buf.h
index 3fa1de8..b242f84 100644
--- a/libc/hdr/types/jmp_buf.h
+++ b/libc/hdr/types/jmp_buf.h
@@ -1,4 +1,4 @@
-//===-- Definition of jmp_buf.h ------------------------------------------===//
+//===-- Definition of jmp_buf.h -------------------------------------------===//
//
// Part of the LLVM Project, under the Apahce License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/hdr/types/sigjmp_buf.h b/libc/hdr/types/sigjmp_buf.h
new file mode 100644
index 0000000..5da5243
--- /dev/null
+++ b/libc/hdr/types/sigjmp_buf.h
@@ -0,0 +1,22 @@
+//===-- Definition of sigjmp_buf.h ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apahce 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_HDR_TYPES_SIGJMP_BUF_H
+#define LLVM_LIBC_HDR_TYPES_SIGJMP_BUF_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/sigjmp_buf.h"
+
+#else // overlay mode
+
+#include <setjmp.h>
+
+#endif // LLVM_LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_SIGJMP_BUF_H
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 7321382..120f385 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -102,6 +102,14 @@ add_header_macro(
)
add_header_macro(
+ stdint
+ ../libc/include/stdint.yaml
+ stdint.h
+ DEPENDS
+ .llvm-libc-macros.stdint_macros
+)
+
+add_header_macro(
inttypes
../libc/include/inttypes.yaml
inttypes.h
@@ -109,6 +117,7 @@ add_header_macro(
.llvm_libc_common_h
.llvm-libc-types.imaxdiv_t
.llvm-libc-macros.inttypes_macros
+ .stdint
)
add_header_macro(
@@ -120,14 +129,6 @@ add_header_macro(
)
add_header_macro(
- stdint
- ../libc/include/stdint.yaml
- stdint.h
- DEPENDS
- .llvm-libc-macros.stdint_macros
-)
-
-add_header_macro(
limits
../libc/include/limits.yaml
limits.h
@@ -186,6 +187,7 @@ add_header_macro(
arpa/inet.h
DEPENDS
.llvm_libc_common_h
+ .inttypes
)
add_header_macro(
@@ -213,6 +215,7 @@ add_header_macro(
DEPENDS
.llvm_libc_common_h
.llvm-libc-types.jmp_buf
+ .llvm-libc-types.sigjmp_buf
)
add_header_macro(
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index b24c973..4ccdde6 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -82,7 +82,9 @@ add_header(union_sigval HDR union_sigval.h)
add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t .clock_t)
add_header(sig_atomic_t HDR sig_atomic_t.h)
add_header(sigset_t HDR sigset_t.h DEPENDS libc.include.llvm-libc-macros.signal_macros)
-add_header(jmp_buf HDR jmp_buf.h DEPENDS .sigset_t)
+add_header(__jmp_buf HDR __jmp_buf.h DEPENDS .sigset_t)
+add_header(jmp_buf HDR jmp_buf.h DEPENDS .__jmp_buf)
+add_header(sigjmp_buf HDR sigjmp_buf.h DEPENDS .__jmp_buf)
add_header(struct_sigaction HDR struct_sigaction.h DEPENDS .sigset_t .siginfo_t)
add_header(struct_timespec HDR struct_timespec.h DEPENDS .time_t)
add_header(
diff --git a/libc/include/llvm-libc-types/__jmp_buf.h b/libc/include/llvm-libc-types/__jmp_buf.h
new file mode 100644
index 0000000..a80afa2
--- /dev/null
+++ b/libc/include/llvm-libc-types/__jmp_buf.h
@@ -0,0 +1,78 @@
+//===-- Definition of type __jmp_buf --------------------------------------===//
+//
+// 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_TYPES___JMP_BUF_H
+#define LLVM_LIBC_TYPES___JMP_BUF_H
+
+// TODO: implement sigjmp_buf related functions for other architectures
+// Issue: https://github.com/llvm/llvm-project/issues/136358
+#if defined(__linux__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
+ defined(__arm__) || defined(__riscv)
+#define __LIBC_HAS_SIGJMP_BUF
+#endif
+#endif
+
+#if defined(__LIBC_HAS_SIGJMP_BUF)
+#include "sigset_t.h"
+#endif
+
+typedef struct {
+#ifdef __x86_64__
+ __UINT64_TYPE__ rbx;
+ __UINT64_TYPE__ rbp;
+ __UINT64_TYPE__ r12;
+ __UINT64_TYPE__ r13;
+ __UINT64_TYPE__ r14;
+ __UINT64_TYPE__ r15;
+ __UINTPTR_TYPE__ rsp;
+ __UINTPTR_TYPE__ rip;
+#elif defined(__i386__)
+ long ebx;
+ long esi;
+ long edi;
+ long ebp;
+ long esp;
+ long eip;
+#elif defined(__riscv)
+ /* Program counter. */
+ long int __pc;
+ /* Callee-saved registers. */
+ long int __regs[12];
+ /* Stack pointer. */
+ long int __sp;
+ /* Callee-saved floating point registers. */
+#if __riscv_float_abi_double
+ double __fpregs[12];
+#elif defined(__riscv_float_abi_single)
+#error "__jmp_buf not available for your target architecture."
+#endif
+#elif defined(__arm__)
+ // r4, r5, r6, r7, r8, r9, r10, r11, r12, lr
+ long opaque[10];
+#elif defined(__aarch64__)
+ long opaque[14]; // x19-x29, lr, sp, optional x18
+#if __ARM_FP
+ long fopaque[8]; // d8-d15
+#endif
+#else
+#error "__jmp_buf not available for your target architecture."
+#endif
+#if defined(__LIBC_HAS_SIGJMP_BUF)
+ // return address
+ void *sig_retaddr;
+ // extra register buffer to avoid indefinite stack growth in sigsetjmp
+ void *sig_extra;
+ // signal masks
+ sigset_t sigmask;
+#endif
+} __jmp_buf;
+
+#undef __LIBC_HAS_SIGJMP_BUF
+
+#endif // LLVM_LIBC_TYPES___JMP_BUF_H
diff --git a/libc/include/llvm-libc-types/jmp_buf.h b/libc/include/llvm-libc-types/jmp_buf.h
index 8a7d283..599310f 100644
--- a/libc/include/llvm-libc-types/jmp_buf.h
+++ b/libc/include/llvm-libc-types/jmp_buf.h
@@ -9,76 +9,8 @@
#ifndef LLVM_LIBC_TYPES_JMP_BUF_H
#define LLVM_LIBC_TYPES_JMP_BUF_H
-// TODO: implement sigjmp_buf related functions for other architectures
-// Issue: https://github.com/llvm/llvm-project/issues/136358
-#if defined(__linux__)
-#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
- defined(__arm__) || defined(__riscv)
-#define __LIBC_HAS_SIGJMP_BUF
-#endif
-#endif
-
-#if defined(__LIBC_HAS_SIGJMP_BUF)
-#include "sigset_t.h"
-#endif
-
-typedef struct {
-#ifdef __x86_64__
- __UINT64_TYPE__ rbx;
- __UINT64_TYPE__ rbp;
- __UINT64_TYPE__ r12;
- __UINT64_TYPE__ r13;
- __UINT64_TYPE__ r14;
- __UINT64_TYPE__ r15;
- __UINTPTR_TYPE__ rsp;
- __UINTPTR_TYPE__ rip;
-#elif defined(__i386__)
- long ebx;
- long esi;
- long edi;
- long ebp;
- long esp;
- long eip;
-#elif defined(__riscv)
- /* Program counter. */
- long int __pc;
- /* Callee-saved registers. */
- long int __regs[12];
- /* Stack pointer. */
- long int __sp;
- /* Callee-saved floating point registers. */
-#if __riscv_float_abi_double
- double __fpregs[12];
-#elif defined(__riscv_float_abi_single)
-#error "__jmp_buf not available for your target architecture."
-#endif
-#elif defined(__arm__)
- // r4, r5, r6, r7, r8, r9, r10, r11, r12, lr
- long opaque[10];
-#elif defined(__aarch64__)
- long opaque[14]; // x19-x29, lr, sp, optional x18
-#if __ARM_FP
- long fopaque[8]; // d8-d15
-#endif
-#else
-#error "__jmp_buf not available for your target architecture."
-#endif
-#if defined(__LIBC_HAS_SIGJMP_BUF)
- // return address
- void *sig_retaddr;
- // extra register buffer to avoid indefinite stack growth in sigsetjmp
- void *sig_extra;
- // signal masks
- sigset_t sigmask;
-#endif
-} __jmp_buf;
+#include "__jmp_buf.h"
typedef __jmp_buf jmp_buf[1];
-#if defined(__LIBC_HAS_SIGJMP_BUF)
-typedef __jmp_buf sigjmp_buf[1];
-#endif
-
-#undef __LIBC_HAS_SIGJMP_BUF
-
#endif // LLVM_LIBC_TYPES_JMP_BUF_H
diff --git a/libc/include/llvm-libc-types/sigjmp_buf.h b/libc/include/llvm-libc-types/sigjmp_buf.h
new file mode 100644
index 0000000..ae9028b
--- /dev/null
+++ b/libc/include/llvm-libc-types/sigjmp_buf.h
@@ -0,0 +1,16 @@
+//===-- Definition of type sigjmp_buf -------------------------------------===//
+//
+// 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_TYPES_SIGJMP_BUF_H
+#define LLVM_LIBC_TYPES_SIGJMP_BUF_H
+
+#include "__jmp_buf.h"
+
+typedef __jmp_buf sigjmp_buf[1];
+
+#endif // LLVM_LIBC_TYPES_SIGJMP_BUF_H
diff --git a/libc/include/math.yaml b/libc/include/math.yaml
index 3044ec3..007be23 100644
--- a/libc/include/math.yaml
+++ b/libc/include/math.yaml
@@ -33,14 +33,14 @@ functions:
return_type: float
arguments:
- type: float
- name: acoshf16
+ - name: acoshf16
standards:
- stdc
return_type: _Float16
arguments:
- type: _Float16
guard: LIBC_TYPES_HAS_FLOAT16
- name: acospif16
+ - name: acospif16
standards:
- stdc
return_type: _Float16
diff --git a/libc/include/wchar.yaml b/libc/include/wchar.yaml
index 123d344..6e1f595 100644
--- a/libc/include/wchar.yaml
+++ b/libc/include/wchar.yaml
@@ -53,6 +53,27 @@ functions:
- type: wchar_t *__restrict
- type: const char *__restrict
- type: size_t
+ - name: mbsinit
+ standards:
+ - stdc
+ return_type: int
+ arguments:
+ - type: mbstate_t *
+ - name: mblen
+ standards:
+ - stdc
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: size_t
+ - name: mbrlen
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: const char *__restrict
+ - type: size_t
+ - type: mbstate_t *__restrict
- name: wmemset
standards:
- stdc
@@ -189,6 +210,25 @@ functions:
- type: wchar_t *__restrict
- type: const wchar_t *__restrict
- type: size_t
+ - name: wcsnrtombs
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: char *__restrict
+ - type: const wchar_t **__restrict
+ - type: size_t
+ - type: size_t
+ - type: mbstate_t
+ - name: wcsrtombs
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: char *__restrict
+ - type: const wchar_t **__restrict
+ - type: size_t
+ - type: mbstate_t
- name: wcrtomb
standards:
- stdc
@@ -211,6 +251,12 @@ functions:
arguments:
- type: wchar_t *__restrict
- type: const wchar_t *__restrict
+ - name: wcsdup
+ standards:
+ - stdc
+ return_type: wchar_t *
+ arguments:
+ - type: const wchar_t *
- name: wcslcpy
standards:
- stdc
@@ -258,6 +304,14 @@ functions:
- type: const wchar_t *__restrict
- type: wchar_t **__restrict
- type: int
+ - name: wcstombs
+ standards:
+ - stdc
+ return_type: size_t
+ arguments:
+ - type: char *__restrict
+ - type: const wchar_t *__restrict
+ - type: size_t
- name: wcstoul
standards:
- stdc
diff --git a/libc/shared/math.h b/libc/shared/math.h
index 8dcfaf0..e0f00f5 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -12,6 +12,16 @@
#include "libc_common.h"
#include "math/acos.h"
+#include "math/acosf.h"
+#include "math/acosf16.h"
+#include "math/acoshf.h"
+#include "math/acoshf16.h"
+#include "math/acospif16.h"
+#include "math/asin.h"
+#include "math/asinf.h"
+#include "math/asinf16.h"
+#include "math/asinhf.h"
+#include "math/erff.h"
#include "math/exp.h"
#include "math/exp10.h"
#include "math/exp10f.h"
diff --git a/libc/shared/math/acosf.h b/libc/shared/math/acosf.h
new file mode 100644
index 0000000..7cdd64e
--- /dev/null
+++ b/libc/shared/math/acosf.h
@@ -0,0 +1,23 @@
+//===-- Shared acosf function -----------------------------------*- 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_SHARED_MATH_ACOSF_H
+#define LLVM_LIBC_SHARED_MATH_ACOSF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/acosf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::acosf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_ACOSF_H
diff --git a/libc/shared/math/acosf16.h b/libc/shared/math/acosf16.h
new file mode 100644
index 0000000..aaf6ed9
--- /dev/null
+++ b/libc/shared/math/acosf16.h
@@ -0,0 +1,29 @@
+//===-- Shared acosf16 function ---------------------------------*- 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_SHARED_MATH_ACOSF16_H
+#define LLVM_LIBC_SHARED_MATH_ACOSF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "shared/libc_common.h"
+#include "src/__support/math/acosf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::acosf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_MATH_ACOSF16_H
diff --git a/libc/shared/math/acoshf.h b/libc/shared/math/acoshf.h
new file mode 100644
index 0000000..86bdbce
--- /dev/null
+++ b/libc/shared/math/acoshf.h
@@ -0,0 +1,23 @@
+//===-- Shared acoshf function ----------------------------------*- 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_SHARED_MATH_ACOSHF_H
+#define LLVM_LIBC_SHARED_MATH_ACOSHF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/acoshf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::acoshf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_ACOSHF_H
diff --git a/libc/shared/math/acoshf16.h b/libc/shared/math/acoshf16.h
new file mode 100644
index 0000000..2f0bc6e
--- /dev/null
+++ b/libc/shared/math/acoshf16.h
@@ -0,0 +1,29 @@
+//===-- Shared acoshf16 function --------------------------------*- 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_SHARED_MATH_ACOSHF16_H
+#define LLVM_LIBC_SHARED_MATH_ACOSHF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+#include "shared/libc_common.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "src/__support/math/acoshf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::acoshf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_MATH_ACOSHF16_H
diff --git a/libc/shared/math/acospif16.h b/libc/shared/math/acospif16.h
new file mode 100644
index 0000000..38225f2
--- /dev/null
+++ b/libc/shared/math/acospif16.h
@@ -0,0 +1,29 @@
+//===-- Shared acospif16 function -------------------------------*- 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_SHARED_MATH_ACOSPIF16_H
+#define LLVM_LIBC_SHARED_MATH_ACOSPIF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "shared/libc_common.h"
+#include "src/__support/math/acospif16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::acospif16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_MATH_ACOSPIF16_H
diff --git a/libc/shared/math/asin.h b/libc/shared/math/asin.h
new file mode 100644
index 0000000..0b2c8ea6
--- /dev/null
+++ b/libc/shared/math/asin.h
@@ -0,0 +1,23 @@
+//===-- Shared asin function ------------------------------------*- 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_SHARED_MATH_ASIN_H
+#define LLVM_LIBC_SHARED_MATH_ASIN_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/asin.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::asin;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_ASIN_H
diff --git a/libc/shared/math/asinf.h b/libc/shared/math/asinf.h
new file mode 100644
index 0000000..ac051bd
--- /dev/null
+++ b/libc/shared/math/asinf.h
@@ -0,0 +1,23 @@
+//===-- Shared asinf function -----------------------------------*- 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_SHARED_MATH_ASINF_H
+#define LLVM_LIBC_SHARED_MATH_ASINF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/asinf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::asinf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_ASINF_H
diff --git a/libc/shared/math/asinf16.h b/libc/shared/math/asinf16.h
new file mode 100644
index 0000000..d545e26
--- /dev/null
+++ b/libc/shared/math/asinf16.h
@@ -0,0 +1,28 @@
+//===-- Shared asinf16 function ---------------------------------*- 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_SHARED_MATH_ASINF16_H
+#define LLVM_LIBC_SHARED_MATH_ASINF16_H
+
+#include "shared/libc_common.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "src/__support/math/asinf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::asinf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_MATH_ASINF_H
diff --git a/libc/shared/math/asinhf.h b/libc/shared/math/asinhf.h
new file mode 100644
index 0000000..c4a5509
--- /dev/null
+++ b/libc/shared/math/asinhf.h
@@ -0,0 +1,23 @@
+//===-- Shared asinhf function ----------------------------------*- 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_SHARED_MATH_ASINHF_H
+#define LLVM_LIBC_SHARED_MATH_ASINHF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/asinhf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::asinhf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_ASINHF_H
diff --git a/libc/shared/math/erff.h b/libc/shared/math/erff.h
new file mode 100644
index 0000000..d0cca15
--- /dev/null
+++ b/libc/shared/math/erff.h
@@ -0,0 +1,23 @@
+//===-- Shared erff function ------------------------------------*- 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_SHARED_MATH_ERFF_H
+#define LLVM_LIBC_SHARED_MATH_ERFF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/erff.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::erff;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_ERFF_H
diff --git a/libc/shared/math/exp10f16.h b/libc/shared/math/exp10f16.h
index 8acdbdb..d6ba067 100644
--- a/libc/shared/math/exp10f16.h
+++ b/libc/shared/math/exp10f16.h
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SHARED_MATH_EXP10F_H
-#define LLVM_LIBC_SHARED_MATH_EXP10F_H
+#ifndef LLVM_LIBC_SHARED_MATH_EXP10F16_H
+#define LLVM_LIBC_SHARED_MATH_EXP10F16_H
#include "include/llvm-libc-macros/float16-macros.h"
+#include "shared/libc_common.h"
#ifdef LIBC_TYPES_HAS_FLOAT16
-#include "shared/libc_common.h"
#include "src/__support/math/exp10f16.h"
namespace LIBC_NAMESPACE_DECL {
@@ -26,4 +26,4 @@ using math::exp10f16;
#endif // LIBC_TYPES_HAS_FLOAT16
-#endif // LLVM_LIBC_SHARED_MATH_EXP10F_H
+#endif // LLVM_LIBC_SHARED_MATH_EXP10F16_H
diff --git a/libc/shared/sign.h b/libc/shared/sign.h
new file mode 100644
index 0000000..2029b52
--- /dev/null
+++ b/libc/shared/sign.h
@@ -0,0 +1,23 @@
+//===-- Shared sign type ----------------------------------------*- 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_SHARED_SIGN_H
+#define LLVM_LIBC_SHARED_SIGN_H
+
+#include "libc_common.h"
+#include "src/__support/sign.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using LIBC_NAMESPACE::Sign;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_SIGN_H
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 cc941f2..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
)
@@ -210,6 +215,17 @@ add_header_library(
)
add_header_library(
+ comparison_operations
+ HDRS
+ comparison_operations.h
+ DEPENDS
+ .fenv_impl
+ .fp_bits
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.macros.config
+)
+
+add_header_library(
hypot
HDRS
Hypot.h
@@ -236,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
@@ -263,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/comparison_operations.h b/libc/src/__support/FPUtil/comparison_operations.h
new file mode 100644
index 0000000..ff62ce0
--- /dev/null
+++ b/libc/src/__support/FPUtil/comparison_operations.h
@@ -0,0 +1,114 @@
+//===-- Comparison operations on floating point numbers ---------*- 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_FPUTIL_COMPARISONOPERATIONS_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_COMPARISONOPERATIONS_H
+
+#include "FEnvImpl.h"
+#include "FPBits.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+
+// All predicates are hereby implemented as per IEEE Std 754-2019
+// Implements compareQuietEqual predicate
+// Rules for comparison within the same floating point type
+// 1. +0 = −0
+// 2. (i) +inf = +inf
+// (ii) -inf = -inf
+// (iii) -inf != +inf
+// 3. Any comparison with NaN returns false
+template <typename T>
+LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool> equals(T x,
+ T y) {
+ using FPBits = FPBits<T>;
+ FPBits x_bits(x);
+ FPBits y_bits(y);
+
+ if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan())
+ fputil::raise_except_if_required(FE_INVALID);
+
+ // NaN == x returns false for every x
+ if (x_bits.is_nan() || y_bits.is_nan())
+ return false;
+
+ // +/- 0 == +/- 0
+ if (x_bits.is_zero() && y_bits.is_zero())
+ return true;
+
+ return x_bits.uintval() == y_bits.uintval();
+}
+
+// Implements compareSignalingLess predicate
+// Section 5.11 Rules:
+// 1. -inf < x (x != -inf)
+// 2. x < +inf (x != +inf)
+// 3. Any comparison with NaN return false
+template <typename T>
+LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool> less_than(T x,
+ T y) {
+ using FPBits = FPBits<T>;
+ FPBits x_bits(x);
+ FPBits y_bits(y);
+
+ // Any comparison with NaN returns false
+ if (x_bits.is_nan() || y_bits.is_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return false;
+ }
+
+ if (x_bits.is_zero() && y_bits.is_zero())
+ return false;
+
+ if (x_bits.is_neg() && y_bits.is_pos())
+ return true;
+
+ if (x_bits.is_pos() && y_bits.is_neg())
+ return false;
+
+ // since floating-point numbers are stored in the format: s | e | m
+ // we can directly compare the uintval's
+
+ // both negative
+ if (x_bits.is_neg())
+ return x_bits.uintval() > y_bits.uintval();
+
+ // both positive
+ return x_bits.uintval() < y_bits.uintval();
+}
+
+// Implements compareSignalingGreater predicate
+// x < y => y > x
+template <typename T>
+LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
+greater_than(T x, T y) {
+ return less_than(y, x);
+}
+
+// Implements compareSignalingLessEqual predicate
+// x <= y => (x < y) || (x == y)
+template <typename T>
+LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
+less_than_or_equals(T x, T y) {
+ return less_than(x, y) || equals(x, y);
+}
+
+// Implements compareSignalingGreaterEqual predicate
+// x >= y => (x > y) || (x == y) => (y < x) || (x == y)
+template <typename T>
+LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, bool>
+greater_than_or_equals(T x, T y) {
+ return less_than(y, x) || equals(x, y);
+}
+
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_COMPARISONOPERATIONS_H
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..2b78c4d 100644
--- a/libc/src/__support/GPU/allocator.cpp
+++ b/libc/src/__support/GPU/allocator.cpp
@@ -16,6 +16,7 @@
#include "allocator.h"
+#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/new.h"
@@ -31,15 +32,12 @@ constexpr static uint64_t SLAB_SIZE = /* 2 MiB */ 2ull * 1024 * 1024;
constexpr static uint64_t ARRAY_SIZE = MAX_SIZE / SLAB_SIZE;
constexpr static uint64_t SLAB_ALIGNMENT = SLAB_SIZE - 1;
constexpr static uint32_t BITS_IN_WORD = sizeof(uint32_t) * 8;
+constexpr static uint32_t BITS_IN_DWORD = sizeof(uint64_t) * 8;
constexpr static uint32_t MIN_SIZE = 16;
constexpr static uint32_t MIN_ALIGNMENT = MIN_SIZE - 1;
-// 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;
+// The number of times to attempt claiming an in-progress slab allocation.
+constexpr static uint32_t MAX_TRIES = 1024;
static_assert(!(ARRAY_SIZE & (ARRAY_SIZE - 1)), "Must be a power of two");
@@ -71,8 +69,8 @@ static void rpc_free(void *ptr) {
// Convert a potentially disjoint bitmask into an increasing integer per-lane
// for use with indexing between gpu lanes.
-static inline uint32_t lane_count(uint64_t lane_mask) {
- return cpp::popcount(lane_mask & ((uint64_t(1) << gpu::get_lane_id()) - 1));
+static inline uint32_t lane_count(uint64_t lane_mask, uint32_t id) {
+ return cpp::popcount(lane_mask & ((uint64_t(1) << id) - 1));
}
// Obtain an initial value to seed a random number generator. We use the rounded
@@ -92,20 +90,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 +111,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) {
@@ -134,7 +132,8 @@ static inline constexpr T round_up(const T x) {
void uniform_memset(uint32_t *s, uint32_t c, uint32_t n, uint64_t uniform) {
uint64_t mask = gpu::get_lane_mask();
uint32_t workers = cpp::popcount(uniform);
- for (uint32_t i = impl::lane_count(mask & uniform); i < n; i += workers)
+ for (uint32_t i = impl::lane_count(mask & uniform, gpu::get_lane_id()); i < n;
+ i += workers)
s[i] = c;
}
@@ -143,6 +142,29 @@ 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. Small
+// allocations are much more likely than large ones, so we give them the most
+// space. We use a cubic easing function normalized on the possible chunks.
+static inline constexpr uint32_t get_start_index(uint32_t chunk_size) {
+ constexpr uint32_t max_chunk = impl::get_chunk_id(SLAB_SIZE / 2);
+ uint64_t norm =
+ (1 << 16) - (impl::get_chunk_id(chunk_size) << 16) / max_chunk;
+ uint64_t bias = (norm * norm * norm) >> 32;
+ uint64_t inv = (1 << 16) - bias;
+ return static_cast<uint32_t>(((ARRAY_SIZE - 1) * inv) >> 16);
+}
+
+// Returns the id of the lane below this one that acts as its leader.
+static inline uint32_t get_leader_id(uint64_t ballot, uint32_t id) {
+ uint64_t mask = id < BITS_IN_DWORD ? ~0ull << (id + 1) : 0;
+ return BITS_IN_DWORD - cpp::countl_zero(ballot & ~mask) - 1;
+}
+
+// We use a sentinal value to indicate a failed or in-progress allocation.
+template <typename T> bool is_sentinel(const T &x) {
+ return x == cpp::numeric_limits<T>::max();
+}
+
} // namespace impl
/// A slab allocator used to hand out identically sized slabs of memory.
@@ -251,33 +273,48 @@ 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)
+ : __builtin_align_down(impl::xorshift32(state), BITS_IN_WORD));
- uint32_t id = impl::lane_count(uniform & mask);
+ // Each lane tries to claim one bit in a single contiguous mask.
+ uint32_t id = impl::lane_count(uniform & mask, gpu::get_lane_id());
uint32_t index = (start + id) % usable_bits(chunk_size);
uint32_t slot = index / BITS_IN_WORD;
uint32_t bit = index % BITS_IN_WORD;
// 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 leader = impl::get_leader_id(
+ uniform & gpu::ballot(mask, !id || index % BITS_IN_WORD == 0),
+ gpu::get_lane_id());
+ uint32_t length = cpp::popcount(uniform & mask) -
+ impl::lane_count(uniform & mask, leader);
+ uint32_t bitmask =
+ static_cast<uint32_t>(
+ (uint64_t(1) << cpp::min(length, BITS_IN_WORD)) - 1)
+ << bit;
uint32_t before = 0;
- if (gpu::get_lane_id() == static_cast<uint32_t>(cpp::countr_zero(match)))
+ if (gpu::get_lane_id() == leader)
before = cpp::AtomicRef(get_bitfield()[slot])
.fetch_or(bitmask, cpp::MemoryOrder::RELAXED);
- before = gpu::shuffle(mask, cpp::countr_zero(match), before);
+ before = gpu::shuffle(mask, leader, before);
if (~before & (1 << bit))
result = ptr_from_index(index, chunk_size);
else
sleep_briefly();
+
+ after = before | bitmask;
+ old_index = index;
}
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
@@ -308,20 +345,20 @@ struct GuardPtr {
private:
struct RefCounter {
// Indicates that the object is in its deallocation phase and thus invalid.
- static constexpr uint64_t INVALID = uint64_t(1) << 63;
+ static constexpr uint32_t INVALID = uint32_t(1) << 31;
// If a read preempts an unlock call we indicate this so the following
// unlock call can swap out the helped bit and maintain exclusive ownership.
- static constexpr uint64_t HELPED = uint64_t(1) << 62;
+ static constexpr uint32_t HELPED = uint32_t(1) << 30;
// Resets the reference counter, cannot be reset to zero safely.
- void reset(uint32_t n, uint64_t &count) {
+ void reset(uint32_t n, uint32_t &count) {
counter.store(n, cpp::MemoryOrder::RELAXED);
count = n;
}
// Acquire a slot in the reference counter if it is not invalid.
- bool acquire(uint32_t n, uint64_t &count) {
+ bool acquire(uint32_t n, uint32_t &count) {
count = counter.fetch_add(n, cpp::MemoryOrder::RELAXED) + n;
return (count & INVALID) == 0;
}
@@ -334,7 +371,7 @@ private:
// another thread resurrected the counter and we quit, or a parallel read
// helped us invalidating it. For the latter, claim that flag and return.
if (counter.fetch_sub(n, cpp::MemoryOrder::RELAXED) == n) {
- uint64_t expected = 0;
+ uint32_t expected = 0;
if (counter.compare_exchange_strong(expected, INVALID,
cpp::MemoryOrder::RELAXED,
cpp::MemoryOrder::RELAXED))
@@ -357,28 +394,29 @@ private:
return (val & INVALID) ? 0 : val;
}
- cpp::Atomic<uint64_t> counter{0};
+ cpp::Atomic<uint32_t> counter{0};
};
- cpp::Atomic<Slab *> ptr{nullptr};
- RefCounter ref{};
+ cpp::Atomic<Slab *> ptr;
+ RefCounter ref;
// Should be called be a single lane for each different pointer.
template <typename... Args>
- Slab *try_lock_impl(uint32_t n, uint64_t &count, Args &&...args) {
+ Slab *try_lock_impl(uint32_t n, uint32_t &count, Args &&...args) {
Slab *expected = ptr.load(cpp::MemoryOrder::RELAXED);
if (!expected &&
ptr.compare_exchange_strong(
- expected, reinterpret_cast<Slab *>(SENTINEL),
+ expected,
+ reinterpret_cast<Slab *>(cpp::numeric_limits<uintptr_t>::max()),
cpp::MemoryOrder::RELAXED, cpp::MemoryOrder::RELAXED)) {
- count = cpp::numeric_limits<uint64_t>::max();
+ count = cpp::numeric_limits<uint32_t>::max();
void *raw = impl::rpc_allocate(sizeof(Slab));
if (!raw)
return nullptr;
return new (raw) Slab(cpp::forward<Args>(args)...);
}
- if (!expected || expected == reinterpret_cast<Slab *>(SENTINEL))
+ if (!expected || impl::is_sentinel(reinterpret_cast<uintptr_t>(expected)))
return nullptr;
if (!ref.acquire(n, count))
@@ -390,7 +428,7 @@ private:
// Finalize the associated memory and signal that it is ready to use by
// resetting the counter.
- void finalize(Slab *mem, uint32_t n, uint64_t &count) {
+ void finalize(Slab *mem, uint32_t n, uint32_t &count) {
cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE);
ptr.store(mem, cpp::MemoryOrder::RELAXED);
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQUIRE);
@@ -403,7 +441,7 @@ public:
// The uniform mask represents which lanes share the same pointer. For each
// uniform value we elect a leader to handle it on behalf of the other lanes.
template <typename... Args>
- Slab *try_lock(uint64_t lane_mask, uint64_t uniform, uint64_t &count,
+ Slab *try_lock(uint64_t lane_mask, uint64_t uniform, uint32_t &count,
Args &&...args) {
count = 0;
Slab *result = nullptr;
@@ -418,14 +456,15 @@ public:
// We defer storing the newly allocated slab until now so that we can use
// multiple lanes to initialize it and release it for use.
- if (count == cpp::numeric_limits<uint64_t>::max()) {
+ if (impl::is_sentinel(count)) {
result->initialize(uniform);
if (gpu::get_lane_id() == uint32_t(cpp::countr_zero(uniform)))
finalize(result, cpp::popcount(uniform), count);
}
- if (count != cpp::numeric_limits<uint64_t>::max())
- count = count - cpp::popcount(uniform) + impl::lane_count(uniform) + 1;
+ if (!impl::is_sentinel(count))
+ count = count - cpp::popcount(uniform) +
+ impl::lane_count(uniform, gpu::get_lane_id()) + 1;
return result;
}
@@ -451,66 +490,71 @@ 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::get_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;
+static Slab *find_slab(uint32_t chunk_size, uint64_t &uniform) {
+ // 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);
+
+ for (uint32_t offset = 0; offset <= ARRAY_SIZE; ++offset) {
+ uint32_t index =
+ !offset ? start
+ : (impl::get_start_index(chunk_size) + offset - 1) % ARRAY_SIZE;
+
+ if (!offset ||
+ slots[index].use_count() < Slab::available_chunks(chunk_size)) {
+ uint64_t lane_mask = gpu::get_lane_mask();
+ uint32_t reserved = 0;
+
+ 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;
+ !slab && !impl::is_sentinel(reserved) && retries < MAX_TRIES;
+ 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();
}
- }
- // Try to claim a slot for the found slot.
- if (!result) {
- uint64_t reserved = 0;
- Slab *slab = slots[index].try_lock(lane_mask & mask, uniform & mask,
- reserved, chunk_size, index);
// 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);
+ uniform = uniform & gpu::get_lane_mask();
+ 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 if (!slab && impl::is_sentinel(reserved)) {
+ uniform = uniform & gpu::get_lane_mask();
+ return nullptr;
} else {
sleep_briefly();
}
}
}
- return result;
+ return nullptr;
}
// Release the lock associated with a given slab.
@@ -533,12 +577,12 @@ void *allocate(uint64_t size) {
// Try to find a slab for the rounded up chunk size and allocate from it.
uint32_t chunk_size = impl::get_chunk_size(static_cast<uint32_t>(size));
- Slab *slab = find_slab(chunk_size);
- if (!slab || slab == reinterpret_cast<Slab *>(SENTINEL))
+ uint64_t uniform = gpu::match_any(gpu::get_lane_mask(), chunk_size);
+ Slab *slab = find_slab(chunk_size, uniform);
+ if (!slab || impl::is_sentinel(reinterpret_cast<uintptr_t>(slab)))
return nullptr;
uint64_t lane_mask = gpu::get_lane_mask();
- uint64_t uniform = gpu::match_any(lane_mask, slab->get_global_index());
void *ptr = slab->allocate(lane_mask, uniform);
return ptr;
}
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/cpu_features.h b/libc/src/__support/macros/properties/cpu_features.h
index cdb2df9..fde30ea 100644
--- a/libc/src/__support/macros/properties/cpu_features.h
+++ b/libc/src/__support/macros/properties/cpu_features.h
@@ -81,7 +81,7 @@
#endif
#if defined(__ARM_FEATURE_FMA) || (defined(__AVX2__) && defined(__FMA__)) || \
- defined(__NVPTX__) || defined(__AMDGPU__) || defined(__LIBC_RISCV_USE_FMA)
+ defined(__NVPTX__) || defined(__AMDGPU__) || defined(__riscv_flen)
#define LIBC_TARGET_CPU_HAS_FMA
// Provide a more fine-grained control of FMA instruction for ARM targets.
#if defined(LIBC_TARGET_CPU_HAS_FPU_HALF)
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 4a29c29..13f46a1 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
@@ -18,6 +17,99 @@ add_header_library(
)
add_header_library(
+ acosf
+ HDRS
+ acosf.h
+ DEPENDS
+ .inv_trigf_utils
+ 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
+)
+
+add_header_library(
+ acosf16
+ HDRS
+ acosf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.except_value_utils
+ 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(
+ acosh_float_constants
+ HDRS
+ acosh_float_constants.h
+ DEPENDS
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ acoshf_utils
+ HDRS
+ acoshf_utils.h
+ DEPENDS
+ .acosh_float_constants
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.polyeval
+)
+
+add_header_library(
+ acoshf
+ HDRS
+ acoshf.h
+ DEPENDS
+ .acoshf_utils
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.sqrt
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ acoshf16
+ HDRS
+ acoshf16.h
+ DEPENDS
+ .acoshf_utils
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.except_value_utils
+ 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
+)
+
+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
@@ -32,6 +124,79 @@ 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(
+ asinhf
+ HDRS
+ asinhf.h
+ DEPENDS
+ .acoshf_utils
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.sqrt
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+)
+
+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(
+ asinf16
+ HDRS
+ asinf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.sqrt
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ erff
+ HDRS
+ erff.h
+ DEPENDS
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.except_value_utils
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
exp_float_constants
HDRS
exp_float_constants.h
@@ -99,6 +264,16 @@ add_header_library(
)
add_header_library(
+ inv_trigf_utils
+ HDRS
+ inv_trigf_utils.h
+ DEPENDS
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.common
+)
+
+add_header_library(
frexpf16
HDRS
frexpf16.h
@@ -237,6 +412,7 @@ add_header_library(
HDRS
exp10_float16_constants.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.array
)
@@ -257,11 +433,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 a7287f1..0e1e413 100644
--- a/libc/src/__support/math/acos.h
+++ b/libc/src/__support/math/acos.h
@@ -24,10 +24,9 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-using DoubleDouble = fputil::DoubleDouble;
-using Float128 = fputil::DyadicFloat<128>;
-
-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>;
FPBits xbits(x);
diff --git a/libc/src/__support/math/acosf.h b/libc/src/__support/math/acosf.h
new file mode 100644
index 0000000..7a0c0e5
--- /dev/null
+++ b/libc/src/__support/math/acosf.h
@@ -0,0 +1,147 @@
+//===-- Implementation header for acosf -------------------------*- 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_ACOSF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSF_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
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+namespace acosf_internal {
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+static constexpr size_t N_EXCEPTS = 4;
+
+// Exceptional values when |x| <= 0.5
+static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{
+ // (inputs, RZ output, RU offset, RD offset, RN offset)
+ // x = 0x1.110b46p-26, acosf(x) = 0x1.921fb4p0 (RZ)
+ {0x328885a3, 0x3fc90fda, 1, 0, 1},
+ // x = -0x1.110b46p-26, acosf(x) = 0x1.921fb4p0 (RZ)
+ {0xb28885a3, 0x3fc90fda, 1, 0, 1},
+ // x = 0x1.04c444p-12, acosf(x) = 0x1.920f68p0 (RZ)
+ {0x39826222, 0x3fc907b4, 1, 0, 1},
+ // x = -0x1.04c444p-12, acosf(x) = 0x1.923p0 (RZ)
+ {0xb9826222, 0x3fc91800, 1, 0, 1},
+}};
+
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+} // namespace acosf_internal
+
+LIBC_INLINE static constexpr float acosf(float x) {
+ using namespace acosf_internal;
+ 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;
+ uint32_t x_sign = x_uint >> 31;
+
+ // |x| <= 0.5
+ if (LIBC_UNLIKELY(x_abs <= 0x3f00'0000U)) {
+ // |x| < 0x1p-10
+ if (LIBC_UNLIKELY(x_abs < 0x3a80'0000U)) {
+ // When |x| < 2^-10, we use the following approximation:
+ // acos(x) = pi/2 - asin(x)
+ // ~ pi/2 - x - x^3 / 6
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Check for exceptional values
+ if (auto r = ACOSF_EXCEPTS.lookup(x_uint); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ double xd = static_cast<double>(x);
+ return static_cast<float>(fputil::multiply_add(
+ -0x1.5555555555555p-3 * xd, xd * xd, M_MATH_PI_2 - xd));
+ }
+
+ // For |x| <= 0.5, we approximate acosf(x) by:
+ // acos(x) = pi/2 - asin(x) = pi/2 - 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]);
+ 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, M_MATH_PI_2 - xd));
+ }
+
+ // |x| >= 1, return 0, 2pi, or NaNs.
+ if (LIBC_UNLIKELY(x_abs >= 0x3f80'0000U)) {
+ if (x_abs == 0x3f80'0000U)
+ return x_sign ? /* x == -1.0f */ fputil::round_result_slightly_down(
+ 0x1.921fb6p+1f)
+ : /* x == 1.0f */ 0.0f;
+
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ // |x| <= +/-inf
+ if (x_abs <= 0x7f80'0000U) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ }
+
+ return x + FPBits::quiet_nan().get_val();
+ }
+
+ // When 0.5 < |x| < 1, we perform range reduction as follow:
+ //
+ // Assume further that 0.5 < x <= 1, and let:
+ // y = acos(x)
+ // We use the double angle formula:
+ // x = cos(y) = 1 - 2 sin^2(y/2)
+ // So:
+ // sin(y/2) = sqrt( (1 - x)/2 )
+ // And hence:
+ // y = 2 * asin( sqrt( (1 - x)/2 ) )
+ // Let u = (1 - x)/2, then
+ // acos(x) = 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:
+ // acos(x) ~ 2 * sqrt(u) * P(u).
+ //
+ // When -1 < x <= -0.5, we use the identity:
+ // acos(x) = pi - acos(-x)
+ // which is reduced to the postive case.
+
+ xbits.set_sign(Sign::POS);
+ double xd = static_cast<double>(xbits.get_val());
+ double u = fputil::multiply_add(-0.5, xd, 0.5);
+ double cv = 2 * fputil::sqrt<double>(u);
+
+ double r3 = asin_eval(u);
+ double r = fputil::multiply_add(cv * u, r3, cv);
+ return static_cast<float>(x_sign ? M_MATH_PI - r : r);
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ACOS_H
diff --git a/libc/src/__support/math/acosf16.h b/libc/src/__support/math/acosf16.h
new file mode 100644
index 0000000..3f0e002
--- /dev/null
+++ b/libc/src/__support/math/acosf16.h
@@ -0,0 +1,164 @@
+//===-- Implementation header for acosf16 -----------------------*- 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_ACOSF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSF16_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/except_value_utils.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 acosf16(float16 x) {
+
+ // Generated by Sollya using the following command:
+ // > round(pi/2, SG, RN);
+ // > round(pi, SG, RN);
+ constexpr float PI_OVER_2 = 0x1.921fb6p0f;
+ constexpr float PI = 0x1.921fb6p1f;
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ constexpr size_t N_EXCEPTS = 2;
+
+ constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSF16_EXCEPTS{{
+ // (input, RZ output, RU offset, RD offset, RN offset)
+ {0xacaf, 0x3e93, 1, 0, 0},
+ {0xb874, 0x4052, 1, 0, 1},
+ }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ 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)) {
+ // acosf16(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();
+ }
+
+ float xf = x;
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Handle exceptional values
+ if (auto r = ACOSF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // |x| == 0x1p0, x is 1 or -1
+ // if x is (-)1, return pi, else
+ // if x is (+)1, return 0
+ if (LIBC_UNLIKELY(x_abs == 0x3c00))
+ return fputil::cast<float16>(x_sign ? PI : 0.0f);
+
+ float xsq = xf * xf;
+
+ // |x| <= 0x1p-1, |x| <= 0.5
+ if (x_abs <= 0x3800) {
+ // if x is 0, return pi/2
+ if (LIBC_UNLIKELY(x_abs == 0))
+ return fputil::cast<float16>(PI_OVER_2);
+
+ // Note that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x)
+ // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
+ // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
+ float interm =
+ fputil::polyeval(xsq, 0x1.000002p0f, 0x1.554c2ap-3f, 0x1.3541ccp-4f,
+ 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
+ return fputil::cast<float16>(fputil::multiply_add(-xf, interm, PI_OVER_2));
+ }
+
+ // 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))
+ //
+ // 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)
+ // 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);
+
+ // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
+ // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
+ float asin_sqrt_u =
+ sqrt_u * fputil::polyeval(u, 0x1.000002p0f, 0x1.554c2ap-3f,
+ 0x1.3541ccp-4f, 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
+
+ return fputil::cast<float16>(
+ x_sign ? fputil::multiply_add(-2.0f, asin_sqrt_u, PI) : 2 * asin_sqrt_u);
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ACOS_H
diff --git a/libc/src/__support/math/acosh_float_constants.h b/libc/src/__support/math/acosh_float_constants.h
new file mode 100644
index 0000000..2eb245d
--- /dev/null
+++ b/libc/src/__support/math/acosh_float_constants.h
@@ -0,0 +1,114 @@
+//===-- Common constants for acoshf function --------------------*- 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_ACOSH_FLOAT_CONSTANTS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSH_FLOAT_CONSTANTS_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace acoshf_internal {
+
+// Lookup table for (1/f) where f = 1 + n*2^(-7), n = 0..127.
+static constexpr double ONE_OVER_F[128] = {
+ 0x1.0000000000000p+0, 0x1.fc07f01fc07f0p-1, 0x1.f81f81f81f820p-1,
+ 0x1.f44659e4a4271p-1, 0x1.f07c1f07c1f08p-1, 0x1.ecc07b301ecc0p-1,
+ 0x1.e9131abf0b767p-1, 0x1.e573ac901e574p-1, 0x1.e1e1e1e1e1e1ep-1,
+ 0x1.de5d6e3f8868ap-1, 0x1.dae6076b981dbp-1, 0x1.d77b654b82c34p-1,
+ 0x1.d41d41d41d41dp-1, 0x1.d0cb58f6ec074p-1, 0x1.cd85689039b0bp-1,
+ 0x1.ca4b3055ee191p-1, 0x1.c71c71c71c71cp-1, 0x1.c3f8f01c3f8f0p-1,
+ 0x1.c0e070381c0e0p-1, 0x1.bdd2b899406f7p-1, 0x1.bacf914c1bad0p-1,
+ 0x1.b7d6c3dda338bp-1, 0x1.b4e81b4e81b4fp-1, 0x1.b2036406c80d9p-1,
+ 0x1.af286bca1af28p-1, 0x1.ac5701ac5701bp-1, 0x1.a98ef606a63bep-1,
+ 0x1.a6d01a6d01a6dp-1, 0x1.a41a41a41a41ap-1, 0x1.a16d3f97a4b02p-1,
+ 0x1.9ec8e951033d9p-1, 0x1.9c2d14ee4a102p-1, 0x1.999999999999ap-1,
+ 0x1.970e4f80cb872p-1, 0x1.948b0fcd6e9e0p-1, 0x1.920fb49d0e229p-1,
+ 0x1.8f9c18f9c18fap-1, 0x1.8d3018d3018d3p-1, 0x1.8acb90f6bf3aap-1,
+ 0x1.886e5f0abb04ap-1, 0x1.8618618618618p-1, 0x1.83c977ab2beddp-1,
+ 0x1.8181818181818p-1, 0x1.7f405fd017f40p-1, 0x1.7d05f417d05f4p-1,
+ 0x1.7ad2208e0ecc3p-1, 0x1.78a4c8178a4c8p-1, 0x1.767dce434a9b1p-1,
+ 0x1.745d1745d1746p-1, 0x1.724287f46debcp-1, 0x1.702e05c0b8170p-1,
+ 0x1.6e1f76b4337c7p-1, 0x1.6c16c16c16c17p-1, 0x1.6a13cd1537290p-1,
+ 0x1.6816816816817p-1, 0x1.661ec6a5122f9p-1, 0x1.642c8590b2164p-1,
+ 0x1.623fa77016240p-1, 0x1.6058160581606p-1, 0x1.5e75bb8d015e7p-1,
+ 0x1.5c9882b931057p-1, 0x1.5ac056b015ac0p-1, 0x1.58ed2308158edp-1,
+ 0x1.571ed3c506b3ap-1, 0x1.5555555555555p-1, 0x1.5390948f40febp-1,
+ 0x1.51d07eae2f815p-1, 0x1.5015015015015p-1, 0x1.4e5e0a72f0539p-1,
+ 0x1.4cab88725af6ep-1, 0x1.4afd6a052bf5bp-1, 0x1.49539e3b2d067p-1,
+ 0x1.47ae147ae147bp-1, 0x1.460cbc7f5cf9ap-1, 0x1.446f86562d9fbp-1,
+ 0x1.42d6625d51f87p-1, 0x1.4141414141414p-1, 0x1.3fb013fb013fbp-1,
+ 0x1.3e22cbce4a902p-1, 0x1.3c995a47babe7p-1, 0x1.3b13b13b13b14p-1,
+ 0x1.3991c2c187f63p-1, 0x1.3813813813814p-1, 0x1.3698df3de0748p-1,
+ 0x1.3521cfb2b78c1p-1, 0x1.33ae45b57bcb2p-1, 0x1.323e34a2b10bfp-1,
+ 0x1.30d190130d190p-1, 0x1.2f684bda12f68p-1, 0x1.2e025c04b8097p-1,
+ 0x1.2c9fb4d812ca0p-1, 0x1.2b404ad012b40p-1, 0x1.29e4129e4129ep-1,
+ 0x1.288b01288b013p-1, 0x1.27350b8812735p-1, 0x1.25e22708092f1p-1,
+ 0x1.2492492492492p-1, 0x1.23456789abcdfp-1, 0x1.21fb78121fb78p-1,
+ 0x1.20b470c67c0d9p-1, 0x1.1f7047dc11f70p-1, 0x1.1e2ef3b3fb874p-1,
+ 0x1.1cf06ada2811dp-1, 0x1.1bb4a4046ed29p-1, 0x1.1a7b9611a7b96p-1,
+ 0x1.19453808ca29cp-1, 0x1.1811811811812p-1, 0x1.16e0689427379p-1,
+ 0x1.15b1e5f75270dp-1, 0x1.1485f0e0acd3bp-1, 0x1.135c81135c811p-1,
+ 0x1.12358e75d3033p-1, 0x1.1111111111111p-1, 0x1.0fef010fef011p-1,
+ 0x1.0ecf56be69c90p-1, 0x1.0db20a88f4696p-1, 0x1.0c9714fbcda3bp-1,
+ 0x1.0b7e6ec259dc8p-1, 0x1.0a6810a6810a7p-1, 0x1.0953f39010954p-1,
+ 0x1.0842108421084p-1, 0x1.073260a47f7c6p-1, 0x1.0624dd2f1a9fcp-1,
+ 0x1.05197f7d73404p-1, 0x1.0410410410410p-1, 0x1.03091b51f5e1ap-1,
+ 0x1.0204081020408p-1, 0x1.0101010101010p-1};
+
+// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127.
+static constexpr double LOG_F[128] = {
+ 0x0.0000000000000p+0, 0x1.fe02a6b106788p-8, 0x1.fc0a8b0fc03e3p-7,
+ 0x1.7b91b07d5b11ap-6, 0x1.f829b0e783300p-6, 0x1.39e87b9febd5fp-5,
+ 0x1.77458f632dcfcp-5, 0x1.b42dd711971bep-5, 0x1.f0a30c01162a6p-5,
+ 0x1.16536eea37ae0p-4, 0x1.341d7961bd1d0p-4, 0x1.51b073f06183fp-4,
+ 0x1.6f0d28ae56b4bp-4, 0x1.8c345d6319b20p-4, 0x1.a926d3a4ad563p-4,
+ 0x1.c5e548f5bc743p-4, 0x1.e27076e2af2e5p-4, 0x1.fec9131dbeabap-4,
+ 0x1.0d77e7cd08e59p-3, 0x1.1b72ad52f67a0p-3, 0x1.29552f81ff523p-3,
+ 0x1.371fc201e8f74p-3, 0x1.44d2b6ccb7d1ep-3, 0x1.526e5e3a1b437p-3,
+ 0x1.5ff3070a793d3p-3, 0x1.6d60fe719d21cp-3, 0x1.7ab890210d909p-3,
+ 0x1.87fa06520c910p-3, 0x1.9525a9cf456b4p-3, 0x1.a23bc1fe2b563p-3,
+ 0x1.af3c94e80bff2p-3, 0x1.bc286742d8cd6p-3, 0x1.c8ff7c79a9a21p-3,
+ 0x1.d5c216b4fbb91p-3, 0x1.e27076e2af2e5p-3, 0x1.ef0adcbdc5936p-3,
+ 0x1.fb9186d5e3e2ap-3, 0x1.0402594b4d040p-2, 0x1.0a324e27390e3p-2,
+ 0x1.1058bf9ae4ad5p-2, 0x1.1675cababa60ep-2, 0x1.1c898c16999fap-2,
+ 0x1.22941fbcf7965p-2, 0x1.2895a13de86a3p-2, 0x1.2e8e2bae11d30p-2,
+ 0x1.347dd9a987d54p-2, 0x1.3a64c556945e9p-2, 0x1.404308686a7e3p-2,
+ 0x1.4618bc21c5ec2p-2, 0x1.4be5f957778a0p-2, 0x1.51aad872df82dp-2,
+ 0x1.5767717455a6cp-2, 0x1.5d1bdbf5809cap-2, 0x1.62c82f2b9c795p-2,
+ 0x1.686c81e9b14aep-2, 0x1.6e08eaa2ba1e3p-2, 0x1.739d7f6bbd006p-2,
+ 0x1.792a55fdd47a2p-2, 0x1.7eaf83b82afc3p-2, 0x1.842d1da1e8b17p-2,
+ 0x1.89a3386c1425ap-2, 0x1.8f11e873662c7p-2, 0x1.947941c2116fap-2,
+ 0x1.99d958117e08ap-2, 0x1.9f323ecbf984bp-2, 0x1.a484090e5bb0ap-2,
+ 0x1.a9cec9a9a0849p-2, 0x1.af1293247786bp-2, 0x1.b44f77bcc8f62p-2,
+ 0x1.b9858969310fbp-2, 0x1.beb4d9da71b7bp-2, 0x1.c3dd7a7cdad4dp-2,
+ 0x1.c8ff7c79a9a21p-2, 0x1.ce1af0b85f3ebp-2, 0x1.d32fe7e00ebd5p-2,
+ 0x1.d83e7258a2f3ep-2, 0x1.dd46a04c1c4a0p-2, 0x1.e24881a7c6c26p-2,
+ 0x1.e744261d68787p-2, 0x1.ec399d2468cc0p-2, 0x1.f128f5faf06ecp-2,
+ 0x1.f6123fa7028acp-2, 0x1.faf588f78f31ep-2, 0x1.ffd2e0857f498p-2,
+ 0x1.02552a5a5d0fep-1, 0x1.04bdf9da926d2p-1, 0x1.0723e5c1cdf40p-1,
+ 0x1.0986f4f573520p-1, 0x1.0be72e4252a82p-1, 0x1.0e44985d1cc8bp-1,
+ 0x1.109f39e2d4c96p-1, 0x1.12f719593efbcp-1, 0x1.154c3d2f4d5e9p-1,
+ 0x1.179eabbd899a0p-1, 0x1.19ee6b467c96ep-1, 0x1.1c3b81f713c24p-1,
+ 0x1.1e85f5e7040d0p-1, 0x1.20cdcd192ab6dp-1, 0x1.23130d7bebf42p-1,
+ 0x1.2555bce98f7cbp-1, 0x1.2795e1289b11ap-1, 0x1.29d37fec2b08ap-1,
+ 0x1.2c0e9ed448e8bp-1, 0x1.2e47436e40268p-1, 0x1.307d7334f10bep-1,
+ 0x1.32b1339121d71p-1, 0x1.34e289d9ce1d3p-1, 0x1.37117b54747b5p-1,
+ 0x1.393e0d3562a19p-1, 0x1.3b68449fffc22p-1, 0x1.3d9026a7156fap-1,
+ 0x1.3fb5b84d16f42p-1, 0x1.41d8fe84672aep-1, 0x1.43f9fe2f9ce67p-1,
+ 0x1.4618bc21c5ec2p-1, 0x1.48353d1ea88dfp-1, 0x1.4a4f85db03ebbp-1,
+ 0x1.4c679afccee39p-1, 0x1.4e7d811b75bb0p-1, 0x1.50913cc01686bp-1,
+ 0x1.52a2d265bc5aap-1, 0x1.54b2467999497p-1, 0x1.56bf9d5b3f399p-1,
+ 0x1.58cadb5cd7989p-1, 0x1.5ad404c359f2cp-1, 0x1.5cdb1dc6c1764p-1,
+ 0x1.5ee02a9241675p-1, 0x1.60e32f44788d8p-1};
+
+} // namespace acoshf_internal
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ACOSH_FLOAT_CONSTANTS_H
diff --git a/libc/src/__support/math/acoshf.h b/libc/src/__support/math/acoshf.h
new file mode 100644
index 0000000..4e00311
--- /dev/null
+++ b/libc/src/__support/math/acoshf.h
@@ -0,0 +1,86 @@
+//===-- Implementation header for acoshf ------------------------*- 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_ACOSHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF_H
+
+#include "acoshf_utils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.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
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr float acoshf(float x) {
+ using namespace acoshf_internal;
+ using FPBits_t = typename fputil::FPBits<float>;
+ FPBits_t xbits(x);
+
+ if (LIBC_UNLIKELY(x <= 1.0f)) {
+ if (x == 1.0f)
+ return 0.0f;
+ // x < 1.
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits_t::quiet_nan().get_val();
+ }
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ uint32_t x_u = xbits.uintval();
+ if (LIBC_UNLIKELY(x_u >= 0x4f8ffb03)) {
+ if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
+ return x;
+
+ // Helper functions to set results for exceptional cases.
+ auto round_result_slightly_down = [](float r) -> float {
+ volatile float tmp = r;
+ tmp = tmp - 0x1.0p-25f;
+ return tmp;
+ };
+ auto round_result_slightly_up = [](float r) -> float {
+ volatile float tmp = r;
+ tmp = tmp + 0x1.0p-25f;
+ return tmp;
+ };
+
+ switch (x_u) {
+ case 0x4f8ffb03: // x = 0x1.1ff606p32f
+ return round_result_slightly_up(0x1.6fdd34p4f);
+ case 0x5c569e88: // x = 0x1.ad3d1p57f
+ return round_result_slightly_up(0x1.45c146p5f);
+ case 0x5e68984e: // x = 0x1.d1309cp61f
+ return round_result_slightly_up(0x1.5c9442p5f);
+ case 0x655890d3: // x = 0x1.b121a6p75f
+ return round_result_slightly_down(0x1.a9a3f2p5f);
+ case 0x6eb1a8ec: // x = 0x1.6351d8p94f
+ return round_result_slightly_down(0x1.08b512p6f);
+ case 0x7997f30a: // x = 0x1.2fe614p116f
+ return round_result_slightly_up(0x1.451436p6f);
+ }
+ }
+#else
+ if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
+ return x;
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ double x_d = static_cast<double>(x);
+ // acosh(x) = log(x + sqrt(x^2 - 1))
+ return static_cast<float>(log_eval(
+ x_d + fputil::sqrt<double>(fputil::multiply_add(x_d, x_d, -1.0))));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF_H
diff --git a/libc/src/__support/math/acoshf16.h b/libc/src/__support/math/acoshf16.h
new file mode 100644
index 0000000..e5be2a8
--- /dev/null
+++ b/libc/src/__support/math/acoshf16.h
@@ -0,0 +1,123 @@
+//===-- Implementation header for acoshf16 ----------------------*- 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_ACOSHF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "acoshf_utils.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/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"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr float16 acoshf16(float16 x) {
+
+ using namespace acoshf_internal;
+ constexpr size_t N_EXCEPTS = 2;
+ constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
+ // (input, RZ output, RU offset, RD offset, RN offset)
+ // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
+ {0x41B7, 0x3ED8, 1, 0, 0},
+ // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
+ {0x3CE4, 0x393E, 1, 0, 1},
+ }};
+
+ using FPBits = fputil::FPBits<float16>;
+ FPBits xbits(x);
+ uint16_t x_u = xbits.uintval();
+
+ // Check for NaN input first.
+ if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ if (xbits.is_neg()) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ return x;
+ }
+
+ // Domain error for inputs less than 1.0.
+ if (LIBC_UNLIKELY(x <= 1.0f)) {
+ if (x == 1.0f)
+ return FPBits::zero().get_val();
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+
+ float xf = x;
+ // High-precision polynomial approximation for inputs close to 1.0
+ // ([1, 1.25)).
+ //
+ // Brief derivation:
+ // 1. Expand acosh(1 + delta) using Taylor series around delta=0:
+ // acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
+ // - 5*delta^3/896 + 35*delta^4/18432 + ...]
+ // 2. Truncate the series to fit accurately for delta in [0, 0.25].
+ // 3. Polynomial coefficients (from sollya) used here are:
+ // P(delta) ≈ 1 - 0x1.555556p-4 * delta + 0x1.333334p-6 * delta^2
+ // - 0x1.6db6dcp-8 * delta^3 + 0x1.f1c71cp-10 * delta^4
+ // 4. The Sollya commands used to generate these coefficients were:
+ // > display = hexadecimal;
+ // > round(1/12, SG, RN);
+ // > round(3/160, SG, RN);
+ // > round(5/896, SG, RN);
+ // > round(35/18432, SG, RN);
+ // With hexadecimal display mode enabled, the outputs were:
+ // 0x1.555556p-4
+ // 0x1.333334p-6
+ // 0x1.6db6dcp-8
+ // 0x1.f1c71cp-10
+ // 5. The maximum absolute error, estimated using:
+ // dirtyinfnorm(acosh(1 + x) - sqrt(2*x) * P(x), [0, 0.25])
+ // is:
+ // 0x1.d84281p-22
+ if (LIBC_UNLIKELY(x_u < 0x3D00U)) {
+ float delta = xf - 1.0f;
+ float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
+ float pe = fputil::polyeval(delta, 0x1p+0f, -0x1.555556p-4f, 0x1.333334p-6f,
+ -0x1.6db6dcp-8f, 0x1.f1c71cp-10f);
+ float approx = sqrt_2_delta * pe;
+ return fputil::cast<float16>(approx);
+ }
+
+ // acosh(x) = log(x + sqrt(x^2 - 1))
+ float sqrt_term = fputil::sqrt<float>(fputil::multiply_add(xf, xf, -1.0f));
+ float result = static_cast<float>(log_eval(xf + sqrt_term));
+
+ return fputil::cast<float16>(result);
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF16_H
diff --git a/libc/src/__support/math/acoshf_utils.h b/libc/src/__support/math/acoshf_utils.h
new file mode 100644
index 0000000..808c3dd
--- /dev/null
+++ b/libc/src/__support/math/acoshf_utils.h
@@ -0,0 +1,60 @@
+//===-- Collection of utils for acoshf --------------------------*- 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_ACOSHF_UTILS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF_UTILS_H
+
+#include "acosh_float_constants.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/multiply_add.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace acoshf_internal {
+
+// x should be positive, normal finite value
+LIBC_INLINE static double log_eval(double x) {
+ // For x = 2^ex * (1 + mx)
+ // log(x) = ex * log(2) + log(1 + mx)
+ using FPB = fputil::FPBits<double>;
+ FPB bs(x);
+
+ double ex = static_cast<double>(bs.get_exponent());
+
+ // p1 is the leading 7 bits of mx, i.e.
+ // p1 * 2^(-7) <= m_x < (p1 + 1) * 2^(-7).
+ int p1 = static_cast<int>(bs.get_mantissa() >> (FPB::FRACTION_LEN - 7));
+
+ // Set bs to (1 + (mx - p1*2^(-7))
+ bs.set_uintval(bs.uintval() & (FPB::FRACTION_MASK >> 7));
+ bs.set_biased_exponent(FPB::EXP_BIAS);
+ // dx = (mx - p1*2^(-7)) / (1 + p1*2^(-7)).
+ double dx = (bs.get_val() - 1.0) * ONE_OVER_F[p1];
+
+ // Minimax polynomial of log(1 + dx) generated by Sollya with:
+ // > P = fpminimax(log(1 + x)/x, 6, [|D...|], [0, 2^-7]);
+ const double COEFFS[6] = {-0x1.ffffffffffffcp-2, 0x1.5555555552ddep-2,
+ -0x1.ffffffefe562dp-3, 0x1.9999817d3a50fp-3,
+ -0x1.554317b3f67a5p-3, 0x1.1dc5c45e09c18p-3};
+ double dx2 = dx * dx;
+ double c1 = fputil::multiply_add(dx, COEFFS[1], COEFFS[0]);
+ double c2 = fputil::multiply_add(dx, COEFFS[3], COEFFS[2]);
+ double c3 = fputil::multiply_add(dx, COEFFS[5], COEFFS[4]);
+
+ double p = fputil::polyeval(dx2, dx, c1, c2, c3);
+ double result =
+ fputil::multiply_add(ex, /*log(2)*/ 0x1.62e42fefa39efp-1, LOG_F[p1] + p);
+ return result;
+}
+
+} // namespace acoshf_internal
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ACOSHF_UTILS_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/asin_utils.h b/libc/src/__support/math/asin_utils.h
index 3146444..e0c9096 100644
--- a/libc/src/__support/math/asin_utils.h
+++ b/libc/src/__support/math/asin_utils.h
@@ -19,7 +19,7 @@
namespace LIBC_NAMESPACE_DECL {
-namespace {
+namespace asin_internal {
using DoubleDouble = fputil::DoubleDouble;
using Float128 = fputil::DyadicFloat<128>;
@@ -567,7 +567,7 @@ LIBC_INLINE static constexpr Float128 asin_eval(const Float128 &u,
#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-} // anonymous namespace
+} // namespace asin_internal
} // namespace LIBC_NAMESPACE_DECL
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/asinf16.h b/libc/src/__support/math/asinf16.h
new file mode 100644
index 0000000..3d032a4
--- /dev/null
+++ b/libc/src/__support/math/asinf16.h
@@ -0,0 +1,146 @@
+//===-- Implementation header for asinf16 -----------------------*- 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_ASINF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINF16_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 asinf16(float16 x) {
+
+ // Generated by Sollya using the following command:
+ // > round(pi/2, D, RN);
+ constexpr float PI_2 = 0x1.921fb54442d18p0f;
+
+ using FPBits = fputil::FPBits<float16>;
+ FPBits xbits(x);
+
+ uint16_t x_u = xbits.uintval();
+ uint16_t x_abs = x_u & 0x7fff;
+ float xf = x;
+
+ // |x| > 0x1p0, |x| > 1, or x is NaN.
+ if (LIBC_UNLIKELY(x_abs > 0x3c00)) {
+ // asinf16(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();
+ }
+
+ float xsq = xf * xf;
+
+ // |x| <= 0x1p-1, |x| <= 0.5
+ if (x_abs <= 0x3800) {
+ // asinf16(+/-0) = +/-0
+ if (LIBC_UNLIKELY(x_abs == 0))
+ return x;
+
+ // Exhaustive tests show that,
+ // for |x| <= 0x1.878p-9, when:
+ // x > 0, and rounding upward, or
+ // x < 0, and rounding downward, then,
+ // asin(x) = x * 2^-11 + x
+ // else, in other rounding modes,
+ // asin(x) = x
+ if (LIBC_UNLIKELY(x_abs <= 0x1a1e)) {
+ int rounding = fputil::quick_get_round();
+
+ if ((xbits.is_pos() && rounding == FE_UPWARD) ||
+ (xbits.is_neg() && rounding == FE_DOWNWARD))
+ return fputil::cast<float16>(fputil::multiply_add(xf, 0x1.0p-11f, xf));
+ return x;
+ }
+
+ // Degree-6 minimax odd polynomial of asin(x) generated by Sollya with:
+ // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
+ float result =
+ fputil::polyeval(xsq, 0x1.000002p0f, 0x1.554c2ap-3f, 0x1.3541ccp-4f,
+ 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
+ return fputil::cast<float16>(xf * result);
+ }
+
+ // 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 - 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))
+ //
+ // WHY?
+ // 11: Recall [7], u = (1 - x)/2
+ // 12: 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 [10] as `sqrt(u)` is in range.
+
+ // 0x1p-1 < |x| <= 0x1p0, 0.5 < |x| <= 1.0
+ float xf_abs = (xf < 0 ? -xf : xf);
+ float sign = (xbits.uintval() >> 15 == 1 ? -1.0 : 1.0);
+ float u = fputil::multiply_add(-0.5f, xf_abs, 0.5f);
+ float u_sqrt = fputil::sqrt<float>(u);
+
+ // Degree-6 minimax odd polynomial of asin(x) generated by Sollya with:
+ // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
+ float asin_sqrt_u =
+ u_sqrt * fputil::polyeval(u, 0x1.000002p0f, 0x1.554c2ap-3f,
+ 0x1.3541ccp-4f, 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
+
+ return fputil::cast<float16>(sign *
+ fputil::multiply_add(-2.0f, asin_sqrt_u, PI_2));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ASINF16_H
diff --git a/libc/src/__support/math/asinhf.h b/libc/src/__support/math/asinhf.h
new file mode 100644
index 0000000..1c08a6e
--- /dev/null
+++ b/libc/src/__support/math/asinhf.h
@@ -0,0 +1,125 @@
+//===-- 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_ASINHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ASINHF_H
+
+#include "acoshf_utils.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.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
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr float asinhf(float x) {
+ using namespace acoshf_internal;
+ using FPBits_t = typename fputil::FPBits<float>;
+ FPBits_t xbits(x);
+ uint32_t x_u = xbits.uintval();
+ uint32_t x_abs = xbits.abs().uintval();
+
+ // |x| <= 2^-3
+ if (LIBC_UNLIKELY(x_abs <= 0x3e80'0000U)) {
+ // |x| <= 2^-26
+ if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
+ return static_cast<float>(LIBC_UNLIKELY(x_abs == 0)
+ ? x
+ : (x - 0x1.5555555555555p-3 * x * x * x));
+ }
+
+ double x_d = x;
+ double x_sq = x_d * x_d;
+ // Generated by Sollya with:
+ // > P = fpminimax(asinh(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16|], [|D...|],
+ // [0, 2^-2]);
+ double p = fputil::polyeval(
+ x_sq, 0.0, -0x1.555555555551ep-3, 0x1.3333333325495p-4,
+ -0x1.6db6db5a7622bp-5, 0x1.f1c70f82928c6p-6, -0x1.6e893934266b7p-6,
+ 0x1.1c0b41d3fbe78p-6, -0x1.c0f47810b3c4fp-7, 0x1.2c8602690143dp-7);
+ return static_cast<float>(fputil::multiply_add(x_d, p, x_d));
+ }
+
+ const double SIGN[2] = {1.0, -1.0};
+ double x_sign = SIGN[x_u >> 31];
+ double x_d = x;
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Helper functions to set results for exceptional cases.
+ auto round_result_slightly_down = [x_sign](float r) -> float {
+ return fputil::multiply_add(static_cast<float>(x_sign), r,
+ static_cast<float>(x_sign) * (-0x1.0p-24f));
+ };
+ auto round_result_slightly_up = [x_sign](float r) -> float {
+ return fputil::multiply_add(static_cast<float>(x_sign), r,
+ static_cast<float>(x_sign) * 0x1.0p-24f);
+ };
+
+ if (LIBC_UNLIKELY(x_abs >= 0x4bdd'65a5U)) {
+ if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits_t::quiet_nan().get_val();
+ }
+
+ return x;
+ }
+
+ // Exceptional cases when x > 2^24.
+ switch (x_abs) {
+ case 0x4bdd65a5: // |x| = 0x1.bacb4ap24f
+ return round_result_slightly_down(0x1.1e0696p4f);
+ case 0x4c803f2c: // |x| = 0x1.007e58p26f
+ return round_result_slightly_down(0x1.2b786cp4f);
+ case 0x4f8ffb03: // |x| = 0x1.1ff606p32f
+ return round_result_slightly_up(0x1.6fdd34p4f);
+ case 0x5c569e88: // |x| = 0x1.ad3d1p57f
+ return round_result_slightly_up(0x1.45c146p5f);
+ case 0x5e68984e: // |x| = 0x1.d1309cp61f
+ return round_result_slightly_up(0x1.5c9442p5f);
+ case 0x655890d3: // |x| = 0x1.b121a6p75f
+ return round_result_slightly_down(0x1.a9a3f2p5f);
+ case 0x65de7ca6: // |x| = 0x1.bcf94cp76f
+ return round_result_slightly_up(0x1.af66cp5f);
+ case 0x6eb1a8ec: // |x| = 0x1.6351d8p94f
+ return round_result_slightly_down(0x1.08b512p6f);
+ case 0x7997f30a: // |x| = 0x1.2fe614p116f
+ return round_result_slightly_up(0x1.451436p6f);
+ }
+ } else {
+ // Exceptional cases when x < 2^24.
+ if (LIBC_UNLIKELY(x_abs == 0x45abaf26)) {
+ // |x| = 0x1.575e4cp12f
+ return round_result_slightly_down(0x1.29becap3f);
+ }
+ if (LIBC_UNLIKELY(x_abs == 0x49d29048)) {
+ // |x| = 0x1.a5209p20f
+ return round_result_slightly_down(0x1.e1b92p3f);
+ }
+ }
+#else
+ if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
+ return x;
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // asinh(x) = log(x + sqrt(x^2 + 1))
+ return static_cast<float>(
+ x_sign * log_eval(fputil::multiply_add(
+ x_d, x_sign,
+ fputil::sqrt<double>(fputil::multiply_add(x_d, x_d, 1.0)))));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ASINHF_H
diff --git a/libc/src/__support/math/erff.h b/libc/src/__support/math/erff.h
new file mode 100644
index 0000000..b81be30
--- /dev/null
+++ b/libc/src/__support/math/erff.h
@@ -0,0 +1,193 @@
+//===-- Implementation header for erff --------------------------*- 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_ERFF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_ERFF_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/macros/config.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+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|],
+ // [|D...|],
+ // [k/8, (k + 1)/8]);
+ // for k = 0..31.
+ constexpr double COEFFS[32][8] = {
+ {0x1.20dd750429b6dp0, -0x1.812746b037753p-2, 0x1.ce2f219e8596ap-4,
+ -0x1.b82cdacb78fdap-6, 0x1.56479297dfda5p-8, -0x1.8b3ac5455ef02p-11,
+ -0x1.126fcac367e3bp-8, 0x1.2d0bdb3ba4984p-4},
+ {0x1.20dd750429b6dp0, -0x1.812746b0379a8p-2, 0x1.ce2f21a03cf2ap-4,
+ -0x1.b82ce30de083ep-6, 0x1.565bcad3eb60fp-8, -0x1.c02c66f659256p-11,
+ 0x1.f92f673385229p-14, -0x1.def402648ae9p-17},
+ {0x1.20dd750429b34p0, -0x1.812746b032dcep-2, 0x1.ce2f219d84aaep-4,
+ -0x1.b82ce22dcf139p-6, 0x1.565b9efcd4af1p-8, -0x1.c021f1af414bcp-11,
+ 0x1.f7c6d177eff82p-14, -0x1.c9e4410dcf865p-17},
+ {0x1.20dd750426eabp0, -0x1.812746ae592c7p-2, 0x1.ce2f211525f14p-4,
+ -0x1.b82ccc125e63fp-6, 0x1.56596f261cfd3p-8, -0x1.bfde1ff8eeecfp-11,
+ 0x1.f31a9d15dc5d8p-14, -0x1.a5a4362844b3cp-17},
+ {0x1.20dd75039c705p0, -0x1.812746777e74dp-2, 0x1.ce2f17af98a1bp-4,
+ -0x1.b82be4b817cbep-6, 0x1.564bec2e2962ep-8, -0x1.bee86f9da3558p-11,
+ 0x1.e9443689dc0ccp-14, -0x1.79c0f230805d8p-17},
+ {0x1.20dd74f811211p0, -0x1.81274371a3e8fp-2, 0x1.ce2ec038262e5p-4,
+ -0x1.b8265b82c5e1fp-6, 0x1.5615a2e239267p-8, -0x1.bc63ae023dcebp-11,
+ 0x1.d87c2102f7e06p-14, -0x1.49584bea41d62p-17},
+ {0x1.20dd746d063e3p0, -0x1.812729a8a950fp-2, 0x1.ce2cb0a2df232p-4,
+ -0x1.b80eca1f51278p-6, 0x1.5572e26c46815p-8, -0x1.b715e5638b65ep-11,
+ 0x1.bfbb195484968p-14, -0x1.177a565c15c52p-17},
+ {0x1.20dd701b44486p0, -0x1.812691145f237p-2, 0x1.ce23a06b8cfd9p-4,
+ -0x1.b7c1dc7245288p-6, 0x1.53e92f7f397ddp-8, -0x1.ad97cc4acf0b2p-11,
+ 0x1.9f028b2b09b71p-14, -0x1.cdc4da08da8c1p-18},
+ {0x1.20dd5715ac332p0, -0x1.8123e680bd0ebp-2, 0x1.ce0457aded691p-4,
+ -0x1.b6f52d52bed4p-6, 0x1.50c291b84414cp-8, -0x1.9ea246b1ad4a9p-11,
+ 0x1.77654674e0cap-14, -0x1.737c11a1bcebbp-18},
+ {0x1.20dce6593e114p0, -0x1.811a59c02eadcp-2, 0x1.cdab53c7cd7d5p-4,
+ -0x1.b526d2e321eedp-6, 0x1.4b1d32cd8b994p-8, -0x1.8963143ec0a1ep-11,
+ 0x1.4ad5700e4db91p-14, -0x1.231e100e43ef2p-18},
+ {0x1.20db48bfd5a62p0, -0x1.80fdd84f9e308p-2, 0x1.ccd340d462983p-4,
+ -0x1.b196a2928768p-6, 0x1.4210c2c13a0f7p-8, -0x1.6dbdfb4ff71aep-11,
+ 0x1.1bca2d17fbd71p-14, -0x1.bca36f90c7cf5p-19},
+ {0x1.20d64b2f8f508p0, -0x1.80b4d4f19fa8bp-2, 0x1.cb088197262e3p-4,
+ -0x1.ab51fd02e5b99p-6, 0x1.34e1e5e81a632p-8, -0x1.4c66377b502cep-11,
+ 0x1.d9ad25066213cp-15, -0x1.4b0df7dd0cfa1p-19},
+ {0x1.20c8fc1243576p0, -0x1.8010cb2009e27p-2, 0x1.c7a47e9299315p-4,
+ -0x1.a155be5683654p-6, 0x1.233502694997bp-8, -0x1.26c94b7d813p-11,
+ 0x1.8094f1de25fb9p-15, -0x1.e0e3d776c6eefp-20},
+ {0x1.20a9bd1611bc1p0, -0x1.7ec7fbce83f9p-2, 0x1.c1d757d7317b7p-4,
+ -0x1.92c160cd589fp-6, 0x1.0d307269cc5c2p-8, -0x1.fda5b0d2d1879p-12,
+ 0x1.2fdd7b3b14a7fp-15, -0x1.54eed4a26af5ap-20},
+ {0x1.20682834f943dp0, -0x1.7c73f747bf5a9p-2, 0x1.b8c2db4a9ffd1p-4,
+ -0x1.7f0e4ffe989ecp-6, 0x1.e7061eae4166ep-9, -0x1.ad36e873fff2dp-12,
+ 0x1.d39222396128ep-16, -0x1.d83dacec5ea6bp-21},
+ {0x1.1feb8d12676d7p0, -0x1.7898347284afep-2, 0x1.aba3466b34451p-4,
+ -0x1.663adc573e2f9p-6, 0x1.ae99fb17c3e08p-9, -0x1.602f950ad5535p-12,
+ 0x1.5e9717490609dp-16, -0x1.3fca107bbc8d5p-21},
+ {0x1.1f12fe3c536fap0, -0x1.72b1d1f22e6d3p-2, 0x1.99fc0eed4a896p-4,
+ -0x1.48db0a87bd8c6p-6, 0x1.73e368895aa61p-9, -0x1.19b35d5301fc8p-12,
+ 0x1.007987e4bb033p-16, -0x1.a7edcd4c2dc7p-22},
+ {0x1.1db7b0df84d5dp0, -0x1.6a4e4a41cde02p-2, 0x1.83bbded16455dp-4,
+ -0x1.2809b3b36977ep-6, 0x1.39c08bab44679p-9, -0x1.b7b45a70ed119p-13,
+ 0x1.6e99b36410e7bp-17, -0x1.13619bb7ebc0cp-22},
+ {0x1.1bb1c85c4a527p0, -0x1.5f23b99a249a3p-2, 0x1.694c91fa0d12cp-4,
+ -0x1.053e1ce11c72dp-6, 0x1.02bf72c50ea78p-9, -0x1.4f478fb56cb02p-13,
+ 0x1.005f80ecbe213p-17, -0x1.5f2446bde7f5bp-23},
+ {0x1.18dec3bd51f9dp0, -0x1.5123f58346186p-2, 0x1.4b8a1ca536ab4p-4,
+ -0x1.c4243015cc723p-7, 0x1.a1a8a01d351efp-10, -0x1.f466b34f1d86bp-14,
+ 0x1.5f835eea0bf6ap-18, -0x1.b83165b939234p-24},
+ {0x1.152804c3369f4p0, -0x1.4084cd4afd4bcp-2, 0x1.2ba2e836e47aap-4,
+ -0x1.800f2dfc6904bp-7, 0x1.4a6daf0669c59p-10, -0x1.6e326ab872317p-14,
+ 0x1.d9761a6a755a5p-19, -0x1.0fca33f9dd4b5p-24},
+ {0x1.1087ad68356aap0, -0x1.2dbb044707459p-2, 0x1.0aea8ceaa0384p-4,
+ -0x1.40b516d52b3d2p-7, 0x1.00c9e05f01d22p-10, -0x1.076afb0dc0ff7p-14,
+ 0x1.39fadec400657p-19, -0x1.4b5761352e7e3p-25},
+ {0x1.0b0a7a8ba4a22p0, -0x1.196990d22d4a1p-2, 0x1.d5551e6ac0c4dp-5,
+ -0x1.07cce1770bd1ap-7, 0x1.890347b8848bfp-11, -0x1.757ec96750b6ap-15,
+ 0x1.9b258a1e06bcep-20, -0x1.8fc6d22da7572p-26},
+ {0x1.04ce2be70fb47p0, -0x1.0449e4b0b9cacp-2, 0x1.97f7424f4b0e7p-5,
+ -0x1.ac825439c42f4p-8, 0x1.28f5f65426dfbp-11, -0x1.05b699a90f90fp-15,
+ 0x1.0a888eecf4593p-20, -0x1.deace2b32bb31p-27},
+ {0x1.fbf9fb0e11cc8p-1, -0x1.de2640856545ap-3, 0x1.5f5b1f47f851p-5,
+ -0x1.588bc71eb41b9p-8, 0x1.bc6a0a772f56dp-12, -0x1.6b9fad1f1657ap-16,
+ 0x1.573204ba66504p-21, -0x1.1d38065c94e44p-27},
+ {0x1.ed8f18c99e031p-1, -0x1.b4cb6acd903b4p-3, 0x1.2c7f3dddd6fc1p-5,
+ -0x1.13052067df4ep-8, 0x1.4a5027444082fp-12, -0x1.f672bab0e2554p-17,
+ 0x1.b83c756348cc9p-22, -0x1.534f1a1079499p-28},
+ {0x1.debd33044166dp-1, -0x1.8d7cd9053f7d8p-3, 0x1.ff9957fb3d6e7p-6,
+ -0x1.b50be55de0f36p-9, 0x1.e92c8ec53a628p-13, -0x1.5a4b88d508007p-17,
+ 0x1.1a27737559e26p-22, -0x1.942ae62cb2c14p-29},
+ {0x1.cfdbf0386f3bdp-1, -0x1.68e33d93b0dc4p-3, 0x1.b2683d58f53dep-6,
+ -0x1.5a9174e70d26fp-9, 0x1.69ddd326d49cdp-13, -0x1.dd8f397a8219cp-18,
+ 0x1.6a755016ad4ddp-23, -0x1.e366e0139187dp-30},
+ {0x1.c132adb8d7464p-1, -0x1.475a899f61b46p-3, 0x1.70a431397a77cp-6,
+ -0x1.12e3d35beeee2p-9, 0x1.0c16b05738333p-13, -0x1.4a47f873e144ep-18,
+ 0x1.d3d494c698c02p-24, -0x1.2302c59547fe5p-30},
+ {0x1.b2f5fd05555e7p-1, -0x1.28feefbe03ec7p-3, 0x1.3923acbb3a676p-6,
+ -0x1.b4ff793cd6358p-10, 0x1.8ea0eb8c913bcp-14, -0x1.cb31ec2baceb1p-19,
+ 0x1.30011e7e80c04p-24, -0x1.617710635cb1dp-31},
+ {0x1.a54853cd9593ep-1, -0x1.0dbdbaea4dc8ep-3, 0x1.0a93e2c20a0fdp-6,
+ -0x1.5c969ff401ea8p-10, 0x1.29e0cc64fe627p-14, -0x1.4160d8e9d3c2ap-19,
+ 0x1.8e7b67594624ap-25, -0x1.b1cf2c975b09bp-32},
+ {0x1.983ceece09ff8p-1, -0x1.eacc78f7a2dp-4, 0x1.c74418410655fp-7,
+ -0x1.1756a050e441ep-10, 0x1.bff3650f7f548p-15, -0x1.c56c0217d3adap-20,
+ 0x1.07b4918d0b489p-25, -0x1.0d4be8c1c50f8p-32},
+ };
+
+ using FPBits = typename fputil::FPBits<float>;
+ FPBits xbits(x);
+
+ uint32_t x_u = xbits.uintval();
+ uint32_t x_abs = x_u & 0x7fff'ffffU;
+
+ if (LIBC_UNLIKELY(x_abs >= 0x4080'0000U)) {
+ constexpr float ONE[2] = {1.0f, -1.0f};
+ constexpr float SMALL[2] = {-0x1.0p-25f, 0x1.0p-25f};
+
+ int sign = xbits.is_neg() ? 1 : 0;
+
+ if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ return (x_abs > 0x7f80'0000) ? x : ONE[sign];
+ }
+
+ return ONE[sign] + SMALL[sign];
+ }
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Exceptional mask = common 0 bits of 2 exceptional values.
+ constexpr uint32_t EXCEPT_MASK = 0x809a'6184U;
+
+ if (LIBC_UNLIKELY((x_abs & EXCEPT_MASK) == 0)) {
+ // Exceptional values
+ if (LIBC_UNLIKELY(x_abs == 0x3f65'9229U)) // |x| = 0x1.cb2452p-1f
+ return x < 0.0f ? fputil::round_result_slightly_down(-0x1.972ea8p-1f)
+ : fputil::round_result_slightly_up(0x1.972ea8p-1f);
+ if (LIBC_UNLIKELY(x_abs == 0x4004'1e6aU)) // |x| = 0x1.083cd4p+1f
+ return x < 0.0f ? fputil::round_result_slightly_down(-0x1.fe3462p-1f)
+ : fputil::round_result_slightly_up(0x1.fe3462p-1f);
+ if (x_abs == 0U)
+ return x;
+ }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // Polynomial approximation:
+ // erf(x) ~ x * (c0 + c1 * x^2 + c2 * x^4 + ... + c7 * x^14)
+ double xd = static_cast<double>(x);
+ double xsq = xd * xd;
+
+ constexpr uint32_t EIGHT = 3 << FPBits::FRACTION_LEN;
+ int idx = static_cast<int>(FPBits(x_abs + EIGHT).get_val());
+
+ double x4 = xsq * xsq;
+ double c0 = fputil::multiply_add(xsq, COEFFS[idx][1], COEFFS[idx][0]);
+ double c1 = fputil::multiply_add(xsq, COEFFS[idx][3], COEFFS[idx][2]);
+ double c2 = fputil::multiply_add(xsq, COEFFS[idx][5], COEFFS[idx][4]);
+ double c3 = fputil::multiply_add(xsq, COEFFS[idx][7], COEFFS[idx][6]);
+
+ double x8 = x4 * x4;
+ double p0 = fputil::multiply_add(x4, c1, c0);
+ double p1 = fputil::multiply_add(x4, c3, c2);
+
+ return static_cast<float>(xd * fputil::multiply_add(x8, p1, p0));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ERFF_H
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/math/generic/inv_trigf_utils.cpp b/libc/src/__support/math/inv_trigf_utils.h
index f23028b..4a8fbec 100644
--- a/libc/src/math/generic/inv_trigf_utils.cpp
+++ b/libc/src/__support/math/inv_trigf_utils.h
@@ -1,4 +1,4 @@
-//===-- Single-precision general exp/log functions ------------------------===//
+//===-- Single-precision general inverse trigonometric functions ----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,11 +6,22 @@
//
//===----------------------------------------------------------------------===//
-#include "inv_trigf_utils.h"
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_INV_TRIGF_UTILS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_INV_TRIGF_UTILS_H
+
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/common.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
+namespace inv_trigf_utils_internal {
+
+// PI and PI / 2
+static constexpr double M_MATH_PI = 0x1.921fb54442d18p+1;
+static constexpr double M_MATH_PI_2 = 0x1.921fb54442d18p+0;
+
// Polynomial approximation for 0 <= x <= 1:
// atan(x) ~ atan((i/16) + (x - (i/16)) * Q(x - i/16)
// = P(x - i/16)
@@ -29,7 +40,7 @@ namespace LIBC_NAMESPACE_DECL {
// Notice that degree-7 is good enough for atanf, but degree-8 helps reduce the
// error bounds for atan2f's fast pass 16 times, and it does not affect the
// performance of atanf much.
-double ATAN_COEFFS[17][9] = {
+static constexpr double ATAN_COEFFS[17][9] = {
{0.0, 1.0, 0x1.3f8d76d26d61bp-47, -0x1.5555555574cd8p-2,
0x1.0dde5d06878eap-29, 0x1.99997738acc77p-3, 0x1.2c43eac9797cap-16,
-0x1.25fb020007dbdp-3, 0x1.c1b6c31d7b0aep-7},
@@ -83,4 +94,91 @@ double ATAN_COEFFS[17][9] = {
0x1.555e31a1e15e9p-6, -0x1.245240d65e629p-7, -0x1.fa9ba66478903p-11},
};
+// Look-up table for atan(k/16) with k = 0..16.
+static constexpr double ATAN_K_OVER_16[17] = {
+ 0.0,
+ 0x1.ff55bb72cfdeap-5,
+ 0x1.fd5ba9aac2f6ep-4,
+ 0x1.7b97b4bce5b02p-3,
+ 0x1.f5b75f92c80ddp-3,
+ 0x1.362773707ebccp-2,
+ 0x1.6f61941e4def1p-2,
+ 0x1.a64eec3cc23fdp-2,
+ 0x1.dac670561bb4fp-2,
+ 0x1.0657e94db30dp-1,
+ 0x1.1e00babdefeb4p-1,
+ 0x1.345f01cce37bbp-1,
+ 0x1.4978fa3269ee1p-1,
+ 0x1.5d58987169b18p-1,
+ 0x1.700a7c5784634p-1,
+ 0x1.819d0b7158a4dp-1,
+ 0x1.921fb54442d18p-1,
+};
+
+// For |x| <= 1/32 and 0 <= i <= 16, return Q(x) such that:
+// Q(x) ~ (atan(x + i/16) - atan(i/16)) / x.
+LIBC_INLINE static double atan_eval(double x, unsigned i) {
+ double x2 = x * x;
+
+ double c0 = fputil::multiply_add(x, ATAN_COEFFS[i][2], ATAN_COEFFS[i][1]);
+ double c1 = fputil::multiply_add(x, ATAN_COEFFS[i][4], ATAN_COEFFS[i][3]);
+ double c2 = fputil::multiply_add(x, ATAN_COEFFS[i][6], ATAN_COEFFS[i][5]);
+ double c3 = fputil::multiply_add(x, ATAN_COEFFS[i][8], ATAN_COEFFS[i][7]);
+
+ double x4 = x2 * x2;
+ double d1 = fputil::multiply_add(x2, c1, c0);
+ double d2 = fputil::multiply_add(x2, c3, c2);
+ double p = fputil::multiply_add(x4, d2, d1);
+ return p;
+}
+
+// Evaluate atan without big lookup table.
+// atan(n/d) - atan(k/16) = atan((n/d - k/16) / (1 + (n/d) * (k/16)))
+// = atan((n - d * k/16)) / (d + n * k/16))
+// So we let q = (n - d * k/16) / (d + n * k/16),
+// and approximate with Taylor polynomial:
+// atan(q) ~ q - q^3/3 + q^5/5 - q^7/7 + q^9/9
+LIBC_INLINE static double atan_eval_no_table(double num, double den,
+ double k_over_16) {
+ double num_r = fputil::multiply_add(den, -k_over_16, num);
+ double den_r = fputil::multiply_add(num, k_over_16, den);
+ double q = num_r / den_r;
+
+ constexpr double ATAN_TAYLOR[] = {
+ -0x1.5555555555555p-2,
+ 0x1.999999999999ap-3,
+ -0x1.2492492492492p-3,
+ 0x1.c71c71c71c71cp-4,
+ };
+ double q2 = q * q;
+ double q3 = q2 * q;
+ double q4 = q2 * q2;
+ double c0 = fputil::multiply_add(q2, ATAN_TAYLOR[1], ATAN_TAYLOR[0]);
+ double c1 = fputil::multiply_add(q2, ATAN_TAYLOR[3], ATAN_TAYLOR[2]);
+ double d = fputil::multiply_add(q4, c1, c0);
+ return fputil::multiply_add(q3, d, q);
+}
+
+// > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|],
+// [|1, D...|], [0, 0.5]);
+static constexpr double ASIN_COEFFS[10] = {
+ 0x1.5555555540fa1p-3, 0x1.333333512edc2p-4, 0x1.6db6cc1541b31p-5,
+ 0x1.f1caff324770ep-6, 0x1.6e43899f5f4f4p-6, 0x1.1f847cf652577p-6,
+ 0x1.9b60f47f87146p-7, 0x1.259e2634c494fp-6, -0x1.df946fa875ddp-8,
+ 0x1.02311ecf99c28p-5};
+
+// Evaluate P(x^2) - 1, where P(x^2) ~ asin(x)/x
+LIBC_INLINE static double asin_eval(double xsq) {
+ double x4 = xsq * xsq;
+ double r1 = fputil::polyeval(x4, ASIN_COEFFS[0], ASIN_COEFFS[2],
+ ASIN_COEFFS[4], ASIN_COEFFS[6], ASIN_COEFFS[8]);
+ double r2 = fputil::polyeval(x4, ASIN_COEFFS[1], ASIN_COEFFS[3],
+ ASIN_COEFFS[5], ASIN_COEFFS[7], ASIN_COEFFS[9]);
+ return fputil::multiply_add(xsq, r2, r1);
+}
+
+} // namespace inv_trigf_utils_internal
+
} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_INV_TRIGF_UTILS_H
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/mbrtowc.cpp b/libc/src/__support/wchar/mbrtowc.cpp
index 90ba934..0f730d6 100644
--- a/libc/src/__support/wchar/mbrtowc.cpp
+++ b/libc/src/__support/wchar/mbrtowc.cpp
@@ -37,7 +37,8 @@ ErrorOr<size_t> mbrtowc(wchar_t *__restrict pwc, const char *__restrict s,
}
auto wc = char_conv.pop_utf32();
if (wc.has_value()) {
- *pwc = wc.value();
+ if (pwc != nullptr)
+ *pwc = wc.value();
// null terminator -> return 0
if (wc.value() == L'\0')
return 0;
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/docs/add_math_function.md b/libc/src/math/docs/add_math_function.md
index daaf1a3..d2c85ec 100644
--- a/libc/src/math/docs/add_math_function.md
+++ b/libc/src/math/docs/add_math_function.md
@@ -183,8 +183,8 @@ implementation (which is very often glibc).
- Build and Run exhaustive test (might take hours to run):
```
- $ ninja libc.test.src.math.exhaustive.<func>_test
- $ projects/libc/test/src/math/exhaustive/libc.test.src.math.exhaustive.<func>_test
+ $ ninja libc.test.src.math.exhaustive.<func>_test.__unit__
+ $ projects/libc/test/src/math/exhaustive/libc.test.src.math.exhaustive.<func>_test.__unit__
```
- Build and Run performance test:
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 7e6a32b..f91feacb 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1295,12 +1295,8 @@ add_entrypoint_object(
HDRS
../erff.h
DEPENDS
- .common_constants
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.macros.optimization
+ libc.src.__support.math.erff
+ libc.src.errno.errno
)
add_entrypoint_object(
@@ -1898,6 +1894,7 @@ add_object_library(
common_constants.cpp
DEPENDS
libc.src.__support.math.exp_constants
+ libc.src.__support.math.acosh_float_constants
libc.src.__support.number_pair
)
@@ -3761,7 +3758,7 @@ add_header_library(
DEPENDS
.common_constants
libc.src.__support.math.exp_utils
- libc.src.__support.math.exp10f_utils
+ libc.src.__support.math.acoshf_utils
libc.src.__support.macros.properties.cpu_features
libc.src.errno.errno
)
@@ -3871,12 +3868,7 @@ add_entrypoint_object(
../acoshf.h
DEPENDS
.explogxf
- 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.math.acoshf
)
add_entrypoint_object(
@@ -3886,18 +3878,8 @@ add_entrypoint_object(
HDRS
../acoshf16.h
DEPENDS
- .explogxf
- libc.hdr.errno_macros
- libc.hdr.fenv_macros
- libc.src.__support.FPUtil.cast
- libc.src.__support.FPUtil.except_value_utils
- 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.acoshf16
+ libc.src.errno.errno
)
add_entrypoint_object(
@@ -3907,12 +3889,7 @@ add_entrypoint_object(
HDRS
../asinhf.h
DEPENDS
- .explogxf
- 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.asinhf
)
add_entrypoint_object(
@@ -3969,18 +3946,6 @@ add_entrypoint_object(
libc.src.__support.macros.properties.types
)
-add_object_library(
- inv_trigf_utils
- HDRS
- inv_trigf_utils.h
- SRCS
- inv_trigf_utils.cpp
- DEPENDS
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.common
-)
-
add_entrypoint_object(
asinf
SRCS
@@ -3988,13 +3953,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
- .inv_trigf_utils
+ libc.src.__support.math.asinf
)
add_entrypoint_object(
@@ -4004,16 +3963,7 @@ add_entrypoint_object(
HDRS
../asinf16.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.asinf16
)
add_entrypoint_object(
@@ -4023,16 +3973,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(
@@ -4042,13 +3983,7 @@ add_entrypoint_object(
HDRS
../acosf.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
- .inv_trigf_utils
+ libc.src.__support.math.acosf
)
add_entrypoint_object(
@@ -4058,17 +3993,8 @@ add_entrypoint_object(
HDRS
../acosf16.h
DEPENDS
- libc.hdr.errno_macros
- libc.hdr.fenv_macros
- libc.src.__support.FPUtil.cast
- libc.src.__support.FPUtil.except_value_utils
- 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.acosf16
+ libc.src.errno.errno
)
add_entrypoint_object(
@@ -4088,16 +4014,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(
@@ -4120,7 +4038,6 @@ add_entrypoint_object(
HDRS
../atanf.h
DEPENDS
- .inv_trigf_utils
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
@@ -4128,6 +4045,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.inv_trigf_utils
)
add_entrypoint_object(
@@ -4176,7 +4094,6 @@ add_entrypoint_object(
../atan2f.h
atan2f_float.h
DEPENDS
- .inv_trigf_utils
libc.hdr.fenv_macros
libc.src.__support.FPUtil.double_double
libc.src.__support.FPUtil.fenv_impl
@@ -4186,6 +4103,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.inv_trigf_utils
)
add_entrypoint_object(
@@ -4987,6 +4905,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/acosf.cpp b/libc/src/math/generic/acosf.cpp
index 8dd6de2..7afc7d6 100644
--- a/libc/src/math/generic/acosf.cpp
+++ b/libc/src/math/generic/acosf.cpp
@@ -7,127 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/acosf.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 "inv_trigf_utils.h"
+#include "src/__support/math/acosf.h"
namespace LIBC_NAMESPACE_DECL {
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr size_t N_EXCEPTS = 4;
-
-// Exceptional values when |x| <= 0.5
-static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{
- // (inputs, RZ output, RU offset, RD offset, RN offset)
- // x = 0x1.110b46p-26, acosf(x) = 0x1.921fb4p0 (RZ)
- {0x328885a3, 0x3fc90fda, 1, 0, 1},
- // x = -0x1.110b46p-26, acosf(x) = 0x1.921fb4p0 (RZ)
- {0xb28885a3, 0x3fc90fda, 1, 0, 1},
- // x = 0x1.04c444p-12, acosf(x) = 0x1.920f68p0 (RZ)
- {0x39826222, 0x3fc907b4, 1, 0, 1},
- // x = -0x1.04c444p-12, acosf(x) = 0x1.923p0 (RZ)
- {0xb9826222, 0x3fc91800, 1, 0, 1},
-}};
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
- using FPBits = typename fputil::FPBits<float>;
-
- FPBits xbits(x);
- uint32_t x_uint = xbits.uintval();
- uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU;
- uint32_t x_sign = x_uint >> 31;
-
- // |x| <= 0.5
- if (LIBC_UNLIKELY(x_abs <= 0x3f00'0000U)) {
- // |x| < 0x1p-10
- if (LIBC_UNLIKELY(x_abs < 0x3a80'0000U)) {
- // When |x| < 2^-10, we use the following approximation:
- // acos(x) = pi/2 - asin(x)
- // ~ pi/2 - x - x^3 / 6
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Check for exceptional values
- if (auto r = ACOSF_EXCEPTS.lookup(x_uint); LIBC_UNLIKELY(r.has_value()))
- return r.value();
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- double xd = static_cast<double>(x);
- return static_cast<float>(fputil::multiply_add(
- -0x1.5555555555555p-3 * xd, xd * xd, M_MATH_PI_2 - xd));
- }
-
- // For |x| <= 0.5, we approximate acosf(x) by:
- // acos(x) = pi/2 - asin(x) = pi/2 - 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]);
- 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, M_MATH_PI_2 - xd));
- }
-
- // |x| >= 1, return 0, 2pi, or NaNs.
- if (LIBC_UNLIKELY(x_abs >= 0x3f80'0000U)) {
- if (x_abs == 0x3f80'0000U)
- return x_sign ? /* x == -1.0f */ fputil::round_result_slightly_down(
- 0x1.921fb6p+1f)
- : /* x == 1.0f */ 0.0f;
-
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- // |x| <= +/-inf
- if (x_abs <= 0x7f80'0000U) {
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- }
-
- return x + FPBits::quiet_nan().get_val();
- }
-
- // When 0.5 < |x| < 1, we perform range reduction as follow:
- //
- // Assume further that 0.5 < x <= 1, and let:
- // y = acos(x)
- // We use the double angle formula:
- // x = cos(y) = 1 - 2 sin^2(y/2)
- // So:
- // sin(y/2) = sqrt( (1 - x)/2 )
- // And hence:
- // y = 2 * asin( sqrt( (1 - x)/2 ) )
- // Let u = (1 - x)/2, then
- // acos(x) = 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:
- // acos(x) ~ 2 * sqrt(u) * P(u).
- //
- // When -1 < x <= -0.5, we use the identity:
- // acos(x) = pi - acos(-x)
- // which is reduced to the postive case.
-
- xbits.set_sign(Sign::POS);
- double xd = static_cast<double>(xbits.get_val());
- double u = fputil::multiply_add(-0.5, xd, 0.5);
- double cv = 2 * fputil::sqrt<double>(u);
-
- double r3 = asin_eval(u);
- double r = fputil::multiply_add(cv * u, r3, cv);
- return static_cast<float>(x_sign ? M_MATH_PI - r : r);
-}
+LLVM_LIBC_FUNCTION(float, acosf, (float x)) { return math::acosf(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/acosf16.cpp b/libc/src/math/generic/acosf16.cpp
index 202a950..0bf85f8 100644
--- a/libc/src/math/generic/acosf16.cpp
+++ b/libc/src/math/generic/acosf16.cpp
@@ -8,144 +8,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/acosf16.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/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/macros/optimization.h"
+#include "src/__support/math/acosf16.h"
namespace LIBC_NAMESPACE_DECL {
-// Generated by Sollya using the following command:
-// > round(pi/2, SG, RN);
-// > round(pi, SG, RN);
-static constexpr float PI_OVER_2 = 0x1.921fb6p0f;
-static constexpr float PI = 0x1.921fb6p1f;
+LLVM_LIBC_FUNCTION(float16, acosf16, (float16 x)) { return math::acosf16(x); }
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr size_t N_EXCEPTS = 2;
-
-static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSF16_EXCEPTS{{
- // (input, RZ output, RU offset, RD offset, RN offset)
- {0xacaf, 0x3e93, 1, 0, 0},
- {0xb874, 0x4052, 1, 0, 1},
-}};
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-LLVM_LIBC_FUNCTION(float16, acosf16, (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)) {
- // acosf16(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();
- }
-
- float xf = x;
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Handle exceptional values
- if (auto r = ACOSF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
- return r.value();
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // |x| == 0x1p0, x is 1 or -1
- // if x is (-)1, return pi, else
- // if x is (+)1, return 0
- if (LIBC_UNLIKELY(x_abs == 0x3c00))
- return fputil::cast<float16>(x_sign ? PI : 0.0f);
-
- float xsq = xf * xf;
-
- // |x| <= 0x1p-1, |x| <= 0.5
- if (x_abs <= 0x3800) {
- // if x is 0, return pi/2
- if (LIBC_UNLIKELY(x_abs == 0))
- return fputil::cast<float16>(PI_OVER_2);
-
- // Note that: acos(x) = pi/2 + asin(-x) = pi/2 - asin(x)
- // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
- // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
- float interm =
- fputil::polyeval(xsq, 0x1.000002p0f, 0x1.554c2ap-3f, 0x1.3541ccp-4f,
- 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
- return fputil::cast<float16>(fputil::multiply_add(-xf, interm, PI_OVER_2));
- }
-
- // 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))
- //
- // 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)
- // 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);
-
- // Degree-6 minimax polynomial of asin(x) generated by Sollya with:
- // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
- float asin_sqrt_u =
- sqrt_u * fputil::polyeval(u, 0x1.000002p0f, 0x1.554c2ap-3f,
- 0x1.3541ccp-4f, 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
-
- return fputil::cast<float16>(
- x_sign ? fputil::multiply_add(-2.0f, asin_sqrt_u, PI) : 2 * asin_sqrt_u);
-}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/acoshf.cpp b/libc/src/math/generic/acoshf.cpp
index c4927fa..5c04583 100644
--- a/libc/src/math/generic/acoshf.cpp
+++ b/libc/src/math/generic/acoshf.cpp
@@ -7,73 +7,11 @@
//===----------------------------------------------------------------------===//
#include "src/math/acoshf.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.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/math/generic/common_constants.h"
-#include "src/math/generic/explogxf.h"
-namespace LIBC_NAMESPACE_DECL {
-
-LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
- using FPBits_t = typename fputil::FPBits<float>;
- FPBits_t xbits(x);
-
- if (LIBC_UNLIKELY(x <= 1.0f)) {
- if (x == 1.0f)
- return 0.0f;
- // x < 1.
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits_t::quiet_nan().get_val();
- }
+#include "src/__support/math/acoshf.h"
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- uint32_t x_u = xbits.uintval();
- if (LIBC_UNLIKELY(x_u >= 0x4f8ffb03)) {
- if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
- return x;
-
- // Helper functions to set results for exceptional cases.
- auto round_result_slightly_down = [](float r) -> float {
- volatile float tmp = r;
- tmp = tmp - 0x1.0p-25f;
- return tmp;
- };
- auto round_result_slightly_up = [](float r) -> float {
- volatile float tmp = r;
- tmp = tmp + 0x1.0p-25f;
- return tmp;
- };
-
- switch (x_u) {
- case 0x4f8ffb03: // x = 0x1.1ff606p32f
- return round_result_slightly_up(0x1.6fdd34p4f);
- case 0x5c569e88: // x = 0x1.ad3d1p57f
- return round_result_slightly_up(0x1.45c146p5f);
- case 0x5e68984e: // x = 0x1.d1309cp61f
- return round_result_slightly_up(0x1.5c9442p5f);
- case 0x655890d3: // x = 0x1.b121a6p75f
- return round_result_slightly_down(0x1.a9a3f2p5f);
- case 0x6eb1a8ec: // x = 0x1.6351d8p94f
- return round_result_slightly_down(0x1.08b512p6f);
- case 0x7997f30a: // x = 0x1.2fe614p116f
- return round_result_slightly_up(0x1.451436p6f);
- }
- }
-#else
- if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
- return x;
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+namespace LIBC_NAMESPACE_DECL {
- double x_d = static_cast<double>(x);
- // acosh(x) = log(x + sqrt(x^2 - 1))
- return static_cast<float>(log_eval(
- x_d + fputil::sqrt<double>(fputil::multiply_add(x_d, x_d, -1.0))));
-}
+LLVM_LIBC_FUNCTION(float, acoshf, (float x)) { return math::acoshf(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/acoshf16.cpp b/libc/src/math/generic/acoshf16.cpp
index 44783a8..bb3a91f 100644
--- a/libc/src/math/generic/acoshf16.cpp
+++ b/libc/src/math/generic/acoshf16.cpp
@@ -7,104 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/acoshf16.h"
-#include "explogxf.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/except_value_utils.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/sqrt.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h"
+#include "src/__support/math/acoshf16.h"
namespace LIBC_NAMESPACE_DECL {
-static constexpr size_t N_EXCEPTS = 2;
-static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
- // (input, RZ output, RU offset, RD offset, RN offset)
- // x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
- {0x41B7, 0x3ED8, 1, 0, 0},
- // x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
- {0x3CE4, 0x393E, 1, 0, 1},
-}};
-
-LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
- using FPBits = fputil::FPBits<float16>;
- FPBits xbits(x);
- uint16_t x_u = xbits.uintval();
-
- // Check for NaN input first.
- if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
- if (xbits.is_neg()) {
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
- return x;
- }
-
- // Domain error for inputs less than 1.0.
- if (LIBC_UNLIKELY(x <= 1.0f)) {
- if (x == 1.0f)
- return FPBits::zero().get_val();
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- if (auto r = ACOSHF16_EXCEPTS.lookup(xbits.uintval());
- LIBC_UNLIKELY(r.has_value()))
- return r.value();
-
- float xf = x;
- // High-precision polynomial approximation for inputs close to 1.0
- // ([1, 1.25)).
- //
- // Brief derivation:
- // 1. Expand acosh(1 + delta) using Taylor series around delta=0:
- // acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
- // - 5*delta^3/896 + 35*delta^4/18432 + ...]
- // 2. Truncate the series to fit accurately for delta in [0, 0.25].
- // 3. Polynomial coefficients (from sollya) used here are:
- // P(delta) ≈ 1 - 0x1.555556p-4 * delta + 0x1.333334p-6 * delta^2
- // - 0x1.6db6dcp-8 * delta^3 + 0x1.f1c71cp-10 * delta^4
- // 4. The Sollya commands used to generate these coefficients were:
- // > display = hexadecimal;
- // > round(1/12, SG, RN);
- // > round(3/160, SG, RN);
- // > round(5/896, SG, RN);
- // > round(35/18432, SG, RN);
- // With hexadecimal display mode enabled, the outputs were:
- // 0x1.555556p-4
- // 0x1.333334p-6
- // 0x1.6db6dcp-8
- // 0x1.f1c71cp-10
- // 5. The maximum absolute error, estimated using:
- // dirtyinfnorm(acosh(1 + x) - sqrt(2*x) * P(x), [0, 0.25])
- // is:
- // 0x1.d84281p-22
- if (LIBC_UNLIKELY(x_u < 0x3D00U)) {
- float delta = xf - 1.0f;
- float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
- float pe = fputil::polyeval(delta, 0x1p+0f, -0x1.555556p-4f, 0x1.333334p-6f,
- -0x1.6db6dcp-8f, 0x1.f1c71cp-10f);
- float approx = sqrt_2_delta * pe;
- return fputil::cast<float16>(approx);
- }
-
- // acosh(x) = log(x + sqrt(x^2 - 1))
- float sqrt_term = fputil::sqrt<float>(fputil::multiply_add(xf, xf, -1.0f));
- float result = static_cast<float>(log_eval(xf + sqrt_term));
-
- return fputil::cast<float16>(result);
-}
+LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) { return math::acoshf16(x); }
} // namespace LIBC_NAMESPACE_DECL
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 c033597..b5ba9ea 100644
--- a/libc/src/math/generic/asin.cpp
+++ b/libc/src/math/generic/asin.cpp
@@ -7,24 +7,12 @@
//===----------------------------------------------------------------------===//
#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>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp
index 12383bf..9c6766f 100644
--- a/libc/src/math/generic/asinf.cpp
+++ b/libc/src/math/generic/asinf.cpp
@@ -7,160 +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 "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 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/asinf16.cpp b/libc/src/math/generic/asinf16.cpp
index 518c384..af8dbfe 100644
--- a/libc/src/math/generic/asinf16.cpp
+++ b/libc/src/math/generic/asinf16.cpp
@@ -7,127 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/asinf16.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/asinf16.h"
namespace LIBC_NAMESPACE_DECL {
-// Generated by Sollya using the following command:
-// > round(pi/2, D, RN);
-static constexpr float PI_2 = 0x1.921fb54442d18p0f;
-
-LLVM_LIBC_FUNCTION(float16, asinf16, (float16 x)) {
- using FPBits = fputil::FPBits<float16>;
- FPBits xbits(x);
-
- uint16_t x_u = xbits.uintval();
- uint16_t x_abs = x_u & 0x7fff;
- float xf = x;
-
- // |x| > 0x1p0, |x| > 1, or x is NaN.
- if (LIBC_UNLIKELY(x_abs > 0x3c00)) {
- // asinf16(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();
- }
-
- float xsq = xf * xf;
-
- // |x| <= 0x1p-1, |x| <= 0.5
- if (x_abs <= 0x3800) {
- // asinf16(+/-0) = +/-0
- if (LIBC_UNLIKELY(x_abs == 0))
- return x;
-
- // Exhaustive tests show that,
- // for |x| <= 0x1.878p-9, when:
- // x > 0, and rounding upward, or
- // x < 0, and rounding downward, then,
- // asin(x) = x * 2^-11 + x
- // else, in other rounding modes,
- // asin(x) = x
- if (LIBC_UNLIKELY(x_abs <= 0x1a1e)) {
- int rounding = fputil::quick_get_round();
-
- if ((xbits.is_pos() && rounding == FE_UPWARD) ||
- (xbits.is_neg() && rounding == FE_DOWNWARD))
- return fputil::cast<float16>(fputil::multiply_add(xf, 0x1.0p-11f, xf));
- return x;
- }
-
- // Degree-6 minimax odd polynomial of asin(x) generated by Sollya with:
- // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
- float result =
- fputil::polyeval(xsq, 0x1.000002p0f, 0x1.554c2ap-3f, 0x1.3541ccp-4f,
- 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
- return fputil::cast<float16>(xf * result);
- }
-
- // 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 - 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))
- //
- // WHY?
- // 11: Recall [7], u = (1 - x)/2
- // 12: 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 [10] as `sqrt(u)` is in range.
-
- // 0x1p-1 < |x| <= 0x1p0, 0.5 < |x| <= 1.0
- float xf_abs = (xf < 0 ? -xf : xf);
- float sign = (xbits.uintval() >> 15 == 1 ? -1.0 : 1.0);
- float u = fputil::multiply_add(-0.5f, xf_abs, 0.5f);
- float u_sqrt = fputil::sqrt<float>(u);
-
- // Degree-6 minimax odd polynomial of asin(x) generated by Sollya with:
- // > P = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8|], [|SG...|], [0, 0.5]);
- float asin_sqrt_u =
- u_sqrt * fputil::polyeval(u, 0x1.000002p0f, 0x1.554c2ap-3f,
- 0x1.3541ccp-4f, 0x1.43b2d6p-5f, 0x1.a0d73ep-5f);
-
- return fputil::cast<float16>(sign *
- fputil::multiply_add(-2.0f, asin_sqrt_u, PI_2));
-}
+LLVM_LIBC_FUNCTION(float16, asinf16, (float16 x)) { return math::asinf16(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/asinhf.cpp b/libc/src/math/generic/asinhf.cpp
index 0bb7065..45023c8 100644
--- a/libc/src/math/generic/asinhf.cpp
+++ b/libc/src/math/generic/asinhf.cpp
@@ -7,111 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/asinhf.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/PolyEval.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/math/generic/common_constants.h"
-#include "src/math/generic/explogxf.h"
+#include "src/__support/math/asinhf.h"
namespace LIBC_NAMESPACE_DECL {
-LLVM_LIBC_FUNCTION(float, asinhf, (float x)) {
- using FPBits_t = typename fputil::FPBits<float>;
- FPBits_t xbits(x);
- uint32_t x_u = xbits.uintval();
- uint32_t x_abs = xbits.abs().uintval();
-
- // |x| <= 2^-3
- if (LIBC_UNLIKELY(x_abs <= 0x3e80'0000U)) {
- // |x| <= 2^-26
- if (LIBC_UNLIKELY(x_abs <= 0x3280'0000U)) {
- return static_cast<float>(LIBC_UNLIKELY(x_abs == 0)
- ? x
- : (x - 0x1.5555555555555p-3 * x * x * x));
- }
-
- double x_d = x;
- double x_sq = x_d * x_d;
- // Generated by Sollya with:
- // > P = fpminimax(asinh(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16|], [|D...|],
- // [0, 2^-2]);
- double p = fputil::polyeval(
- x_sq, 0.0, -0x1.555555555551ep-3, 0x1.3333333325495p-4,
- -0x1.6db6db5a7622bp-5, 0x1.f1c70f82928c6p-6, -0x1.6e893934266b7p-6,
- 0x1.1c0b41d3fbe78p-6, -0x1.c0f47810b3c4fp-7, 0x1.2c8602690143dp-7);
- return static_cast<float>(fputil::multiply_add(x_d, p, x_d));
- }
-
- const double SIGN[2] = {1.0, -1.0};
- double x_sign = SIGN[x_u >> 31];
- double x_d = x;
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Helper functions to set results for exceptional cases.
- auto round_result_slightly_down = [x_sign](float r) -> float {
- return fputil::multiply_add(static_cast<float>(x_sign), r,
- static_cast<float>(x_sign) * (-0x1.0p-24f));
- };
- auto round_result_slightly_up = [x_sign](float r) -> float {
- return fputil::multiply_add(static_cast<float>(x_sign), r,
- static_cast<float>(x_sign) * 0x1.0p-24f);
- };
-
- if (LIBC_UNLIKELY(x_abs >= 0x4bdd'65a5U)) {
- if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits_t::quiet_nan().get_val();
- }
-
- return x;
- }
-
- // Exceptional cases when x > 2^24.
- switch (x_abs) {
- case 0x4bdd65a5: // |x| = 0x1.bacb4ap24f
- return round_result_slightly_down(0x1.1e0696p4f);
- case 0x4c803f2c: // |x| = 0x1.007e58p26f
- return round_result_slightly_down(0x1.2b786cp4f);
- case 0x4f8ffb03: // |x| = 0x1.1ff606p32f
- return round_result_slightly_up(0x1.6fdd34p4f);
- case 0x5c569e88: // |x| = 0x1.ad3d1p57f
- return round_result_slightly_up(0x1.45c146p5f);
- case 0x5e68984e: // |x| = 0x1.d1309cp61f
- return round_result_slightly_up(0x1.5c9442p5f);
- case 0x655890d3: // |x| = 0x1.b121a6p75f
- return round_result_slightly_down(0x1.a9a3f2p5f);
- case 0x65de7ca6: // |x| = 0x1.bcf94cp76f
- return round_result_slightly_up(0x1.af66cp5f);
- case 0x6eb1a8ec: // |x| = 0x1.6351d8p94f
- return round_result_slightly_down(0x1.08b512p6f);
- case 0x7997f30a: // |x| = 0x1.2fe614p116f
- return round_result_slightly_up(0x1.451436p6f);
- }
- } else {
- // Exceptional cases when x < 2^24.
- if (LIBC_UNLIKELY(x_abs == 0x45abaf26)) {
- // |x| = 0x1.575e4cp12f
- return round_result_slightly_down(0x1.29becap3f);
- }
- if (LIBC_UNLIKELY(x_abs == 0x49d29048)) {
- // |x| = 0x1.a5209p20f
- return round_result_slightly_down(0x1.e1b92p3f);
- }
- }
-#else
- if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
- return x;
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // asinh(x) = log(x + sqrt(x^2 + 1))
- return static_cast<float>(
- x_sign * log_eval(fputil::multiply_add(
- x_d, x_sign,
- fputil::sqrt<double>(fputil::multiply_add(x_d, x_d, 1.0)))));
-}
+LLVM_LIBC_FUNCTION(float, asinhf, (float x)) { return math::asinhf(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/asinhf16.cpp b/libc/src/math/generic/asinhf16.cpp
index 7878632..0a0b471 100644
--- a/libc/src/math/generic/asinhf16.cpp
+++ b/libc/src/math/generic/asinhf16.cpp
@@ -49,6 +49,7 @@ static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ASINHF16_EXCEPTS{{
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, asinhf16, (float16 x)) {
+ using namespace acoshf_internal;
using FPBits = fputil::FPBits<float16>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/atan2f.cpp b/libc/src/math/generic/atan2f.cpp
index c04b0eb..32b977f 100644
--- a/libc/src/math/generic/atan2f.cpp
+++ b/libc/src/math/generic/atan2f.cpp
@@ -8,7 +8,6 @@
#include "src/math/atan2f.h"
#include "hdr/fenv_macros.h"
-#include "inv_trigf_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -18,6 +17,7 @@
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/inv_trigf_utils.h"
#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS) && \
defined(LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT)
@@ -236,6 +236,7 @@ float atan2f_double_double(double num_d, double den_d, double q_d, int idx,
// which is about rounding errors of double-double (2^-104).
LLVM_LIBC_FUNCTION(float, atan2f, (float y, float x)) {
+ using namespace inv_trigf_utils_internal;
using FPBits = typename fputil::FPBits<float>;
constexpr double IS_NEG[2] = {1.0, -1.0};
constexpr double PI = 0x1.921fb54442d18p1;
diff --git a/libc/src/math/generic/atanf.cpp b/libc/src/math/generic/atanf.cpp
index 46196dbe..22f962e 100644
--- a/libc/src/math/generic/atanf.cpp
+++ b/libc/src/math/generic/atanf.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/atanf.h"
-#include "inv_trigf_utils.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/except_value_utils.h"
@@ -16,10 +15,12 @@
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/inv_trigf_utils.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float, atanf, (float x)) {
+ using namespace inv_trigf_utils_internal;
using FPBits = typename fputil::FPBits<float>;
constexpr double FINAL_SIGN[2] = {1.0, -1.0};
diff --git a/libc/src/math/generic/atanhf.cpp b/libc/src/math/generic/atanhf.cpp
index f6fde76..602a8f0 100644
--- a/libc/src/math/generic/atanhf.cpp
+++ b/libc/src/math/generic/atanhf.cpp
@@ -16,6 +16,7 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float, atanhf, (float x)) {
+ using namespace acoshf_internal;
using FPBits = typename fputil::FPBits<float>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/common_constants.cpp b/libc/src/math/generic/common_constants.cpp
index 4dcf84d..42e3ff0 100644
--- a/libc/src/math/generic/common_constants.cpp
+++ b/libc/src/math/generic/common_constants.cpp
@@ -51,52 +51,6 @@ const float ONE_OVER_F_FLOAT[128] = {
0x1.08421p-1f, 0x1.07326p-1f, 0x1.0624dep-1f, 0x1.05198p-1f,
0x1.041042p-1f, 0x1.03091cp-1f, 0x1.020408p-1f, 0x1.010102p-1f};
-// Lookup table for (1/f) where f = 1 + n*2^(-7), n = 0..127.
-const double ONE_OVER_F[128] = {
- 0x1.0000000000000p+0, 0x1.fc07f01fc07f0p-1, 0x1.f81f81f81f820p-1,
- 0x1.f44659e4a4271p-1, 0x1.f07c1f07c1f08p-1, 0x1.ecc07b301ecc0p-1,
- 0x1.e9131abf0b767p-1, 0x1.e573ac901e574p-1, 0x1.e1e1e1e1e1e1ep-1,
- 0x1.de5d6e3f8868ap-1, 0x1.dae6076b981dbp-1, 0x1.d77b654b82c34p-1,
- 0x1.d41d41d41d41dp-1, 0x1.d0cb58f6ec074p-1, 0x1.cd85689039b0bp-1,
- 0x1.ca4b3055ee191p-1, 0x1.c71c71c71c71cp-1, 0x1.c3f8f01c3f8f0p-1,
- 0x1.c0e070381c0e0p-1, 0x1.bdd2b899406f7p-1, 0x1.bacf914c1bad0p-1,
- 0x1.b7d6c3dda338bp-1, 0x1.b4e81b4e81b4fp-1, 0x1.b2036406c80d9p-1,
- 0x1.af286bca1af28p-1, 0x1.ac5701ac5701bp-1, 0x1.a98ef606a63bep-1,
- 0x1.a6d01a6d01a6dp-1, 0x1.a41a41a41a41ap-1, 0x1.a16d3f97a4b02p-1,
- 0x1.9ec8e951033d9p-1, 0x1.9c2d14ee4a102p-1, 0x1.999999999999ap-1,
- 0x1.970e4f80cb872p-1, 0x1.948b0fcd6e9e0p-1, 0x1.920fb49d0e229p-1,
- 0x1.8f9c18f9c18fap-1, 0x1.8d3018d3018d3p-1, 0x1.8acb90f6bf3aap-1,
- 0x1.886e5f0abb04ap-1, 0x1.8618618618618p-1, 0x1.83c977ab2beddp-1,
- 0x1.8181818181818p-1, 0x1.7f405fd017f40p-1, 0x1.7d05f417d05f4p-1,
- 0x1.7ad2208e0ecc3p-1, 0x1.78a4c8178a4c8p-1, 0x1.767dce434a9b1p-1,
- 0x1.745d1745d1746p-1, 0x1.724287f46debcp-1, 0x1.702e05c0b8170p-1,
- 0x1.6e1f76b4337c7p-1, 0x1.6c16c16c16c17p-1, 0x1.6a13cd1537290p-1,
- 0x1.6816816816817p-1, 0x1.661ec6a5122f9p-1, 0x1.642c8590b2164p-1,
- 0x1.623fa77016240p-1, 0x1.6058160581606p-1, 0x1.5e75bb8d015e7p-1,
- 0x1.5c9882b931057p-1, 0x1.5ac056b015ac0p-1, 0x1.58ed2308158edp-1,
- 0x1.571ed3c506b3ap-1, 0x1.5555555555555p-1, 0x1.5390948f40febp-1,
- 0x1.51d07eae2f815p-1, 0x1.5015015015015p-1, 0x1.4e5e0a72f0539p-1,
- 0x1.4cab88725af6ep-1, 0x1.4afd6a052bf5bp-1, 0x1.49539e3b2d067p-1,
- 0x1.47ae147ae147bp-1, 0x1.460cbc7f5cf9ap-1, 0x1.446f86562d9fbp-1,
- 0x1.42d6625d51f87p-1, 0x1.4141414141414p-1, 0x1.3fb013fb013fbp-1,
- 0x1.3e22cbce4a902p-1, 0x1.3c995a47babe7p-1, 0x1.3b13b13b13b14p-1,
- 0x1.3991c2c187f63p-1, 0x1.3813813813814p-1, 0x1.3698df3de0748p-1,
- 0x1.3521cfb2b78c1p-1, 0x1.33ae45b57bcb2p-1, 0x1.323e34a2b10bfp-1,
- 0x1.30d190130d190p-1, 0x1.2f684bda12f68p-1, 0x1.2e025c04b8097p-1,
- 0x1.2c9fb4d812ca0p-1, 0x1.2b404ad012b40p-1, 0x1.29e4129e4129ep-1,
- 0x1.288b01288b013p-1, 0x1.27350b8812735p-1, 0x1.25e22708092f1p-1,
- 0x1.2492492492492p-1, 0x1.23456789abcdfp-1, 0x1.21fb78121fb78p-1,
- 0x1.20b470c67c0d9p-1, 0x1.1f7047dc11f70p-1, 0x1.1e2ef3b3fb874p-1,
- 0x1.1cf06ada2811dp-1, 0x1.1bb4a4046ed29p-1, 0x1.1a7b9611a7b96p-1,
- 0x1.19453808ca29cp-1, 0x1.1811811811812p-1, 0x1.16e0689427379p-1,
- 0x1.15b1e5f75270dp-1, 0x1.1485f0e0acd3bp-1, 0x1.135c81135c811p-1,
- 0x1.12358e75d3033p-1, 0x1.1111111111111p-1, 0x1.0fef010fef011p-1,
- 0x1.0ecf56be69c90p-1, 0x1.0db20a88f4696p-1, 0x1.0c9714fbcda3bp-1,
- 0x1.0b7e6ec259dc8p-1, 0x1.0a6810a6810a7p-1, 0x1.0953f39010954p-1,
- 0x1.0842108421084p-1, 0x1.073260a47f7c6p-1, 0x1.0624dd2f1a9fcp-1,
- 0x1.05197f7d73404p-1, 0x1.0410410410410p-1, 0x1.03091b51f5e1ap-1,
- 0x1.0204081020408p-1, 0x1.0101010101010p-1};
-
// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127,
// computed and stored as float precision constants.
// Generated by Sollya with the following commands:
@@ -136,52 +90,6 @@ const float LOG_F_FLOAT[128] = {
0x1.52a2d2p-1f, 0x1.54b246p-1f, 0x1.56bf9ep-1f, 0x1.58cadcp-1f,
0x1.5ad404p-1f, 0x1.5cdb1ep-1f, 0x1.5ee02ap-1f, 0x1.60e33p-1f};
-// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127.
-const double LOG_F[128] = {
- 0x0.0000000000000p+0, 0x1.fe02a6b106788p-8, 0x1.fc0a8b0fc03e3p-7,
- 0x1.7b91b07d5b11ap-6, 0x1.f829b0e783300p-6, 0x1.39e87b9febd5fp-5,
- 0x1.77458f632dcfcp-5, 0x1.b42dd711971bep-5, 0x1.f0a30c01162a6p-5,
- 0x1.16536eea37ae0p-4, 0x1.341d7961bd1d0p-4, 0x1.51b073f06183fp-4,
- 0x1.6f0d28ae56b4bp-4, 0x1.8c345d6319b20p-4, 0x1.a926d3a4ad563p-4,
- 0x1.c5e548f5bc743p-4, 0x1.e27076e2af2e5p-4, 0x1.fec9131dbeabap-4,
- 0x1.0d77e7cd08e59p-3, 0x1.1b72ad52f67a0p-3, 0x1.29552f81ff523p-3,
- 0x1.371fc201e8f74p-3, 0x1.44d2b6ccb7d1ep-3, 0x1.526e5e3a1b437p-3,
- 0x1.5ff3070a793d3p-3, 0x1.6d60fe719d21cp-3, 0x1.7ab890210d909p-3,
- 0x1.87fa06520c910p-3, 0x1.9525a9cf456b4p-3, 0x1.a23bc1fe2b563p-3,
- 0x1.af3c94e80bff2p-3, 0x1.bc286742d8cd6p-3, 0x1.c8ff7c79a9a21p-3,
- 0x1.d5c216b4fbb91p-3, 0x1.e27076e2af2e5p-3, 0x1.ef0adcbdc5936p-3,
- 0x1.fb9186d5e3e2ap-3, 0x1.0402594b4d040p-2, 0x1.0a324e27390e3p-2,
- 0x1.1058bf9ae4ad5p-2, 0x1.1675cababa60ep-2, 0x1.1c898c16999fap-2,
- 0x1.22941fbcf7965p-2, 0x1.2895a13de86a3p-2, 0x1.2e8e2bae11d30p-2,
- 0x1.347dd9a987d54p-2, 0x1.3a64c556945e9p-2, 0x1.404308686a7e3p-2,
- 0x1.4618bc21c5ec2p-2, 0x1.4be5f957778a0p-2, 0x1.51aad872df82dp-2,
- 0x1.5767717455a6cp-2, 0x1.5d1bdbf5809cap-2, 0x1.62c82f2b9c795p-2,
- 0x1.686c81e9b14aep-2, 0x1.6e08eaa2ba1e3p-2, 0x1.739d7f6bbd006p-2,
- 0x1.792a55fdd47a2p-2, 0x1.7eaf83b82afc3p-2, 0x1.842d1da1e8b17p-2,
- 0x1.89a3386c1425ap-2, 0x1.8f11e873662c7p-2, 0x1.947941c2116fap-2,
- 0x1.99d958117e08ap-2, 0x1.9f323ecbf984bp-2, 0x1.a484090e5bb0ap-2,
- 0x1.a9cec9a9a0849p-2, 0x1.af1293247786bp-2, 0x1.b44f77bcc8f62p-2,
- 0x1.b9858969310fbp-2, 0x1.beb4d9da71b7bp-2, 0x1.c3dd7a7cdad4dp-2,
- 0x1.c8ff7c79a9a21p-2, 0x1.ce1af0b85f3ebp-2, 0x1.d32fe7e00ebd5p-2,
- 0x1.d83e7258a2f3ep-2, 0x1.dd46a04c1c4a0p-2, 0x1.e24881a7c6c26p-2,
- 0x1.e744261d68787p-2, 0x1.ec399d2468cc0p-2, 0x1.f128f5faf06ecp-2,
- 0x1.f6123fa7028acp-2, 0x1.faf588f78f31ep-2, 0x1.ffd2e0857f498p-2,
- 0x1.02552a5a5d0fep-1, 0x1.04bdf9da926d2p-1, 0x1.0723e5c1cdf40p-1,
- 0x1.0986f4f573520p-1, 0x1.0be72e4252a82p-1, 0x1.0e44985d1cc8bp-1,
- 0x1.109f39e2d4c96p-1, 0x1.12f719593efbcp-1, 0x1.154c3d2f4d5e9p-1,
- 0x1.179eabbd899a0p-1, 0x1.19ee6b467c96ep-1, 0x1.1c3b81f713c24p-1,
- 0x1.1e85f5e7040d0p-1, 0x1.20cdcd192ab6dp-1, 0x1.23130d7bebf42p-1,
- 0x1.2555bce98f7cbp-1, 0x1.2795e1289b11ap-1, 0x1.29d37fec2b08ap-1,
- 0x1.2c0e9ed448e8bp-1, 0x1.2e47436e40268p-1, 0x1.307d7334f10bep-1,
- 0x1.32b1339121d71p-1, 0x1.34e289d9ce1d3p-1, 0x1.37117b54747b5p-1,
- 0x1.393e0d3562a19p-1, 0x1.3b68449fffc22p-1, 0x1.3d9026a7156fap-1,
- 0x1.3fb5b84d16f42p-1, 0x1.41d8fe84672aep-1, 0x1.43f9fe2f9ce67p-1,
- 0x1.4618bc21c5ec2p-1, 0x1.48353d1ea88dfp-1, 0x1.4a4f85db03ebbp-1,
- 0x1.4c679afccee39p-1, 0x1.4e7d811b75bb0p-1, 0x1.50913cc01686bp-1,
- 0x1.52a2d265bc5aap-1, 0x1.54b2467999497p-1, 0x1.56bf9d5b3f399p-1,
- 0x1.58cadb5cd7989p-1, 0x1.5ad404c359f2cp-1, 0x1.5cdb1dc6c1764p-1,
- 0x1.5ee02a9241675p-1, 0x1.60e32f44788d8p-1};
-
// Range reduction constants for logarithms.
// r(0) = 1, r(127) = 0.5
// r(k) = 2^-8 * ceil(2^8 * (1 - 2^-8) / (1 + k*2^-7))
diff --git a/libc/src/math/generic/common_constants.h b/libc/src/math/generic/common_constants.h
index 291816a..72b1d564 100644
--- a/libc/src/math/generic/common_constants.h
+++ b/libc/src/math/generic/common_constants.h
@@ -11,6 +11,7 @@
#include "src/__support/FPUtil/triple_double.h"
#include "src/__support/macros/config.h"
+#include "src/__support/math/acosh_float_constants.h"
#include "src/__support/math/exp_constants.h"
#include "src/__support/number_pair.h"
@@ -20,16 +21,10 @@ namespace LIBC_NAMESPACE_DECL {
// computed and stored as float precision constants.
extern const float ONE_OVER_F_FLOAT[128];
-// Lookup table for (1/f) where f = 1 + n*2^(-7), n = 0..127.
-extern const double ONE_OVER_F[128];
-
// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127,
// computed and stored as float precision constants.
extern const float LOG_F_FLOAT[128];
-// Lookup table for log(f) = log(1 + n*2^(-7)) where n = 0..127.
-extern const double LOG_F[128];
-
// Lookup table for range reduction constants r for logarithms.
extern const float R[128];
diff --git a/libc/src/math/generic/erff.cpp b/libc/src/math/generic/erff.cpp
index 44607a5..003b346 100644
--- a/libc/src/math/generic/erff.cpp
+++ b/libc/src/math/generic/erff.cpp
@@ -7,180 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/erff.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/common.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/erff.h"
namespace LIBC_NAMESPACE_DECL {
-// 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|], [|D...|],
-// [k/8, (k + 1)/8]);
-// for k = 0..31.
-constexpr double COEFFS[32][8] = {
- {0x1.20dd750429b6dp0, -0x1.812746b037753p-2, 0x1.ce2f219e8596ap-4,
- -0x1.b82cdacb78fdap-6, 0x1.56479297dfda5p-8, -0x1.8b3ac5455ef02p-11,
- -0x1.126fcac367e3bp-8, 0x1.2d0bdb3ba4984p-4},
- {0x1.20dd750429b6dp0, -0x1.812746b0379a8p-2, 0x1.ce2f21a03cf2ap-4,
- -0x1.b82ce30de083ep-6, 0x1.565bcad3eb60fp-8, -0x1.c02c66f659256p-11,
- 0x1.f92f673385229p-14, -0x1.def402648ae9p-17},
- {0x1.20dd750429b34p0, -0x1.812746b032dcep-2, 0x1.ce2f219d84aaep-4,
- -0x1.b82ce22dcf139p-6, 0x1.565b9efcd4af1p-8, -0x1.c021f1af414bcp-11,
- 0x1.f7c6d177eff82p-14, -0x1.c9e4410dcf865p-17},
- {0x1.20dd750426eabp0, -0x1.812746ae592c7p-2, 0x1.ce2f211525f14p-4,
- -0x1.b82ccc125e63fp-6, 0x1.56596f261cfd3p-8, -0x1.bfde1ff8eeecfp-11,
- 0x1.f31a9d15dc5d8p-14, -0x1.a5a4362844b3cp-17},
- {0x1.20dd75039c705p0, -0x1.812746777e74dp-2, 0x1.ce2f17af98a1bp-4,
- -0x1.b82be4b817cbep-6, 0x1.564bec2e2962ep-8, -0x1.bee86f9da3558p-11,
- 0x1.e9443689dc0ccp-14, -0x1.79c0f230805d8p-17},
- {0x1.20dd74f811211p0, -0x1.81274371a3e8fp-2, 0x1.ce2ec038262e5p-4,
- -0x1.b8265b82c5e1fp-6, 0x1.5615a2e239267p-8, -0x1.bc63ae023dcebp-11,
- 0x1.d87c2102f7e06p-14, -0x1.49584bea41d62p-17},
- {0x1.20dd746d063e3p0, -0x1.812729a8a950fp-2, 0x1.ce2cb0a2df232p-4,
- -0x1.b80eca1f51278p-6, 0x1.5572e26c46815p-8, -0x1.b715e5638b65ep-11,
- 0x1.bfbb195484968p-14, -0x1.177a565c15c52p-17},
- {0x1.20dd701b44486p0, -0x1.812691145f237p-2, 0x1.ce23a06b8cfd9p-4,
- -0x1.b7c1dc7245288p-6, 0x1.53e92f7f397ddp-8, -0x1.ad97cc4acf0b2p-11,
- 0x1.9f028b2b09b71p-14, -0x1.cdc4da08da8c1p-18},
- {0x1.20dd5715ac332p0, -0x1.8123e680bd0ebp-2, 0x1.ce0457aded691p-4,
- -0x1.b6f52d52bed4p-6, 0x1.50c291b84414cp-8, -0x1.9ea246b1ad4a9p-11,
- 0x1.77654674e0cap-14, -0x1.737c11a1bcebbp-18},
- {0x1.20dce6593e114p0, -0x1.811a59c02eadcp-2, 0x1.cdab53c7cd7d5p-4,
- -0x1.b526d2e321eedp-6, 0x1.4b1d32cd8b994p-8, -0x1.8963143ec0a1ep-11,
- 0x1.4ad5700e4db91p-14, -0x1.231e100e43ef2p-18},
- {0x1.20db48bfd5a62p0, -0x1.80fdd84f9e308p-2, 0x1.ccd340d462983p-4,
- -0x1.b196a2928768p-6, 0x1.4210c2c13a0f7p-8, -0x1.6dbdfb4ff71aep-11,
- 0x1.1bca2d17fbd71p-14, -0x1.bca36f90c7cf5p-19},
- {0x1.20d64b2f8f508p0, -0x1.80b4d4f19fa8bp-2, 0x1.cb088197262e3p-4,
- -0x1.ab51fd02e5b99p-6, 0x1.34e1e5e81a632p-8, -0x1.4c66377b502cep-11,
- 0x1.d9ad25066213cp-15, -0x1.4b0df7dd0cfa1p-19},
- {0x1.20c8fc1243576p0, -0x1.8010cb2009e27p-2, 0x1.c7a47e9299315p-4,
- -0x1.a155be5683654p-6, 0x1.233502694997bp-8, -0x1.26c94b7d813p-11,
- 0x1.8094f1de25fb9p-15, -0x1.e0e3d776c6eefp-20},
- {0x1.20a9bd1611bc1p0, -0x1.7ec7fbce83f9p-2, 0x1.c1d757d7317b7p-4,
- -0x1.92c160cd589fp-6, 0x1.0d307269cc5c2p-8, -0x1.fda5b0d2d1879p-12,
- 0x1.2fdd7b3b14a7fp-15, -0x1.54eed4a26af5ap-20},
- {0x1.20682834f943dp0, -0x1.7c73f747bf5a9p-2, 0x1.b8c2db4a9ffd1p-4,
- -0x1.7f0e4ffe989ecp-6, 0x1.e7061eae4166ep-9, -0x1.ad36e873fff2dp-12,
- 0x1.d39222396128ep-16, -0x1.d83dacec5ea6bp-21},
- {0x1.1feb8d12676d7p0, -0x1.7898347284afep-2, 0x1.aba3466b34451p-4,
- -0x1.663adc573e2f9p-6, 0x1.ae99fb17c3e08p-9, -0x1.602f950ad5535p-12,
- 0x1.5e9717490609dp-16, -0x1.3fca107bbc8d5p-21},
- {0x1.1f12fe3c536fap0, -0x1.72b1d1f22e6d3p-2, 0x1.99fc0eed4a896p-4,
- -0x1.48db0a87bd8c6p-6, 0x1.73e368895aa61p-9, -0x1.19b35d5301fc8p-12,
- 0x1.007987e4bb033p-16, -0x1.a7edcd4c2dc7p-22},
- {0x1.1db7b0df84d5dp0, -0x1.6a4e4a41cde02p-2, 0x1.83bbded16455dp-4,
- -0x1.2809b3b36977ep-6, 0x1.39c08bab44679p-9, -0x1.b7b45a70ed119p-13,
- 0x1.6e99b36410e7bp-17, -0x1.13619bb7ebc0cp-22},
- {0x1.1bb1c85c4a527p0, -0x1.5f23b99a249a3p-2, 0x1.694c91fa0d12cp-4,
- -0x1.053e1ce11c72dp-6, 0x1.02bf72c50ea78p-9, -0x1.4f478fb56cb02p-13,
- 0x1.005f80ecbe213p-17, -0x1.5f2446bde7f5bp-23},
- {0x1.18dec3bd51f9dp0, -0x1.5123f58346186p-2, 0x1.4b8a1ca536ab4p-4,
- -0x1.c4243015cc723p-7, 0x1.a1a8a01d351efp-10, -0x1.f466b34f1d86bp-14,
- 0x1.5f835eea0bf6ap-18, -0x1.b83165b939234p-24},
- {0x1.152804c3369f4p0, -0x1.4084cd4afd4bcp-2, 0x1.2ba2e836e47aap-4,
- -0x1.800f2dfc6904bp-7, 0x1.4a6daf0669c59p-10, -0x1.6e326ab872317p-14,
- 0x1.d9761a6a755a5p-19, -0x1.0fca33f9dd4b5p-24},
- {0x1.1087ad68356aap0, -0x1.2dbb044707459p-2, 0x1.0aea8ceaa0384p-4,
- -0x1.40b516d52b3d2p-7, 0x1.00c9e05f01d22p-10, -0x1.076afb0dc0ff7p-14,
- 0x1.39fadec400657p-19, -0x1.4b5761352e7e3p-25},
- {0x1.0b0a7a8ba4a22p0, -0x1.196990d22d4a1p-2, 0x1.d5551e6ac0c4dp-5,
- -0x1.07cce1770bd1ap-7, 0x1.890347b8848bfp-11, -0x1.757ec96750b6ap-15,
- 0x1.9b258a1e06bcep-20, -0x1.8fc6d22da7572p-26},
- {0x1.04ce2be70fb47p0, -0x1.0449e4b0b9cacp-2, 0x1.97f7424f4b0e7p-5,
- -0x1.ac825439c42f4p-8, 0x1.28f5f65426dfbp-11, -0x1.05b699a90f90fp-15,
- 0x1.0a888eecf4593p-20, -0x1.deace2b32bb31p-27},
- {0x1.fbf9fb0e11cc8p-1, -0x1.de2640856545ap-3, 0x1.5f5b1f47f851p-5,
- -0x1.588bc71eb41b9p-8, 0x1.bc6a0a772f56dp-12, -0x1.6b9fad1f1657ap-16,
- 0x1.573204ba66504p-21, -0x1.1d38065c94e44p-27},
- {0x1.ed8f18c99e031p-1, -0x1.b4cb6acd903b4p-3, 0x1.2c7f3dddd6fc1p-5,
- -0x1.13052067df4ep-8, 0x1.4a5027444082fp-12, -0x1.f672bab0e2554p-17,
- 0x1.b83c756348cc9p-22, -0x1.534f1a1079499p-28},
- {0x1.debd33044166dp-1, -0x1.8d7cd9053f7d8p-3, 0x1.ff9957fb3d6e7p-6,
- -0x1.b50be55de0f36p-9, 0x1.e92c8ec53a628p-13, -0x1.5a4b88d508007p-17,
- 0x1.1a27737559e26p-22, -0x1.942ae62cb2c14p-29},
- {0x1.cfdbf0386f3bdp-1, -0x1.68e33d93b0dc4p-3, 0x1.b2683d58f53dep-6,
- -0x1.5a9174e70d26fp-9, 0x1.69ddd326d49cdp-13, -0x1.dd8f397a8219cp-18,
- 0x1.6a755016ad4ddp-23, -0x1.e366e0139187dp-30},
- {0x1.c132adb8d7464p-1, -0x1.475a899f61b46p-3, 0x1.70a431397a77cp-6,
- -0x1.12e3d35beeee2p-9, 0x1.0c16b05738333p-13, -0x1.4a47f873e144ep-18,
- 0x1.d3d494c698c02p-24, -0x1.2302c59547fe5p-30},
- {0x1.b2f5fd05555e7p-1, -0x1.28feefbe03ec7p-3, 0x1.3923acbb3a676p-6,
- -0x1.b4ff793cd6358p-10, 0x1.8ea0eb8c913bcp-14, -0x1.cb31ec2baceb1p-19,
- 0x1.30011e7e80c04p-24, -0x1.617710635cb1dp-31},
- {0x1.a54853cd9593ep-1, -0x1.0dbdbaea4dc8ep-3, 0x1.0a93e2c20a0fdp-6,
- -0x1.5c969ff401ea8p-10, 0x1.29e0cc64fe627p-14, -0x1.4160d8e9d3c2ap-19,
- 0x1.8e7b67594624ap-25, -0x1.b1cf2c975b09bp-32},
- {0x1.983ceece09ff8p-1, -0x1.eacc78f7a2dp-4, 0x1.c74418410655fp-7,
- -0x1.1756a050e441ep-10, 0x1.bff3650f7f548p-15, -0x1.c56c0217d3adap-20,
- 0x1.07b4918d0b489p-25, -0x1.0d4be8c1c50f8p-32},
-};
-
-LLVM_LIBC_FUNCTION(float, erff, (float x)) {
- using FPBits = typename fputil::FPBits<float>;
- FPBits xbits(x);
-
- uint32_t x_u = xbits.uintval();
- uint32_t x_abs = x_u & 0x7fff'ffffU;
-
- if (LIBC_UNLIKELY(x_abs >= 0x4080'0000U)) {
- const float ONE[2] = {1.0f, -1.0f};
- const float SMALL[2] = {-0x1.0p-25f, 0x1.0p-25f};
-
- int sign = xbits.is_neg() ? 1 : 0;
-
- if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
- return (x_abs > 0x7f80'0000) ? x : ONE[sign];
- }
-
- return ONE[sign] + SMALL[sign];
- }
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Exceptional mask = common 0 bits of 2 exceptional values.
- constexpr uint32_t EXCEPT_MASK = 0x809a'6184U;
-
- if (LIBC_UNLIKELY((x_abs & EXCEPT_MASK) == 0)) {
- // Exceptional values
- if (LIBC_UNLIKELY(x_abs == 0x3f65'9229U)) // |x| = 0x1.cb2452p-1f
- return x < 0.0f ? fputil::round_result_slightly_down(-0x1.972ea8p-1f)
- : fputil::round_result_slightly_up(0x1.972ea8p-1f);
- if (LIBC_UNLIKELY(x_abs == 0x4004'1e6aU)) // |x| = 0x1.083cd4p+1f
- return x < 0.0f ? fputil::round_result_slightly_down(-0x1.fe3462p-1f)
- : fputil::round_result_slightly_up(0x1.fe3462p-1f);
- if (x_abs == 0U)
- return x;
- }
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // Polynomial approximation:
- // erf(x) ~ x * (c0 + c1 * x^2 + c2 * x^4 + ... + c7 * x^14)
- double xd = static_cast<double>(x);
- double xsq = xd * xd;
-
- const uint32_t EIGHT = 3 << FPBits::FRACTION_LEN;
- int idx = static_cast<int>(FPBits(x_abs + EIGHT).get_val());
-
- double x4 = xsq * xsq;
- double c0 = fputil::multiply_add(xsq, COEFFS[idx][1], COEFFS[idx][0]);
- double c1 = fputil::multiply_add(xsq, COEFFS[idx][3], COEFFS[idx][2]);
- double c2 = fputil::multiply_add(xsq, COEFFS[idx][5], COEFFS[idx][4]);
- double c3 = fputil::multiply_add(xsq, COEFFS[idx][7], COEFFS[idx][6]);
-
- double x8 = x4 * x4;
- double p0 = fputil::multiply_add(x4, c1, c0);
- double p1 = fputil::multiply_add(x4, c3, c2);
-
- return static_cast<float>(xd * fputil::multiply_add(x8, p1, p0));
-}
+LLVM_LIBC_FUNCTION(float, erff, (float x)) { return math::erff(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/explogxf.h b/libc/src/math/generic/explogxf.h
index be4328a..a2a6d60 100644
--- a/libc/src/math/generic/explogxf.h
+++ b/libc/src/math/generic/explogxf.h
@@ -13,6 +13,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/acoshf_utils.h"
#include "src/__support/math/exp10f_utils.h"
#include "src/__support/math/exp_utils.h"
@@ -163,41 +164,6 @@ LIBC_INLINE static float log_eval_f(float x) {
return result;
}
-// x should be positive, normal finite value
-LIBC_INLINE static double log_eval(double x) {
- // For x = 2^ex * (1 + mx)
- // log(x) = ex * log(2) + log(1 + mx)
- using FPB = fputil::FPBits<double>;
- FPB bs(x);
-
- double ex = static_cast<double>(bs.get_exponent());
-
- // p1 is the leading 7 bits of mx, i.e.
- // p1 * 2^(-7) <= m_x < (p1 + 1) * 2^(-7).
- int p1 = static_cast<int>(bs.get_mantissa() >> (FPB::FRACTION_LEN - 7));
-
- // Set bs to (1 + (mx - p1*2^(-7))
- bs.set_uintval(bs.uintval() & (FPB::FRACTION_MASK >> 7));
- bs.set_biased_exponent(FPB::EXP_BIAS);
- // dx = (mx - p1*2^(-7)) / (1 + p1*2^(-7)).
- double dx = (bs.get_val() - 1.0) * ONE_OVER_F[p1];
-
- // Minimax polynomial of log(1 + dx) generated by Sollya with:
- // > P = fpminimax(log(1 + x)/x, 6, [|D...|], [0, 2^-7]);
- const double COEFFS[6] = {-0x1.ffffffffffffcp-2, 0x1.5555555552ddep-2,
- -0x1.ffffffefe562dp-3, 0x1.9999817d3a50fp-3,
- -0x1.554317b3f67a5p-3, 0x1.1dc5c45e09c18p-3};
- double dx2 = dx * dx;
- double c1 = fputil::multiply_add(dx, COEFFS[1], COEFFS[0]);
- double c2 = fputil::multiply_add(dx, COEFFS[3], COEFFS[2]);
- double c3 = fputil::multiply_add(dx, COEFFS[5], COEFFS[4]);
-
- double p = fputil::polyeval(dx2, dx, c1, c2, c3);
- double result =
- fputil::multiply_add(ex, /*log(2)*/ 0x1.62e42fefa39efp-1, LOG_F[p1] + p);
- return result;
-}
-
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_MATH_GENERIC_EXPLOGXF_H
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/inv_trigf_utils.h b/libc/src/math/generic/inv_trigf_utils.h
deleted file mode 100644
index 8b47aba..0000000
--- a/libc/src/math/generic/inv_trigf_utils.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//===-- Single-precision general inverse trigonometric functions ----------===//
-//
-// 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_MATH_GENERIC_INV_TRIGF_UTILS_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_INV_TRIGF_UTILS_H
-
-#include "src/__support/FPUtil/PolyEval.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-
-namespace LIBC_NAMESPACE_DECL {
-
-// PI and PI / 2
-static constexpr double M_MATH_PI = 0x1.921fb54442d18p+1;
-static constexpr double M_MATH_PI_2 = 0x1.921fb54442d18p+0;
-
-extern double ATAN_COEFFS[17][9];
-
-// Look-up table for atan(k/16) with k = 0..16.
-static constexpr double ATAN_K_OVER_16[17] = {
- 0.0,
- 0x1.ff55bb72cfdeap-5,
- 0x1.fd5ba9aac2f6ep-4,
- 0x1.7b97b4bce5b02p-3,
- 0x1.f5b75f92c80ddp-3,
- 0x1.362773707ebccp-2,
- 0x1.6f61941e4def1p-2,
- 0x1.a64eec3cc23fdp-2,
- 0x1.dac670561bb4fp-2,
- 0x1.0657e94db30dp-1,
- 0x1.1e00babdefeb4p-1,
- 0x1.345f01cce37bbp-1,
- 0x1.4978fa3269ee1p-1,
- 0x1.5d58987169b18p-1,
- 0x1.700a7c5784634p-1,
- 0x1.819d0b7158a4dp-1,
- 0x1.921fb54442d18p-1,
-};
-
-// For |x| <= 1/32 and 0 <= i <= 16, return Q(x) such that:
-// Q(x) ~ (atan(x + i/16) - atan(i/16)) / x.
-LIBC_INLINE static double atan_eval(double x, unsigned i) {
- double x2 = x * x;
-
- double c0 = fputil::multiply_add(x, ATAN_COEFFS[i][2], ATAN_COEFFS[i][1]);
- double c1 = fputil::multiply_add(x, ATAN_COEFFS[i][4], ATAN_COEFFS[i][3]);
- double c2 = fputil::multiply_add(x, ATAN_COEFFS[i][6], ATAN_COEFFS[i][5]);
- double c3 = fputil::multiply_add(x, ATAN_COEFFS[i][8], ATAN_COEFFS[i][7]);
-
- double x4 = x2 * x2;
- double d1 = fputil::multiply_add(x2, c1, c0);
- double d2 = fputil::multiply_add(x2, c3, c2);
- double p = fputil::multiply_add(x4, d2, d1);
- return p;
-}
-
-// Evaluate atan without big lookup table.
-// atan(n/d) - atan(k/16) = atan((n/d - k/16) / (1 + (n/d) * (k/16)))
-// = atan((n - d * k/16)) / (d + n * k/16))
-// So we let q = (n - d * k/16) / (d + n * k/16),
-// and approximate with Taylor polynomial:
-// atan(q) ~ q - q^3/3 + q^5/5 - q^7/7 + q^9/9
-LIBC_INLINE static double atan_eval_no_table(double num, double den,
- double k_over_16) {
- double num_r = fputil::multiply_add(den, -k_over_16, num);
- double den_r = fputil::multiply_add(num, k_over_16, den);
- double q = num_r / den_r;
-
- constexpr double ATAN_TAYLOR[] = {
- -0x1.5555555555555p-2,
- 0x1.999999999999ap-3,
- -0x1.2492492492492p-3,
- 0x1.c71c71c71c71cp-4,
- };
- double q2 = q * q;
- double q3 = q2 * q;
- double q4 = q2 * q2;
- double c0 = fputil::multiply_add(q2, ATAN_TAYLOR[1], ATAN_TAYLOR[0]);
- double c1 = fputil::multiply_add(q2, ATAN_TAYLOR[3], ATAN_TAYLOR[2]);
- double d = fputil::multiply_add(q4, c1, c0);
- return fputil::multiply_add(q3, d, q);
-}
-
-// > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|],
-// [|1, D...|], [0, 0.5]);
-static constexpr double ASIN_COEFFS[10] = {
- 0x1.5555555540fa1p-3, 0x1.333333512edc2p-4, 0x1.6db6cc1541b31p-5,
- 0x1.f1caff324770ep-6, 0x1.6e43899f5f4f4p-6, 0x1.1f847cf652577p-6,
- 0x1.9b60f47f87146p-7, 0x1.259e2634c494fp-6, -0x1.df946fa875ddp-8,
- 0x1.02311ecf99c28p-5};
-
-// Evaluate P(x^2) - 1, where P(x^2) ~ asin(x)/x
-LIBC_INLINE static double asin_eval(double xsq) {
- double x4 = xsq * xsq;
- double r1 = fputil::polyeval(x4, ASIN_COEFFS[0], ASIN_COEFFS[2],
- ASIN_COEFFS[4], ASIN_COEFFS[6], ASIN_COEFFS[8]);
- double r2 = fputil::polyeval(x4, ASIN_COEFFS[1], ASIN_COEFFS[3],
- ASIN_COEFFS[5], ASIN_COEFFS[7], ASIN_COEFFS[9]);
- return fputil::multiply_add(xsq, r2, r1);
-}
-
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_INV_TRIGF_UTILS_H
diff --git a/libc/src/math/generic/log1pf.cpp b/libc/src/math/generic/log1pf.cpp
index 7f61429..16b1b34 100644
--- a/libc/src/math/generic/log1pf.cpp
+++ b/libc/src/math/generic/log1pf.cpp
@@ -37,6 +37,7 @@ namespace internal {
// We don't need to treat denormal and 0
LIBC_INLINE float log(double x) {
+ using namespace acoshf_internal;
constexpr double LOG_2 = 0x1.62e42fefa39efp-1;
using FPBits = typename fputil::FPBits<double>;
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/baremetal/CMakeLists.txt b/libc/src/stdio/baremetal/CMakeLists.txt
index e879230..548938f 100644
--- a/libc/src/stdio/baremetal/CMakeLists.txt
+++ b/libc/src/stdio/baremetal/CMakeLists.txt
@@ -72,6 +72,7 @@ add_entrypoint_object(
../scanf.h
DEPENDS
.scanf_internal
+ libc.include.inttypes
libc.src.stdio.scanf_core.scanf_main
libc.src.__support.arg_list
libc.src.__support.OSUtil.osutil
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/stdio/scanf_core/CMakeLists.txt b/libc/src/stdio/scanf_core/CMakeLists.txt
index dee125c..561180c 100644
--- a/libc/src/stdio/scanf_core/CMakeLists.txt
+++ b/libc/src/stdio/scanf_core/CMakeLists.txt
@@ -35,6 +35,7 @@ add_header_library(
core_structs.h
DEPENDS
.scanf_config
+ libc.include.inttypes
libc.src.__support.CPP.string_view
libc.src.__support.CPP.bitset
libc.src.__support.FPUtil.fp_bits
@@ -97,6 +98,7 @@ add_header_library(
DEPENDS
.reader
.core_structs
+ libc.include.inttypes
libc.src.__support.common
libc.src.__support.ctype_utils
libc.src.__support.CPP.bitset
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 4f56263..80e5783 100644
--- a/libc/src/string/string_utils.h
+++ b/libc/src/string/string_utils.h
@@ -15,6 +15,7 @@
#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
diff --git a/libc/src/sys/epoll/linux/epoll_create.cpp b/libc/src/sys/epoll/linux/epoll_create.cpp
index 2e44e88..dcd082b 100644
--- a/libc/src/sys/epoll/linux/epoll_create.cpp
+++ b/libc/src/sys/epoll/linux/epoll_create.cpp
@@ -20,6 +20,11 @@ LLVM_LIBC_FUNCTION(int, epoll_create, ([[maybe_unused]] int size)) {
#ifdef SYS_epoll_create
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_epoll_create, size);
#elif defined(SYS_epoll_create1)
+ if (size == 0) {
+ libc_errno = EINVAL;
+ return -1;
+ }
+
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_epoll_create1, 0);
#else
#error \
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/sys/time/linux/setitimer.cpp b/libc/src/sys/time/linux/setitimer.cpp
index 1de0d43..fb16358 100644
--- a/libc/src/sys/time/linux/setitimer.cpp
+++ b/libc/src/sys/time/linux/setitimer.cpp
@@ -22,9 +22,9 @@ LLVM_LIBC_FUNCTION(int, setitimer,
// There is no SYS_setitimer_time64 call, so we can't use time_t directly,
// and need to convert it to long first.
long new_value32[4] = {static_cast<long>(new_value->it_interval.tv_sec),
- new_value->it_interval.tv_usec,
+ static_cast<long>(new_value->it_interval.tv_usec),
static_cast<long>(new_value->it_value.tv_sec),
- new_value->it_value.tv_usec};
+ static_cast<long>(new_value->it_value.tv_usec)};
long old_value32[4];
ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which, new_value32,
diff --git a/libc/src/sys/time/linux/utimes.cpp b/libc/src/sys/time/linux/utimes.cpp
index ed37b42..9c00ce9 100644
--- a/libc/src/sys/time/linux/utimes.cpp
+++ b/libc/src/sys/time/linux/utimes.cpp
@@ -59,8 +59,10 @@ LLVM_LIBC_FUNCTION(int, utimes,
ts[1].tv_sec = times[1].tv_sec;
// convert u-seconds to nanoseconds
- ts[0].tv_nsec = times[0].tv_usec * 1000;
- ts[1].tv_nsec = times[1].tv_usec * 1000;
+ ts[0].tv_nsec =
+ static_cast<decltype(ts[0].tv_nsec)>(times[0].tv_usec * 1000);
+ ts[1].tv_nsec =
+ static_cast<decltype(ts[1].tv_nsec)>(times[1].tv_usec * 1000);
ts_ptr = ts;
}
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 7ace1a6..49f4a1b 100644
--- a/libc/src/wchar/CMakeLists.txt
+++ b/libc/src/wchar/CMakeLists.txt
@@ -1,3 +1,13 @@
+add_header_library(
+ wchar_utils
+ HDRS
+ wchar_utils.h
+ DEPENDS
+ libc.hdr.types.size_t
+ libc.hdr.types.wchar_t
+ libc.src.__support.common
+)
+
add_entrypoint_object(
wcslen
SRCS
@@ -127,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
@@ -160,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
@@ -215,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
@@ -255,6 +365,8 @@ add_entrypoint_object(
DEPENDS
libc.hdr.wchar_macros
libc.hdr.types.size_t
+ libc.src.wchar.wchar_utils
+ libc.src.__support.macros.null_check
)
add_entrypoint_object(
@@ -266,6 +378,8 @@ add_entrypoint_object(
DEPENDS
libc.hdr.wchar_macros
libc.hdr.types.size_t
+ libc.src.wchar.wchar_utils
+ libc.src.__support.macros.null_check
)
add_entrypoint_object(
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/mbtowc.cpp b/libc/src/wchar/mbtowc.cpp
index eae39ba..6d099d4 100644
--- a/libc/src/wchar/mbtowc.cpp
+++ b/libc/src/wchar/mbtowc.cpp
@@ -25,10 +25,7 @@ LLVM_LIBC_FUNCTION(int, mbtowc,
if (s == nullptr)
return 0;
internal::mbstate internal_mbstate;
- // temp ptr to use if pwc is nullptr
- wchar_t buf[1];
- auto ret =
- internal::mbrtowc(pwc == nullptr ? buf : pwc, s, n, &internal_mbstate);
+ auto ret = internal::mbrtowc(pwc, s, n, &internal_mbstate);
if (!ret.has_value() || static_cast<int>(ret.value()) == -2) {
// Encoding failure
libc_errno = EILSEQ;
diff --git a/libc/src/wchar/wchar_utils.h b/libc/src/wchar/wchar_utils.h
new file mode 100644
index 0000000..55a3cee
--- /dev/null
+++ b/libc/src/wchar/wchar_utils.h
@@ -0,0 +1,42 @@
+//===-- wchar utils ---------------------------------------------*- 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_WCHAR_WCHAR_UTILS_H
+#define LLVM_LIBC_SRC_WCHAR_WCHAR_UTILS_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+LIBC_INLINE static const wchar_t *wcschr(const wchar_t *s, wchar_t c) {
+ for (; *s && *s != c; ++s)
+ ;
+ return (*s == c) ? s : nullptr;
+}
+
+// bool should be true for wcscspn for complimentary span
+// should be false for wcsspn since we want it to span
+LIBC_INLINE static size_t wcsspn(const wchar_t *s1, const wchar_t *s2,
+ bool not_match_set) {
+ size_t i = 0;
+ for (; s1[i]; ++i) {
+ bool in_set = internal::wcschr(s2, s1[i]);
+ if (in_set == not_match_set)
+ return i;
+ }
+ return i;
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_WCHAR_WCHAR_UTILS_H
diff --git a/libc/src/wchar/wcschr.cpp b/libc/src/wchar/wcschr.cpp
index defc2ce..8ac4916 100644
--- a/libc/src/wchar/wcschr.cpp
+++ b/libc/src/wchar/wcschr.cpp
@@ -11,15 +11,14 @@
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+#include "wchar_utils.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(const wchar_t *, wcschr, (const wchar_t *s, wchar_t c)) {
- for (; *s && *s != c; ++s)
- ;
- if (*s == c)
- return s;
- return nullptr;
+ LIBC_CRASH_ON_NULLPTR(s);
+ return internal::wcschr(s, c);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wcscspn.cpp b/libc/src/wchar/wcscspn.cpp
index 8869d84..34f3451 100644
--- a/libc/src/wchar/wcscspn.cpp
+++ b/libc/src/wchar/wcscspn.cpp
@@ -12,23 +12,15 @@
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+#include "wchar_utils.h"
namespace LIBC_NAMESPACE_DECL {
-bool check(wchar_t c, const wchar_t *s2) {
- for (int n = 0; s2[n]; ++n) {
- if (s2[n] == c)
- return false;
- }
- return true;
-}
LLVM_LIBC_FUNCTION(size_t, wcscspn, (const wchar_t *s1, const wchar_t *s2)) {
- size_t i = 0;
- for (; s1[i]; ++i) {
- if (!check(s1[i], s2))
- return i;
- }
- return i;
+ LIBC_CRASH_ON_NULLPTR(s1);
+ LIBC_CRASH_ON_NULLPTR(s2);
+ return internal::wcsspn(s1, s2, /*not_match_set=*/true);
}
} // namespace LIBC_NAMESPACE_DECL
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/wcspbrk.cpp b/libc/src/wchar/wcspbrk.cpp
index a00ba99..5d86a49 100644
--- a/libc/src/wchar/wcspbrk.cpp
+++ b/libc/src/wchar/wcspbrk.cpp
@@ -11,17 +11,10 @@
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"
#include "src/__support/macros/null_check.h"
+#include "wchar_utils.h"
namespace LIBC_NAMESPACE_DECL {
-bool contains_char(const wchar_t *str, wchar_t target) {
- for (; *str != L'\0'; str++)
- if (*str == target)
- return true;
-
- return false;
-}
-
LLVM_LIBC_FUNCTION(const wchar_t *, wcspbrk,
(const wchar_t *src, const wchar_t *breakset)) {
LIBC_CRASH_ON_NULLPTR(src);
@@ -29,7 +22,7 @@ LLVM_LIBC_FUNCTION(const wchar_t *, wcspbrk,
// currently O(n * m), can be further optimized to O(n + m) with a hash set
for (int src_idx = 0; src[src_idx] != 0; src_idx++)
- if (contains_char(breakset, src[src_idx]))
+ if (internal::wcschr(breakset, src[src_idx]))
return src + src_idx;
return nullptr;
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/wcsspn.cpp b/libc/src/wchar/wcsspn.cpp
index 23de381..ae2cf5a 100644
--- a/libc/src/wchar/wcsspn.cpp
+++ b/libc/src/wchar/wcsspn.cpp
@@ -12,23 +12,15 @@
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+#include "wchar_utils.h"
namespace LIBC_NAMESPACE_DECL {
-bool check(wchar_t c, const wchar_t *s2) {
- for (int n = 0; s2[n]; ++n) {
- if (s2[n] == c)
- return true;
- }
- return false;
-}
LLVM_LIBC_FUNCTION(size_t, wcsspn, (const wchar_t *s1, const wchar_t *s2)) {
- size_t i = 0;
- for (; s1[i]; ++i) {
- if (!check(s1[i], s2))
- return i;
- }
- return i;
+ LIBC_CRASH_ON_NULLPTR(s1);
+ LIBC_CRASH_ON_NULLPTR(s2);
+ return internal::wcsspn(s1, s2, /*not_match_set=*/false);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wcstok.cpp b/libc/src/wchar/wcstok.cpp
index 291efc1..ed4f0aa 100644
--- a/libc/src/wchar/wcstok.cpp
+++ b/libc/src/wchar/wcstok.cpp
@@ -10,18 +10,12 @@
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"
+#include "wchar_utils.h"
namespace LIBC_NAMESPACE_DECL {
-bool isADelimeter(wchar_t wc, const wchar_t *delimiters) {
- for (const wchar_t *delim_ptr = delimiters; *delim_ptr != L'\0'; ++delim_ptr)
- if (wc == *delim_ptr)
- return true;
- return false;
-}
-
LLVM_LIBC_FUNCTION(wchar_t *, wcstok,
- (wchar_t *__restrict str, const wchar_t *__restrict delim,
+ (wchar_t *__restrict str, const wchar_t *__restrict delims,
wchar_t **__restrict context)) {
if (str == nullptr) {
if (*context == nullptr)
@@ -30,14 +24,13 @@ LLVM_LIBC_FUNCTION(wchar_t *, wcstok,
str = *context;
}
- wchar_t *tok_start, *tok_end;
- for (tok_start = str; *tok_start != L'\0' && isADelimeter(*tok_start, delim);
- ++tok_start)
- ;
+ wchar_t *tok_start = str;
+ while (*tok_start != L'\0' && internal::wcschr(delims, *tok_start))
+ ++tok_start;
- for (tok_end = tok_start; *tok_end != L'\0' && !isADelimeter(*tok_end, delim);
- ++tok_end)
- ;
+ wchar_t *tok_end = tok_start;
+ while (*tok_end != L'\0' && !internal::wcschr(delims, *tok_end))
+ ++tok_end;
if (*tok_end != L'\0') {
*tok_end = L'\0';
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
diff --git a/libc/startup/baremetal/CMakeLists.txt b/libc/startup/baremetal/CMakeLists.txt
index 4faced9..276fe33 100644
--- a/libc/startup/baremetal/CMakeLists.txt
+++ b/libc/startup/baremetal/CMakeLists.txt
@@ -2,10 +2,16 @@ add_entrypoint_object(
init
SRCS
init.cpp
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.common
)
add_entrypoint_object(
fini
SRCS
fini.cpp
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.common
)
diff --git a/libc/startup/baremetal/fini.cpp b/libc/startup/baremetal/fini.cpp
index 263d7192..64af842 100644
--- a/libc/startup/baremetal/fini.cpp
+++ b/libc/startup/baremetal/fini.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
#include <stddef.h>
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/startup/baremetal/init.cpp b/libc/startup/baremetal/init.cpp
index ce38701..995609c 100644
--- a/libc/startup/baremetal/init.cpp
+++ b/libc/startup/baremetal/init.cpp
@@ -6,9 +6,9 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
#include <stddef.h>
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/startup/linux/CMakeLists.txt b/libc/startup/linux/CMakeLists.txt
index eaa724e..7af1819 100644
--- a/libc/startup/linux/CMakeLists.txt
+++ b/libc/startup/linux/CMakeLists.txt
@@ -96,6 +96,7 @@ add_object_library(
do_start.h
DEPENDS
libc.config.app_h
+ libc.hdr.stdint_proxy
libc.include.sys_mman
libc.include.sys_syscall
libc.include.llvm-libc-macros.link_macros
diff --git a/libc/startup/linux/do_start.cpp b/libc/startup/linux/do_start.cpp
index ff104c7..94c4ec7 100644
--- a/libc/startup/linux/do_start.cpp
+++ b/libc/startup/linux/do_start.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "startup/linux/do_start.h"
#include "config/linux/app.h"
+#include "hdr/stdint_proxy.h"
#include "include/llvm-libc-macros/link-macros.h"
#include "src/__support/OSUtil/syscall.h"
#include "src/__support/macros/config.h"
@@ -17,7 +18,6 @@
#include <linux/auxvec.h>
#include <linux/elf.h>
-#include <stdint.h>
#include <sys/mman.h>
#include <sys/syscall.h>
diff --git a/libc/test/CMakeLists.txt b/libc/test/CMakeLists.txt
index 1a0780f..011ad6ae 100644
--- a/libc/test/CMakeLists.txt
+++ b/libc/test/CMakeLists.txt
@@ -20,6 +20,7 @@ endif()
add_subdirectory(src)
add_subdirectory(utils)
+add_subdirectory(shared)
if(NOT LLVM_LIBC_FULL_BUILD)
return()
diff --git a/libc/test/IntegrationTest/CMakeLists.txt b/libc/test/IntegrationTest/CMakeLists.txt
index 4a99940..3afe354 100644
--- a/libc/test/IntegrationTest/CMakeLists.txt
+++ b/libc/test/IntegrationTest/CMakeLists.txt
@@ -11,6 +11,7 @@ add_object_library(
HDRS
test.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.OSUtil.osutil
${arch_specific_deps}
)
diff --git a/libc/test/IntegrationTest/test.cpp b/libc/test/IntegrationTest/test.cpp
index 871bdf0..8baf746 100644
--- a/libc/test/IntegrationTest/test.cpp
+++ b/libc/test/IntegrationTest/test.cpp
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include <stddef.h>
-#include <stdint.h>
#ifdef LIBC_TARGET_ARCH_IS_AARCH64
#include "src/sys/auxv/getauxval.h"
diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt
index c32809d..d92ab6f 100644
--- a/libc/test/UnitTest/CMakeLists.txt
+++ b/libc/test/UnitTest/CMakeLists.txt
@@ -69,6 +69,7 @@ add_unittest_framework_library(
Test.h
TestLogger.h
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.big_int
libc.src.__support.c_string
libc.src.__support.CPP.string
@@ -91,12 +92,16 @@ add_unittest_framework_library(
${libc_death_test_srcs}
HDRS
ExecuteFunction.h
+ DEPENDS
+ libc.hdr.stdint_proxy
)
add_unittest_framework_library(
LibcHermeticTestSupport
SRCS
HermeticTestUtils.cpp
+ DEPENDS
+ libc.hdr.stdint_proxy
)
add_header_library(
@@ -160,6 +165,7 @@ add_unittest_framework_library(
PrintfMatcher.h
DEPENDS
LibcTest
+ libc.hdr.stdint_proxy
libc.src.__support.FPUtil.fp_bits
libc.src.stdio.printf_core.core_structs
libc.test.UnitTest.string_utils
@@ -173,6 +179,7 @@ add_unittest_framework_library(
ScanfMatcher.h
DEPENDS
LibcTest
+ libc.hdr.stdint_proxy
libc.src.__support.FPUtil.fp_bits
libc.src.stdio.scanf_core.core_structs
libc.test.UnitTest.string_utils
diff --git a/libc/test/UnitTest/ExecuteFunction.h b/libc/test/UnitTest/ExecuteFunction.h
index 93ab6e9..5844fd5 100644
--- a/libc/test/UnitTest/ExecuteFunction.h
+++ b/libc/test/UnitTest/ExecuteFunction.h
@@ -9,9 +9,9 @@
#ifndef LLVM_LIBC_TEST_UNITTEST_EXECUTEFUNCTION_H
#define LLVM_LIBC_TEST_UNITTEST_EXECUTEFUNCTION_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/limits.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace testutils {
diff --git a/libc/test/UnitTest/HermeticTestUtils.cpp b/libc/test/UnitTest/HermeticTestUtils.cpp
index a9494af..f34a73f 100644
--- a/libc/test/UnitTest/HermeticTestUtils.cpp
+++ b/libc/test/UnitTest/HermeticTestUtils.cpp
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include <stddef.h>
-#include <stdint.h>
#ifdef LIBC_TARGET_ARCH_IS_AARCH64
#include "src/sys/auxv/getauxval.h"
diff --git a/libc/test/UnitTest/PrintfMatcher.cpp b/libc/test/UnitTest/PrintfMatcher.cpp
index 4fdcbf1..2ea1bbf 100644
--- a/libc/test/UnitTest/PrintfMatcher.cpp
+++ b/libc/test/UnitTest/PrintfMatcher.cpp
@@ -8,6 +8,7 @@
#include "PrintfMatcher.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/macros/config.h"
#include "src/stdio/printf_core/core_structs.h"
@@ -15,8 +16,6 @@
#include "test/UnitTest/StringUtils.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace testing {
diff --git a/libc/test/UnitTest/RoundingModeUtils.h b/libc/test/UnitTest/RoundingModeUtils.h
index cdc3699..5f23a87 100644
--- a/libc/test/UnitTest/RoundingModeUtils.h
+++ b/libc/test/UnitTest/RoundingModeUtils.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_TEST_UNITTEST_ROUNDINGMODEUTILS_H
#define LLVM_LIBC_TEST_UNITTEST_ROUNDINGMODEUTILS_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
diff --git a/libc/test/UnitTest/ScanfMatcher.cpp b/libc/test/UnitTest/ScanfMatcher.cpp
index 3e9f2a5..d47ad71 100644
--- a/libc/test/UnitTest/ScanfMatcher.cpp
+++ b/libc/test/UnitTest/ScanfMatcher.cpp
@@ -8,6 +8,7 @@
#include "ScanfMatcher.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/macros/config.h"
#include "src/stdio/scanf_core/core_structs.h"
@@ -15,8 +16,6 @@
#include "test/UnitTest/StringUtils.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace testing {
diff --git a/libc/test/UnitTest/Test.h b/libc/test/UnitTest/Test.h
index a5a2a3c..e70fc51 100644
--- a/libc/test/UnitTest/Test.h
+++ b/libc/test/UnitTest/Test.h
@@ -52,4 +52,13 @@
libc_errno = 0; \
} while (0)
+// Some macro utility to append file names with LIBC_TEST macro's value to be
+// used in stdio tests.
+#undef STR
+#undef EVAL_THEN_STR
+#define STR(X) #X
+#define EVAL_THEN_STR(X) STR(X)
+
+#define APPEND_LIBC_TEST(X) X "." EVAL_THEN_STR(LIBC_TEST)
+
#endif // LLVM_LIBC_TEST_UNITTEST_TEST_H
diff --git a/libc/test/UnitTest/TestLogger.cpp b/libc/test/UnitTest/TestLogger.cpp
index e1df798..3d95d48 100644
--- a/libc/test/UnitTest/TestLogger.cpp
+++ b/libc/test/UnitTest/TestLogger.cpp
@@ -1,14 +1,13 @@
#include "test/UnitTest/TestLogger.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/string.h"
#include "src/__support/CPP/string_view.h"
-#include "src/__support/OSUtil/io.h" // write_to_stderr
-#include "src/__support/big_int.h" // is_big_int
+#include "src/__support/OSUtil/io.h" // write_to_stderr
+#include "src/__support/big_int.h" // is_big_int
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "src/__support/uint128.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace testing {
diff --git a/libc/test/integration/src/pthread/CMakeLists.txt b/libc/test/integration/src/pthread/CMakeLists.txt
index 208ba3f..0bdd99c 100644
--- a/libc/test/integration/src/pthread/CMakeLists.txt
+++ b/libc/test/integration/src/pthread/CMakeLists.txt
@@ -7,6 +7,7 @@ add_integration_test(
SRCS
pthread_mutex_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.pthread
libc.src.errno.errno
libc.src.pthread.pthread_mutex_destroy
@@ -84,6 +85,7 @@ add_integration_test(
SRCS
pthread_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.pthread
libc.src.pthread.pthread_create
libc.src.pthread.pthread_join
@@ -96,6 +98,7 @@ add_integration_test(
SRCS
pthread_equal_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.pthread
libc.src.errno.errno
libc.src.pthread.pthread_mutex_destroy
@@ -115,6 +118,7 @@ add_integration_test(
SRCS
pthread_name_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.pthread
libc.src.errno.errno
libc.src.pthread.pthread_create
@@ -165,6 +169,7 @@ add_integration_test(
SRCS
pthread_once_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.pthread
libc.src.pthread.pthread_once
libc.src.pthread.pthread_mutex_destroy
diff --git a/libc/test/integration/src/pthread/pthread_equal_test.cpp b/libc/test/integration/src/pthread/pthread_equal_test.cpp
index 82f5a49..01569798 100644
--- a/libc/test/integration/src/pthread/pthread_equal_test.cpp
+++ b/libc/test/integration/src/pthread/pthread_equal_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h" // uintptr_t
#include "src/pthread/pthread_create.h"
#include "src/pthread/pthread_equal.h"
#include "src/pthread/pthread_join.h"
@@ -14,11 +15,9 @@
#include "src/pthread/pthread_mutex_lock.h"
#include "src/pthread/pthread_mutex_unlock.h"
#include "src/pthread/pthread_self.h"
-
#include "test/IntegrationTest/test.h"
#include <pthread.h>
-#include <stdint.h> // uintptr_t
pthread_t child_thread;
pthread_mutex_t mutex;
diff --git a/libc/test/integration/src/pthread/pthread_mutex_test.cpp b/libc/test/integration/src/pthread/pthread_mutex_test.cpp
index 137daed..d41ad6d 100644
--- a/libc/test/integration/src/pthread/pthread_mutex_test.cpp
+++ b/libc/test/integration/src/pthread/pthread_mutex_test.cpp
@@ -6,18 +6,16 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h" // uintptr_t
+#include "src/pthread/pthread_create.h"
+#include "src/pthread/pthread_join.h"
#include "src/pthread/pthread_mutex_destroy.h"
#include "src/pthread/pthread_mutex_init.h"
#include "src/pthread/pthread_mutex_lock.h"
#include "src/pthread/pthread_mutex_unlock.h"
-
-#include "src/pthread/pthread_create.h"
-#include "src/pthread/pthread_join.h"
-
#include "test/IntegrationTest/test.h"
#include <pthread.h>
-#include <stdint.h> // uintptr_t
constexpr int START = 0;
constexpr int MAX = 10000;
diff --git a/libc/test/integration/src/pthread/pthread_name_test.cpp b/libc/test/integration/src/pthread/pthread_name_test.cpp
index 35dd3b1..343a223 100644
--- a/libc/test/integration/src/pthread/pthread_name_test.cpp
+++ b/libc/test/integration/src/pthread/pthread_name_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h" // uintptr_t
#include "src/__support/CPP/string_view.h"
#include "src/__support/libc_errno.h"
#include "src/pthread/pthread_create.h"
@@ -17,11 +18,9 @@
#include "src/pthread/pthread_mutex_unlock.h"
#include "src/pthread/pthread_self.h"
#include "src/pthread/pthread_setname_np.h"
-
#include "test/IntegrationTest/test.h"
#include <pthread.h>
-#include <stdint.h> // uintptr_t
using string_view = LIBC_NAMESPACE::cpp::string_view;
diff --git a/libc/test/integration/src/pthread/pthread_once_test.cpp b/libc/test/integration/src/pthread/pthread_once_test.cpp
index 8e0f234..68aadf3 100644
--- a/libc/test/integration/src/pthread/pthread_once_test.cpp
+++ b/libc/test/integration/src/pthread/pthread_once_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h" // uintptr_t
#include "src/__support/CPP/atomic.h"
#include "src/pthread/pthread_create.h"
#include "src/pthread/pthread_join.h"
@@ -14,11 +15,9 @@
#include "src/pthread/pthread_mutex_lock.h"
#include "src/pthread/pthread_mutex_unlock.h"
#include "src/pthread/pthread_once.h"
-
#include "test/IntegrationTest/test.h"
#include <pthread.h>
-#include <stdint.h> // uintptr_t
static constexpr unsigned int NUM_THREADS = 5;
static LIBC_NAMESPACE::cpp::Atomic<unsigned int> thread_count;
diff --git a/libc/test/integration/src/pthread/pthread_test.cpp b/libc/test/integration/src/pthread/pthread_test.cpp
index 3565a7c..4d635fd 100644
--- a/libc/test/integration/src/pthread/pthread_test.cpp
+++ b/libc/test/integration/src/pthread/pthread_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h" // uintptr_t
#include "src/pthread/pthread_create.h"
#include "src/pthread/pthread_join.h"
#include "test/IntegrationTest/test.h"
#include <pthread.h>
-#include <stdint.h> // uintptr_t
static constexpr int thread_count = 1000;
static int counter = 0;
diff --git a/libc/test/integration/src/spawn/CMakeLists.txt b/libc/test/integration/src/spawn/CMakeLists.txt
index caed59f..f3a7327 100644
--- a/libc/test/integration/src/spawn/CMakeLists.txt
+++ b/libc/test/integration/src/spawn/CMakeLists.txt
@@ -29,6 +29,7 @@ add_integration_test(
DEPENDS
libc_posix_spawn_test_binary
libc.test.integration.src.spawn.test_binary_properties
+ libc.hdr.stdint_proxy
libc.include.fcntl
libc.include.signal
libc.include.spawn
diff --git a/libc/test/integration/src/spawn/posix_spawn_test.cpp b/libc/test/integration/src/spawn/posix_spawn_test.cpp
index 104096c..3c8cc73 100644
--- a/libc/test/integration/src/spawn/posix_spawn_test.cpp
+++ b/libc/test/integration/src/spawn/posix_spawn_test.cpp
@@ -8,6 +8,7 @@
#include "test_binary_properties.h"
+#include "hdr/stdint_proxy.h"
#include "src/spawn/posix_spawn.h"
#include "src/spawn/posix_spawn_file_actions_addopen.h"
#include "src/spawn/posix_spawn_file_actions_destroy.h"
@@ -18,7 +19,6 @@
#include <fcntl.h>
#include <spawn.h>
#include <stddef.h>
-#include <stdint.h>
#include <sys/wait.h>
char arg0[] = "libc_posix_spawn_test_binary";
diff --git a/libc/test/integration/src/stdlib/gpu/malloc_stress.cpp b/libc/test/integration/src/stdlib/gpu/malloc_stress.cpp
index 77479f8..4c540a8 100644
--- a/libc/test/integration/src/stdlib/gpu/malloc_stress.cpp
+++ b/libc/test/integration/src/stdlib/gpu/malloc_stress.cpp
@@ -14,6 +14,20 @@
using namespace LIBC_NAMESPACE;
+static inline uint32_t entropy() {
+ return (static_cast<uint32_t>(gpu::processor_clock()) ^
+ (gpu::get_thread_id_x() * 0x632be59b) ^
+ (gpu::get_block_id_x() * 0x85157af5)) *
+ 0x9e3779bb;
+}
+
+static inline uint32_t xorshift32(uint32_t &state) {
+ state ^= state << 13;
+ state ^= state >> 17;
+ state ^= state << 5;
+ return state * 0x9e3779bb;
+}
+
static inline void use(uint8_t *ptr, uint32_t size) {
EXPECT_NE(ptr, nullptr);
for (int i = 0; i < size; ++i)
@@ -34,5 +48,19 @@ TEST_MAIN(int, char **, char **) {
for (int i = 0; i < 256; ++i)
free(ptrs[i]);
+
+ uint32_t state = entropy();
+ for (int i = 0; i < 1024; ++i) {
+ if (xorshift32(state) % 2) {
+ uint64_t size = xorshift32(state) % 256 + 16;
+ uint64_t *ptr = reinterpret_cast<uint64_t *>(malloc(size));
+ *ptr = gpu::get_thread_id();
+
+ EXPECT_EQ(*ptr, gpu::get_thread_id());
+ ASSERT_TRUE(ptr);
+ ASSERT_TRUE(__builtin_is_aligned(ptr, 16));
+ free(ptr);
+ }
+ }
return 0;
}
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
new file mode 100644
index 0000000..77f3617
--- /dev/null
+++ b/libc/test/shared/CMakeLists.txt
@@ -0,0 +1,33 @@
+add_custom_target(libc-shared-tests)
+
+add_fp_unittest(
+ shared_math_test
+ SUITE
+ libc-shared-tests
+ SRCS
+ shared_math_test.cpp
+ DEPENDS
+ libc.src.__support.math.acos
+ libc.src.__support.math.acosf
+ libc.src.__support.math.acosf16
+ libc.src.__support.math.acoshf
+ libc.src.__support.math.acoshf16
+ libc.src.__support.math.acospif16
+ libc.src.__support.math.asin
+ libc.src.__support.math.asinf
+ libc.src.__support.math.asinf16
+ libc.src.__support.math.asinhf
+ libc.src.__support.math.erff
+ libc.src.__support.math.exp
+ libc.src.__support.math.exp10
+ libc.src.__support.math.exp10f
+ libc.src.__support.math.exp10f16
+ libc.src.__support.math.expf
+ libc.src.__support.math.expf16
+ libc.src.__support.math.frexpf
+ libc.src.__support.math.frexpf128
+ libc.src.__support.math.frexpf16
+ libc.src.__support.math.ldexpf
+ libc.src.__support.math.ldexpf128
+ libc.src.__support.math.ldexpf16
+)
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
new file mode 100644
index 0000000..2e4450a
--- /dev/null
+++ b/libc/test/shared/shared_math_test.cpp
@@ -0,0 +1,80 @@
+//===-- Unittests for shared math functions -------------------------------===//
+//
+// 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 "shared/math.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+TEST(LlvmLibcSharedMathTest, AllFloat16) {
+ int exponent;
+
+ EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::acoshf16(1.0f16));
+ EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::acospif16(1.0f16));
+ EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::asinf16(0.0f16));
+
+ EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::exp10f16(0.0f16));
+
+ EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::expf16(0.0f16));
+
+ ASSERT_FP_EQ(float16(8 << 5), LIBC_NAMESPACE::shared::ldexpf16(8.0f16, 5));
+ ASSERT_FP_EQ(float16(-1 * (8 << 5)),
+ LIBC_NAMESPACE::shared::ldexpf16(-8.0f16, 5));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(
+ 0.75f16, LIBC_NAMESPACE::shared::frexpf16(24.0f16, &exponent));
+ EXPECT_EQ(exponent, 5);
+
+ EXPECT_FP_EQ(0x1.921fb6p+0f16, LIBC_NAMESPACE::shared::acosf16(0.0f16));
+}
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+TEST(LlvmLibcSharedMathTest, AllFloat) {
+ int exponent;
+
+ EXPECT_FP_EQ(0x1.921fb6p+0, LIBC_NAMESPACE::shared::acosf(0.0f));
+ EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::acoshf(1.0f));
+ EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::asinf(0.0f));
+ EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::asinhf(0.0f));
+ EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::erff(0.0f));
+ EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::exp10f(0.0f));
+ EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::expf(0.0f));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(0.75f,
+ LIBC_NAMESPACE::shared::frexpf(24.0f, &exponent));
+ EXPECT_EQ(exponent, 5);
+
+ ASSERT_FP_EQ(float(8 << 5), LIBC_NAMESPACE::shared::ldexpf(8.0f, 5));
+ ASSERT_FP_EQ(float(-1 * (8 << 5)), LIBC_NAMESPACE::shared::ldexpf(-8.0f, 5));
+}
+
+TEST(LlvmLibcSharedMathTest, AllDouble) {
+ EXPECT_FP_EQ(0x1.921fb54442d18p+0, LIBC_NAMESPACE::shared::acos(0.0));
+ EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::asin(0.0));
+ EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::exp(0.0));
+ EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::exp10(0.0));
+}
+
+#ifdef LIBC_TYPES_HAS_FLOAT128
+
+TEST(LlvmLibcSharedMathTest, AllFloat128) {
+ int exponent;
+
+ EXPECT_FP_EQ_ALL_ROUNDING(float128(0.75), LIBC_NAMESPACE::shared::frexpf128(
+ float128(24), &exponent));
+ EXPECT_EQ(exponent, 5);
+
+ ASSERT_FP_EQ(float128(8 << 5),
+ LIBC_NAMESPACE::shared::ldexpf128(float128(8), 5));
+ ASSERT_FP_EQ(float128(-1 * (8 << 5)),
+ LIBC_NAMESPACE::shared::ldexpf128(float128(-8), 5));
+}
+
+#endif // LIBC_TYPES_HAS_FLOAT128
diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index b3eba43..c576e08 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -51,7 +51,9 @@ function(add_fp_unittest name)
${test_type}
LINK_LIBRARIES "${MATH_UNITTEST_LINK_LIBRARIES}"
"${MATH_UNITTEST_UNPARSED_ARGUMENTS}"
- DEPENDS "${deps}"
+ DEPENDS
+ libc.hdr.stdint_proxy
+ "${deps}"
)
endfunction(add_fp_unittest)
diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt
index e54d7a5..5d1d0e0 100644
--- a/libc/test/src/__support/CMakeLists.txt
+++ b/libc/test/src/__support/CMakeLists.txt
@@ -265,6 +265,7 @@ add_libc_test(
SRCS
str_to_float_comparison_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.stdio.printf
libc.src.stdio.fopen
libc.src.stdio.fclose
diff --git a/libc/test/src/__support/CPP/CMakeLists.txt b/libc/test/src/__support/CPP/CMakeLists.txt
index 2b4d610..3e1379d 100644
--- a/libc/test/src/__support/CPP/CMakeLists.txt
+++ b/libc/test/src/__support/CPP/CMakeLists.txt
@@ -27,6 +27,7 @@ add_libc_test(
SRCS
bit_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.big_int
libc.src.__support.CPP.bit
libc.src.__support.macros.properties.types
diff --git a/libc/test/src/__support/CPP/bit_test.cpp b/libc/test/src/__support/CPP/bit_test.cpp
index 89e2a75..891e693 100644
--- a/libc/test/src/__support/CPP/bit_test.cpp
+++ b/libc/test/src/__support/CPP/bit_test.cpp
@@ -6,14 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/big_int.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace cpp {
diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt
index dfd9005..81db4cc 100644
--- a/libc/test/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/test/src/__support/FPUtil/CMakeLists.txt
@@ -39,6 +39,12 @@ add_fp_unittest(
libc.src.__support.FPUtil.rounding_mode
)
+# TODO: Temporally disable bfloat16 test until MPCommon target is updated
+# https://github.com/llvm/llvm-project/pull/149678
+if(LLVM_LIBC_FULL_BUILD)
+ return()
+endif()
+
add_fp_unittest(
bfloat16_test
NEED_MPFR
@@ -49,3 +55,15 @@ add_fp_unittest(
DEPENDS
libc.src.__support.FPUtil.bfloat16
)
+
+add_fp_unittest(
+ comparison_operations_test
+ SUITE
+ libc-fputil-tests
+ SRCS
+ comparison_operations_test.cpp
+ DEPENDS
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.comparison_operations
+ libc.src.__support.macros.properties.types
+)
diff --git a/libc/test/src/__support/FPUtil/comparison_operations_test.cpp b/libc/test/src/__support/FPUtil/comparison_operations_test.cpp
new file mode 100644
index 0000000..04a3321
--- /dev/null
+++ b/libc/test/src/__support/FPUtil/comparison_operations_test.cpp
@@ -0,0 +1,350 @@
+//===-- Unittests for comparison operations on floating-point numbers -----===//
+//
+// 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/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/comparison_operations.h"
+#include "src/__support/macros/properties/types.h"
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::fputil::equals;
+using LIBC_NAMESPACE::fputil::greater_than;
+using LIBC_NAMESPACE::fputil::greater_than_or_equals;
+using LIBC_NAMESPACE::fputil::less_than;
+using LIBC_NAMESPACE::fputil::less_than_or_equals;
+
+using BFloat16 = LIBC_NAMESPACE::fputil::BFloat16;
+
+template <typename T>
+class ComparisonOperationsTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+ // TODO: Make these constexpr once quick_get_round is made constexpr.
+ T normal1;
+ T neg_normal1;
+ T normal2;
+ T small;
+ T neg_small;
+ T large;
+ T neg_large;
+
+public:
+ void SetUp() override {
+ with_fenv_preserved([this]() {
+ normal1 = T(3.14);
+ neg_normal1 = T(-3.14);
+ normal2 = T(2.71);
+ small = T(0.1);
+ neg_small = T(-0.1);
+ large = T(10000.0);
+ neg_large = T(-10000.0);
+ });
+ }
+
+ void test_equals() {
+ EXPECT_TRUE(equals(neg_zero, neg_zero));
+ EXPECT_TRUE(equals(zero, neg_zero));
+ EXPECT_TRUE(equals(neg_zero, zero));
+
+ EXPECT_TRUE(equals(inf, inf));
+ EXPECT_TRUE(equals(neg_inf, neg_inf));
+ EXPECT_FALSE(equals(inf, neg_inf));
+ EXPECT_FALSE(equals(neg_inf, inf));
+
+ EXPECT_TRUE(equals(normal1, normal1));
+ EXPECT_TRUE(equals(normal2, normal2));
+ EXPECT_FALSE(equals(normal1, normal2));
+ EXPECT_FALSE(equals(normal1, neg_normal1));
+
+ auto test_qnan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(equals(x, y));
+ EXPECT_FP_EXCEPTION(0);
+ };
+
+ test_qnan(aNaN, aNaN);
+ test_qnan(aNaN, neg_aNaN);
+ test_qnan(aNaN, zero);
+ test_qnan(aNaN, inf);
+ test_qnan(aNaN, normal1);
+
+ test_qnan(neg_aNaN, neg_aNaN);
+ test_qnan(neg_aNaN, aNaN);
+ test_qnan(neg_aNaN, zero);
+ test_qnan(neg_aNaN, inf);
+ test_qnan(neg_aNaN, normal1);
+
+ auto test_snan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(equals(x, y));
+ EXPECT_FP_EXCEPTION(FE_INVALID);
+ };
+
+ test_snan(sNaN, sNaN);
+ test_snan(sNaN, neg_sNaN);
+ test_snan(sNaN, aNaN);
+ test_snan(sNaN, neg_aNaN);
+ test_snan(sNaN, zero);
+ test_snan(sNaN, neg_zero);
+ test_snan(sNaN, inf);
+ test_snan(sNaN, neg_inf);
+ test_snan(sNaN, normal1);
+
+ test_snan(neg_sNaN, neg_sNaN);
+ test_snan(neg_sNaN, sNaN);
+ test_snan(neg_sNaN, aNaN);
+ test_snan(neg_sNaN, neg_aNaN);
+ test_snan(neg_sNaN, zero);
+ test_snan(neg_sNaN, neg_zero);
+ test_snan(neg_sNaN, inf);
+ test_snan(neg_sNaN, neg_inf);
+ test_snan(neg_sNaN, normal1);
+ }
+
+ void test_less_than() {
+ EXPECT_TRUE(less_than(neg_small, small));
+ EXPECT_TRUE(less_than(small, large));
+
+ EXPECT_TRUE(less_than(neg_large, neg_small));
+ EXPECT_FALSE(less_than(large, small));
+ EXPECT_FALSE(less_than(small, neg_small));
+
+ EXPECT_FALSE(less_than(zero, neg_zero));
+ EXPECT_FALSE(less_than(neg_zero, zero));
+ EXPECT_FALSE(less_than(zero, zero));
+
+ EXPECT_TRUE(less_than(neg_small, zero));
+ EXPECT_TRUE(less_than(neg_zero, small));
+ EXPECT_FALSE(less_than(small, zero));
+
+ EXPECT_TRUE(less_than(neg_inf, inf));
+ EXPECT_TRUE(less_than(neg_inf, neg_small));
+ EXPECT_TRUE(less_than(small, inf));
+ EXPECT_FALSE(less_than(inf, small));
+
+ EXPECT_FALSE(less_than(small, small));
+ EXPECT_FALSE(less_than(neg_inf, neg_inf));
+
+ auto test_qnan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(less_than(x, y));
+ EXPECT_FP_EXCEPTION(FE_INVALID);
+ };
+
+ test_qnan(aNaN, small);
+ test_qnan(small, aNaN);
+ test_qnan(aNaN, aNaN);
+ test_qnan(neg_aNaN, neg_small);
+ test_qnan(neg_small, neg_aNaN);
+ test_qnan(neg_aNaN, neg_aNaN);
+
+ auto test_snan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(less_than(x, y));
+ EXPECT_FP_EXCEPTION(FE_INVALID);
+ };
+
+ test_snan(sNaN, small);
+ test_snan(sNaN, neg_small);
+ test_snan(sNaN, zero);
+ test_snan(sNaN, inf);
+ test_snan(sNaN, aNaN);
+ test_snan(sNaN, sNaN);
+
+ test_snan(neg_sNaN, small);
+ test_snan(neg_sNaN, neg_small);
+ test_snan(neg_sNaN, zero);
+ test_snan(neg_sNaN, inf);
+ test_snan(neg_sNaN, aNaN);
+ test_snan(neg_sNaN, neg_sNaN);
+ }
+
+ void test_greater_than() {
+ EXPECT_TRUE(greater_than(large, neg_small));
+ EXPECT_TRUE(greater_than(neg_small, neg_large));
+
+ EXPECT_FALSE(greater_than(large, large));
+ EXPECT_FALSE(greater_than(neg_small, large));
+
+ EXPECT_FALSE(greater_than(zero, neg_zero));
+ EXPECT_FALSE(greater_than(neg_zero, zero));
+
+ EXPECT_TRUE(greater_than(inf, neg_inf));
+ EXPECT_TRUE(greater_than(inf, large));
+ EXPECT_TRUE(greater_than(large, neg_inf));
+ EXPECT_FALSE(greater_than(neg_inf, inf));
+
+ EXPECT_FALSE(greater_than(large, large));
+ EXPECT_FALSE(greater_than(inf, inf));
+
+ auto test_qnan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(greater_than(x, y));
+ EXPECT_FP_EXCEPTION(FE_INVALID);
+ };
+
+ test_qnan(aNaN, large);
+ test_qnan(large, aNaN);
+ test_qnan(aNaN, aNaN);
+ test_qnan(neg_aNaN, neg_small);
+ test_qnan(neg_small, neg_aNaN);
+ test_qnan(neg_aNaN, neg_aNaN);
+
+ auto test_snan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(greater_than(x, y));
+ EXPECT_FP_EXCEPTION(FE_INVALID);
+ };
+
+ test_snan(sNaN, large);
+ test_snan(sNaN, neg_small);
+ test_snan(sNaN, zero);
+ test_snan(sNaN, inf);
+ test_snan(sNaN, aNaN);
+ test_snan(sNaN, sNaN);
+
+ test_snan(neg_sNaN, large);
+ test_snan(neg_sNaN, neg_small);
+ test_snan(neg_sNaN, zero);
+ test_snan(neg_sNaN, inf);
+ test_snan(neg_sNaN, aNaN);
+ test_snan(neg_sNaN, neg_sNaN);
+ }
+
+ void test_less_than_or_equals() {
+ EXPECT_TRUE(less_than_or_equals(neg_small, small));
+ EXPECT_TRUE(less_than_or_equals(small, large));
+ EXPECT_TRUE(less_than_or_equals(neg_inf, small));
+
+ EXPECT_TRUE(less_than_or_equals(small, small));
+ EXPECT_TRUE(less_than_or_equals(zero, neg_zero));
+ EXPECT_TRUE(less_than_or_equals(inf, inf));
+
+ EXPECT_FALSE(less_than_or_equals(small, neg_small));
+ EXPECT_FALSE(less_than_or_equals(large, small));
+ EXPECT_FALSE(less_than_or_equals(inf, small));
+
+ EXPECT_TRUE(less_than_or_equals(neg_large, small));
+ EXPECT_FALSE(less_than_or_equals(large, neg_small));
+
+ auto test_qnan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(less_than_or_equals(x, y));
+ EXPECT_FP_EXCEPTION(FE_INVALID);
+ };
+
+ test_qnan(aNaN, small);
+ test_qnan(small, aNaN);
+ test_qnan(aNaN, aNaN);
+ test_qnan(neg_aNaN, neg_small);
+ test_qnan(neg_small, neg_aNaN);
+ test_qnan(neg_aNaN, neg_aNaN);
+
+ auto test_snan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(less_than_or_equals(x, y));
+ EXPECT_FP_EXCEPTION(FE_INVALID);
+ };
+
+ test_snan(sNaN, small);
+ test_snan(sNaN, neg_small);
+ test_snan(sNaN, zero);
+ test_snan(sNaN, inf);
+ test_snan(sNaN, aNaN);
+ test_snan(sNaN, sNaN);
+
+ test_snan(neg_sNaN, small);
+ test_snan(neg_sNaN, neg_small);
+ test_snan(neg_sNaN, zero);
+ test_snan(neg_sNaN, inf);
+ test_snan(neg_sNaN, aNaN);
+ test_snan(neg_sNaN, neg_sNaN);
+ }
+
+ void test_greater_than_or_equals() {
+ EXPECT_TRUE(greater_than_or_equals(small, neg_small));
+ EXPECT_TRUE(greater_than_or_equals(large, small));
+ EXPECT_TRUE(greater_than_or_equals(inf, small));
+
+ EXPECT_TRUE(greater_than_or_equals(small, small));
+ EXPECT_TRUE(greater_than_or_equals(zero, neg_zero));
+ EXPECT_TRUE(greater_than_or_equals(neg_inf, neg_inf));
+
+ EXPECT_FALSE(greater_than_or_equals(neg_small, small));
+ EXPECT_FALSE(greater_than_or_equals(small, large));
+ EXPECT_FALSE(greater_than_or_equals(neg_inf, small));
+
+ EXPECT_TRUE(greater_than_or_equals(large, neg_small));
+ EXPECT_FALSE(greater_than_or_equals(neg_large, small));
+
+ auto test_qnan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(greater_than_or_equals(x, y));
+ EXPECT_FP_EXCEPTION(FE_INVALID);
+ };
+
+ test_qnan(aNaN, small);
+ test_qnan(small, aNaN);
+ test_qnan(aNaN, aNaN);
+ test_qnan(neg_aNaN, neg_small);
+ test_qnan(neg_small, neg_aNaN);
+ test_qnan(neg_aNaN, neg_aNaN);
+
+ auto test_snan = [&](T x, T y) {
+ LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+ EXPECT_FALSE(greater_than_or_equals(x, y));
+ EXPECT_FP_EXCEPTION(FE_INVALID);
+ };
+
+ test_snan(sNaN, small);
+ test_snan(sNaN, neg_small);
+ test_snan(sNaN, zero);
+ test_snan(sNaN, inf);
+ test_snan(sNaN, aNaN);
+ test_snan(sNaN, sNaN);
+
+ test_snan(neg_sNaN, small);
+ test_snan(neg_sNaN, neg_small);
+ test_snan(neg_sNaN, zero);
+ test_snan(neg_sNaN, inf);
+ test_snan(neg_sNaN, aNaN);
+ test_snan(neg_sNaN, neg_sNaN);
+ }
+};
+
+#define TEST_COMPARISON_OPS(Name, Type) \
+ using LlvmLibc##Name##ComparisonOperationsTest = \
+ ComparisonOperationsTest<Type>; \
+ TEST_F(LlvmLibc##Name##ComparisonOperationsTest, Equals) { test_equals(); } \
+ TEST_F(LlvmLibc##Name##ComparisonOperationsTest, LessThan) { \
+ test_less_than(); \
+ } \
+ TEST_F(LlvmLibc##Name##ComparisonOperationsTest, GreaterThan) { \
+ test_greater_than(); \
+ } \
+ TEST_F(LlvmLibc##Name##ComparisonOperationsTest, LessThanOrEquals) { \
+ test_less_than_or_equals(); \
+ } \
+ TEST_F(LlvmLibc##Name##ComparisonOperationsTest, GreaterThanOrEquals) { \
+ test_greater_than_or_equals(); \
+ }
+
+TEST_COMPARISON_OPS(Float, float)
+TEST_COMPARISON_OPS(Double, double)
+TEST_COMPARISON_OPS(LongDouble, long double)
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+TEST_COMPARISON_OPS(Float16, float16)
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#ifdef LIBC_TYPES_HAS_FLOAT128
+TEST_COMPARISON_OPS(Float128, float128)
+#endif // LIBC_TYPES_HAS_FLOAT128
+
+TEST_COMPARISON_OPS(BFloat16, BFloat16)
diff --git a/libc/test/src/__support/File/platform_file_test.cpp b/libc/test/src/__support/File/platform_file_test.cpp
index 6b2be2a..425da6c 100644
--- a/libc/test/src/__support/File/platform_file_test.cpp
+++ b/libc/test/src/__support/File/platform_file_test.cpp
@@ -21,7 +21,8 @@ LIBC_INLINE File *openfile(const char *file_name, const char *mode) {
}
TEST(LlvmLibcPlatformFileTest, CreateWriteCloseAndReadBack) {
- constexpr char FILENAME[] = "testdata/create_write_close_and_readback.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/create_write_close_and_readback.test");
File *file = openfile(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
ASSERT_EQ(file->write(TEXT, TEXT_SIZE).value, TEXT_SIZE);
@@ -42,7 +43,8 @@ TEST(LlvmLibcPlatformFileTest, CreateWriteCloseAndReadBack) {
}
TEST(LlvmLibcPlatformFileTest, CreateWriteSeekAndReadBack) {
- constexpr char FILENAME[] = "testdata/create_write_seek_and_readback.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/create_write_seek_and_readback.test");
File *file = openfile(FILENAME, "w+");
ASSERT_FALSE(file == nullptr);
ASSERT_EQ(file->write(TEXT, TEXT_SIZE).value, TEXT_SIZE);
@@ -62,7 +64,8 @@ TEST(LlvmLibcPlatformFileTest, CreateWriteSeekAndReadBack) {
}
TEST(LlvmLibcPlatformFileTest, CreateAppendCloseAndReadBack) {
- constexpr char FILENAME[] = "testdata/create_append_close_and_readback.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/create_append_close_and_readback.test");
File *file = openfile(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
ASSERT_EQ(file->write(TEXT, TEXT_SIZE).value, TEXT_SIZE);
@@ -91,7 +94,8 @@ TEST(LlvmLibcPlatformFileTest, CreateAppendCloseAndReadBack) {
}
TEST(LlvmLibcPlatformFileTest, CreateAppendSeekAndReadBack) {
- constexpr char FILENAME[] = "testdata/create_append_seek_and_readback.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/create_append_seek_and_readback.test");
File *file = openfile(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
ASSERT_EQ(file->write(TEXT, TEXT_SIZE).value, TEXT_SIZE);
@@ -124,7 +128,7 @@ TEST(LlvmLibcPlatformFileTest, LargeFile) {
for (size_t i = 0; i < DATA_SIZE; ++i)
write_data[i] = BYTE;
- constexpr char FILENAME[] = "testdata/large_file.test";
+ constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/large_file.test");
File *file = openfile(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
@@ -151,7 +155,8 @@ TEST(LlvmLibcPlatformFileTest, LargeFile) {
}
TEST(LlvmLibcPlatformFileTest, ReadSeekCurAndRead) {
- constexpr char FILENAME[] = "testdata/read_seek_cur_and_read.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/read_seek_cur_and_read.test");
File *file = openfile(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
constexpr char CONTENT[] = "1234567890987654321";
@@ -178,7 +183,8 @@ TEST(LlvmLibcPlatformFileTest, ReadSeekCurAndRead) {
}
TEST(LlvmLibcPlatformFileTest, IncorrectOperation) {
- constexpr char FILENAME[] = "testdata/incorrect_operation.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/incorrect_operation.test");
char data[1] = {123};
File *file = openfile(FILENAME, "w");
diff --git a/libc/test/src/__support/HashTable/CMakeLists.txt b/libc/test/src/__support/HashTable/CMakeLists.txt
index f84835f..55e9864 100644
--- a/libc/test/src/__support/HashTable/CMakeLists.txt
+++ b/libc/test/src/__support/HashTable/CMakeLists.txt
@@ -30,6 +30,7 @@ add_libc_test(
SRCS
group_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.HashTable.bitmask
libc.src.stdlib.rand
libc.src.search.hsearch
diff --git a/libc/test/src/__support/HashTable/group_test.cpp b/libc/test/src/__support/HashTable/group_test.cpp
index acdc58e..890ca00 100644
--- a/libc/test/src/__support/HashTable/group_test.cpp
+++ b/libc/test/src/__support/HashTable/group_test.cpp
@@ -8,11 +8,11 @@
#include "src/__support/HashTable/bitmask.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/macros/config.h"
#include "src/stdlib/rand.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace internal {
diff --git a/libc/test/src/__support/str_to_float_comparison_test.cpp b/libc/test/src/__support/str_to_float_comparison_test.cpp
index 6e89ce2..18be22a 100644
--- a/libc/test/src/__support/str_to_float_comparison_test.cpp
+++ b/libc/test/src/__support/str_to_float_comparison_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/bit.h"
#include "src/stdio/fclose.h"
#include "src/stdio/fgets.h"
@@ -17,7 +18,6 @@
#include "src/string/strdup.h"
#include "src/string/strtok.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
// The intent of this test is to read in files in the format used in this test
// dataset: https://github.com/nigeltao/parse-number-fxx-test-data
diff --git a/libc/test/src/__support/wchar/CMakeLists.txt b/libc/test/src/__support/wchar/CMakeLists.txt
index f072745..c112c83 100644
--- a/libc/test/src/__support/wchar/CMakeLists.txt
+++ b/libc/test/src/__support/wchar/CMakeLists.txt
@@ -34,3 +34,20 @@ add_libc_test(
libc.hdr.errno_macros
libc.hdr.types.char32_t
)
+
+add_libc_test(
+ wcsnrtombs_test
+ SUITE
+ libc-support-tests
+ SRCS
+ wcsnrtombs_test.cpp
+ DEPENDS
+ libc.src.__support.wchar.string_converter
+ libc.src.__support.wchar.character_converter
+ libc.src.__support.wchar.mbstate
+ libc.src.__support.error_or
+ libc.src.__support.wchar.wcsnrtombs
+ libc.hdr.errno_macros
+ libc.hdr.types.char32_t
+ libc.hdr.types.char8_t
+)
diff --git a/libc/test/src/__support/wchar/wcsnrtombs_test.cpp b/libc/test/src/__support/wchar/wcsnrtombs_test.cpp
new file mode 100644
index 0000000..2d431ed
--- /dev/null
+++ b/libc/test/src/__support/wchar/wcsnrtombs_test.cpp
@@ -0,0 +1,213 @@
+//===-- Unittests 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/errno_macros.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/wchar_t.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/null_check.h"
+#include "src/__support/macros/properties/os.h"
+#include "src/__support/wchar/mbstate.h"
+#include "src/__support/wchar/wcsnrtombs.h"
+#include "test/UnitTest/Test.h"
+
+// TODO: add support for 16-bit widechars to remove this macro
+#ifdef LIBC_TARGET_OS_IS_WINDOWS
+TEST(LlvmLibcStringConverterTest, Windows) {
+ // pass on windows for now
+}
+
+#else
+
+TEST(LlvmLibcWcsnrtombs, AllMultibyteLengths) {
+ LIBC_NAMESPACE::internal::mbstate state;
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+ char mbs[11];
+
+ auto res = LIBC_NAMESPACE::internal::wcsnrtombs(mbs, &cur, 5, 11, &state);
+ ASSERT_TRUE(res.has_value());
+ ASSERT_EQ(res.value(), static_cast<size_t>(10));
+ ASSERT_EQ(cur, nullptr);
+ ASSERT_EQ(mbs[0], '\xF0'); // clown begin
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
+ ASSERT_EQ(mbs[5], '\x88');
+ ASSERT_EQ(mbs[6], '\x91');
+ ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin
+ ASSERT_EQ(mbs[8], '\xBF');
+ ASSERT_EQ(mbs[9], '\x41'); // A begin
+ ASSERT_EQ(mbs[10], '\0'); // null terminator
+}
+
+TEST(LlvmLibcWcsnrtombs, DestLimit) {
+ LIBC_NAMESPACE::internal::mbstate state1;
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+
+ char mbs[11];
+ for (int i = 0; i < 11; ++i)
+ mbs[i] = '\x01'; // dummy initial values
+
+ auto res = LIBC_NAMESPACE::internal::wcsnrtombs(mbs, &cur, 5, 4, &state1);
+ ASSERT_TRUE(res.has_value());
+ ASSERT_EQ(res.value(), static_cast<size_t>(4));
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes
+
+ for (int i = 0; i < 11; ++i)
+ mbs[i] = '\x01'; // dummy initial values
+ LIBC_NAMESPACE::internal::mbstate state2;
+
+ // not enough bytes to convert the second character, so only converts one
+ cur = src;
+ res = LIBC_NAMESPACE::internal::wcsnrtombs(mbs, &cur, 5, 6, &state2);
+ ASSERT_TRUE(res.has_value());
+ ASSERT_EQ(res.value(), static_cast<size_t>(4));
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01');
+}
+
+TEST(LlvmLibcWcsnrtombs, SrcLimit) {
+ LIBC_NAMESPACE::internal::mbstate state;
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+
+ char mbs[11];
+ for (int i = 0; i < 11; ++i)
+ mbs[i] = '\x01'; // dummy initial values
+
+ auto res = LIBC_NAMESPACE::internal::wcsnrtombs(mbs, &cur, 2, 11, &state);
+ ASSERT_TRUE(res.has_value());
+ ASSERT_EQ(res.value(), static_cast<size_t>(7));
+ ASSERT_EQ(cur, src + 2);
+ ASSERT_EQ(mbs[0], '\xF0'); // clown begin
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
+ ASSERT_EQ(mbs[5], '\x88');
+ ASSERT_EQ(mbs[6], '\x91');
+ ASSERT_EQ(mbs[7], '\x01');
+
+ res = LIBC_NAMESPACE::internal::wcsnrtombs(mbs + res.value(), &cur, 100, 11,
+ &state);
+ ASSERT_TRUE(res.has_value());
+ ASSERT_EQ(res.value(), static_cast<size_t>(3));
+ ASSERT_EQ(cur, nullptr);
+ ASSERT_EQ(mbs[0], '\xF0'); // clown begin
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
+ ASSERT_EQ(mbs[5], '\x88');
+ ASSERT_EQ(mbs[6], '\x91');
+ ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin
+ ASSERT_EQ(mbs[8], '\xBF');
+ ASSERT_EQ(mbs[9], '\x41'); // A begin
+ ASSERT_EQ(mbs[10], '\0'); // null terminator
+}
+
+TEST(LlvmLibcWcsnrtombs, NullDest) {
+ LIBC_NAMESPACE::internal::mbstate state1;
+
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+
+ // n parameter ignored when dest is null
+ auto res = LIBC_NAMESPACE::internal::wcsnrtombs(nullptr, &cur, 5, 1, &state1);
+ ASSERT_TRUE(res.has_value());
+ ASSERT_EQ(res.value(), static_cast<size_t>(10));
+ ASSERT_EQ(cur, src); // pointer not updated when dest = null
+
+ LIBC_NAMESPACE::internal::mbstate state2;
+ res = LIBC_NAMESPACE::internal::wcsnrtombs(nullptr, &cur, 5, 100, &state2);
+ ASSERT_TRUE(res.has_value());
+ ASSERT_EQ(res.value(), static_cast<size_t>(10));
+ ASSERT_EQ(cur, src);
+}
+
+TEST(LlvmLibcWcsnrtombs, InvalidState) {
+ // this is more thoroughly tested by CharacterConverter
+ LIBC_NAMESPACE::internal::mbstate state;
+ state.total_bytes = 100;
+
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+
+ // n parameter ignored when dest is null
+ auto res = LIBC_NAMESPACE::internal::wcsnrtombs(nullptr, &cur, 5, 1, &state);
+ ASSERT_FALSE(res.has_value());
+ ASSERT_EQ(res.error(), EINVAL);
+}
+
+TEST(LlvmLibcWcsnrtombs, InvalidCharacter) {
+ LIBC_NAMESPACE::internal::mbstate state1;
+
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0x12ffff), // invalid widechar
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+ char mbs[11];
+
+ // n parameter ignored when dest is null
+ auto res = LIBC_NAMESPACE::internal::wcsnrtombs(mbs, &cur, 5, 7, &state1);
+ ASSERT_TRUE(res.has_value());
+ ASSERT_EQ(res.value(), static_cast<size_t>(7));
+
+ LIBC_NAMESPACE::internal::mbstate state2;
+ cur = src;
+ res = LIBC_NAMESPACE::internal::wcsnrtombs(mbs, &cur, 5, 11, &state2);
+ ASSERT_FALSE(res.has_value());
+ ASSERT_EQ(res.error(), EILSEQ);
+}
+
+#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+TEST(LlvmLibcWcsnrtombs, NullSrc) {
+ EXPECT_DEATH(
+ [] {
+ LIBC_NAMESPACE::internal::mbstate state;
+ char mbs[10];
+ LIBC_NAMESPACE::internal::wcsnrtombs(mbs, nullptr, 1, 1, &state);
+ },
+ WITH_SIGNAL(-1));
+}
+#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif
diff --git a/libc/test/src/fenv/feclearexcept_test.cpp b/libc/test/src/fenv/feclearexcept_test.cpp
index 52adda4..f39cf4ec 100644
--- a/libc/test/src/fenv/feclearexcept_test.cpp
+++ b/libc/test/src/fenv/feclearexcept_test.cpp
@@ -13,7 +13,6 @@
#include "test/UnitTest/Test.h"
#include "hdr/fenv_macros.h"
-#include <stdint.h>
#include "excepts.h"
diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h
index 5c5419c..902ff04 100644
--- a/libc/test/src/math/FmaTest.h
+++ b/libc/test/src/math/FmaTest.h
@@ -48,7 +48,8 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
InStorageType get_random_bit_pattern() {
InStorageType bits{0};
for (InStorageType i = 0; i < sizeof(InStorageType) / 2; ++i) {
- bits = (bits << 2) + static_cast<uint16_t>(LIBC_NAMESPACE::rand());
+ bits = static_cast<InStorageType>(
+ (bits << 2) + static_cast<uint16_t>(LIBC_NAMESPACE::rand()));
}
return bits;
}
@@ -57,7 +58,7 @@ public:
using FmaFunc = OutType (*)(InType, InType, InType);
void test_subnormal_range(FmaFunc func) {
- constexpr InStorageType COUNT = 100'001;
+ constexpr InStorageType COUNT = 10'001;
constexpr InStorageType RAW_STEP =
(IN_MAX_SUBNORMAL_U - IN_MIN_SUBNORMAL_U) / COUNT;
constexpr InStorageType STEP = (RAW_STEP == 0 ? 1 : RAW_STEP);
@@ -75,7 +76,7 @@ public:
}
void test_normal_range(FmaFunc func) {
- constexpr InStorageType COUNT = 100'001;
+ constexpr InStorageType COUNT = 10'001;
constexpr InStorageType RAW_STEP =
(IN_MAX_NORMAL_U - IN_MIN_NORMAL_U) / COUNT;
constexpr InStorageType STEP = (RAW_STEP == 0 ? 1 : RAW_STEP);
diff --git a/libc/test/src/math/HypotTest.h b/libc/test/src/math/HypotTest.h
index dc73581..b37abf7 100644
--- a/libc/test/src/math/HypotTest.h
+++ b/libc/test/src/math/HypotTest.h
@@ -71,8 +71,9 @@ public:
void test_subnormal_range(Func func) {
constexpr StorageType COUNT = 10'001;
- for (unsigned scale = 0; scale < 4; ++scale) {
- StorageType max_value = MAX_SUBNORMAL << scale;
+ constexpr unsigned SCALE = (sizeof(T) < 4) ? 1 : 4;
+ for (unsigned scale = 0; scale < SCALE; ++scale) {
+ StorageType max_value = static_cast<StorageType>(MAX_SUBNORMAL << scale);
StorageType step = (max_value - MIN_SUBNORMAL) / COUNT + 1;
for (int signs = 0; signs < 4; ++signs) {
for (StorageType v = MIN_SUBNORMAL, w = max_value;
diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h
index 08dce0d..cff2aeb 100644
--- a/libc/test/src/math/LdExpTest.h
+++ b/libc/test/src/math/LdExpTest.h
@@ -17,7 +17,7 @@
#include "test/UnitTest/Test.h"
#include "hdr/math_macros.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LIBC_NAMESPACE::Sign;
diff --git a/libc/test/src/math/acosf_test.cpp b/libc/test/src/math/acosf_test.cpp
index aa0128f..6e2bed7 100644
--- a/libc/test/src/math/acosf_test.cpp
+++ b/libc/test/src/math/acosf_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/acosf.h"
@@ -14,8 +15,6 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
-
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
using LlvmLibcAcosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/acoshf16_test.cpp b/libc/test/src/math/acoshf16_test.cpp
index 2eb9521..d190cd1 100644
--- a/libc/test/src/math/acoshf16_test.cpp
+++ b/libc/test/src/math/acoshf16_test.cpp
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/libc_errno.h"
#include "src/math/acoshf16.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
using LlvmLibcAcoshf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/libc/test/src/math/acoshf_test.cpp b/libc/test/src/math/acoshf_test.cpp
index 3d3b827..3305445 100644
--- a/libc/test/src/math/acoshf_test.cpp
+++ b/libc/test/src/math/acoshf_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/acoshf.h"
@@ -14,8 +15,6 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
-
using LlvmLibcAcoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/libc/test/src/math/asinf_test.cpp b/libc/test/src/math/asinf_test.cpp
index 1eaa6b8..f2963f2 100644
--- a/libc/test/src/math/asinf_test.cpp
+++ b/libc/test/src/math/asinf_test.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/asinf.h"
@@ -15,8 +16,6 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
-
using LlvmLibcAsinfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/libc/test/src/math/asinhf_test.cpp b/libc/test/src/math/asinhf_test.cpp
index 8c78f93..f9dfb0a 100644
--- a/libc/test/src/math/asinhf_test.cpp
+++ b/libc/test/src/math/asinhf_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/asinhf.h"
@@ -14,8 +15,6 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
-
using LlvmLibcAsinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/libc/test/src/math/atanf_test.cpp b/libc/test/src/math/atanf_test.cpp
index a4bdf18..dc489fe 100644
--- a/libc/test/src/math/atanf_test.cpp
+++ b/libc/test/src/math/atanf_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/atanf.h"
@@ -14,8 +15,6 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
-
using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/libc/test/src/math/atanhf16_test.cpp b/libc/test/src/math/atanhf16_test.cpp
index e35cc77..4c35304 100644
--- a/libc/test/src/math/atanhf16_test.cpp
+++ b/libc/test/src/math/atanhf16_test.cpp
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/math/atanhf16.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
using LlvmLibcAtanhf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/libc/test/src/math/atanhf_test.cpp b/libc/test/src/math/atanhf_test.cpp
index 32272ef..1ec7b6b 100644
--- a/libc/test/src/math/atanhf_test.cpp
+++ b/libc/test/src/math/atanhf_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/atanhf.h"
@@ -14,8 +15,6 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
-
using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
using LIBC_NAMESPACE::Sign;
diff --git a/libc/test/src/math/cosf_test.cpp b/libc/test/src/math/cosf_test.cpp
index 90dc8ff..e2b444f 100644
--- a/libc/test/src/math/cosf_test.cpp
+++ b/libc/test/src/math/cosf_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/cosf.h"
@@ -15,8 +16,6 @@
#include "test/src/math/sdcomp26094.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
-
using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
using LlvmLibcCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/coshf_test.cpp b/libc/test/src/math/coshf_test.cpp
index bdaba50..98f9a82 100644
--- a/libc/test/src/math/coshf_test.cpp
+++ b/libc/test/src/math/coshf_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
@@ -15,8 +16,6 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
-
using LlvmLibcCoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
diff --git a/libc/test/src/math/erff_test.cpp b/libc/test/src/math/erff_test.cpp
index f9b0337..c40aacf 100644
--- a/libc/test/src/math/erff_test.cpp
+++ b/libc/test/src/math/erff_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcErffTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/exp10_test.cpp b/libc/test/src/math/exp10_test.cpp
index 6126e5f2..ee8fe9b 100644
--- a/libc/test/src/math/exp10_test.cpp
+++ b/libc/test/src/math/exp10_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExp10Test = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/libc/test/src/math/exp10f_test.cpp b/libc/test/src/math/exp10f_test.cpp
index 8991596..e2021423 100644
--- a/libc/test/src/math/exp10f_test.cpp
+++ b/libc/test/src/math/exp10f_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExp10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/exp10m1f_test.cpp b/libc/test/src/math/exp10m1f_test.cpp
index 01802bd..613fdeb 100644
--- a/libc/test/src/math/exp10m1f_test.cpp
+++ b/libc/test/src/math/exp10m1f_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExp10m1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/exp2_test.cpp b/libc/test/src/math/exp2_test.cpp
index 4cd95dd..7866037 100644
--- a/libc/test/src/math/exp2_test.cpp
+++ b/libc/test/src/math/exp2_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExp2Test = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/libc/test/src/math/exp2f_test.cpp b/libc/test/src/math/exp2f_test.cpp
index aeecb3e..349a4c3 100644
--- a/libc/test/src/math/exp2f_test.cpp
+++ b/libc/test/src/math/exp2f_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExp2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/exp2m1f_test.cpp b/libc/test/src/math/exp2m1f_test.cpp
index 0c87657..a323bdc 100644
--- a/libc/test/src/math/exp2m1f_test.cpp
+++ b/libc/test/src/math/exp2m1f_test.cpp
@@ -15,7 +15,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExp2m1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/exp_test.cpp b/libc/test/src/math/exp_test.cpp
index 83addae..d328d09 100644
--- a/libc/test/src/math/exp_test.cpp
+++ b/libc/test/src/math/exp_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExpTest = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/libc/test/src/math/expf_test.cpp b/libc/test/src/math/expf_test.cpp
index 3c10812f..8329d74 100644
--- a/libc/test/src/math/expf_test.cpp
+++ b/libc/test/src/math/expf_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExpfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/explogxf_test.cpp b/libc/test/src/math/explogxf_test.cpp
index ff1181e..49cc962 100644
--- a/libc/test/src/math/explogxf_test.cpp
+++ b/libc/test/src/math/explogxf_test.cpp
@@ -44,6 +44,7 @@ TEST_F(LlvmLibcExplogfTest, ExpInFloatRange) {
}
TEST_F(LlvmLibcExplogfTest, LogInFloatRange) {
- CHECK_DATA(0.0f, inf, mpfr::Operation::Log, LIBC_NAMESPACE::log_eval,
- f_normal, def_count, def_prec);
+ CHECK_DATA(0.0f, inf, mpfr::Operation::Log,
+ LIBC_NAMESPACE::acoshf_internal::log_eval, f_normal, def_count,
+ def_prec);
}
diff --git a/libc/test/src/math/expm1_test.cpp b/libc/test/src/math/expm1_test.cpp
index 0cf07e2..5d546de 100644
--- a/libc/test/src/math/expm1_test.cpp
+++ b/libc/test/src/math/expm1_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExpm1Test = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/libc/test/src/math/expm1f_test.cpp b/libc/test/src/math/expm1f_test.cpp
index cf3fe9c..d5c98be 100644
--- a/libc/test/src/math/expm1f_test.cpp
+++ b/libc/test/src/math/expm1f_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcExpm1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/in_float_range_test_helper.h b/libc/test/src/math/in_float_range_test_helper.h
index 35e039e..2179182 100644
--- a/libc/test/src/math/in_float_range_test_helper.h
+++ b/libc/test/src/math/in_float_range_test_helper.h
@@ -5,7 +5,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_IN_FLOAT_RANGE_TEST_HELPER_H
#define LLVM_LIBC_TEST_SRC_MATH_IN_FLOAT_RANGE_TEST_HELPER_H
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
#define CHECK_DATA(start, stop, mfp_op, f, f_check, count, prec) \
{ \
diff --git a/libc/test/src/math/log10_test.cpp b/libc/test/src/math/log10_test.cpp
index e9529d8..7d087d4e 100644
--- a/libc/test/src/math/log10_test.cpp
+++ b/libc/test/src/math/log10_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcLog10Test = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/libc/test/src/math/log10f_test.cpp b/libc/test/src/math/log10f_test.cpp
index b2c1c28..c554948 100644
--- a/libc/test/src/math/log10f_test.cpp
+++ b/libc/test/src/math/log10f_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcLog10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/log1p_test.cpp b/libc/test/src/math/log1p_test.cpp
index e5747b7..4d1efe7 100644
--- a/libc/test/src/math/log1p_test.cpp
+++ b/libc/test/src/math/log1p_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcLog1pTest = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/libc/test/src/math/log1pf_test.cpp b/libc/test/src/math/log1pf_test.cpp
index ffe2dd2..0badbeb 100644
--- a/libc/test/src/math/log1pf_test.cpp
+++ b/libc/test/src/math/log1pf_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcLog1pfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/log2_test.cpp b/libc/test/src/math/log2_test.cpp
index fc440c0..dd55bd8 100644
--- a/libc/test/src/math/log2_test.cpp
+++ b/libc/test/src/math/log2_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcLog2Test = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/libc/test/src/math/log2f_test.cpp b/libc/test/src/math/log2f_test.cpp
index 92226c7..7854489 100644
--- a/libc/test/src/math/log2f_test.cpp
+++ b/libc/test/src/math/log2f_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcLog2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/log_test.cpp b/libc/test/src/math/log_test.cpp
index 54afaa3..be156fe 100644
--- a/libc/test/src/math/log_test.cpp
+++ b/libc/test/src/math/log_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcLogTest = LIBC_NAMESPACE::testing::FPTest<double>;
diff --git a/libc/test/src/math/logf_test.cpp b/libc/test/src/math/logf_test.cpp
index 79d8275..7658075 100644
--- a/libc/test/src/math/logf_test.cpp
+++ b/libc/test/src/math/logf_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcLogfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/performance_testing/Timer.h b/libc/test/src/math/performance_testing/Timer.h
index 32578ad..f75c1f0 100644
--- a/libc/test/src/math/performance_testing/Timer.h
+++ b/libc/test/src/math/performance_testing/Timer.h
@@ -9,8 +9,8 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_PERFORMACE_TESTING_TIMER_H
#define LLVM_LIBC_TEST_SRC_MATH_PERFORMACE_TESTING_TIMER_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
namespace testing {
diff --git a/libc/test/src/math/performance_testing/fmodf16_perf.cpp b/libc/test/src/math/performance_testing/fmodf16_perf.cpp
index f7c492c..407ed7c 100644
--- a/libc/test/src/math/performance_testing/fmodf16_perf.cpp
+++ b/libc/test/src/math/performance_testing/fmodf16_perf.cpp
@@ -11,7 +11,7 @@
#include "src/__support/FPUtil/generic/FMod.h"
#include "src/__support/macros/properties/types.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
#define FMOD_FUNC(U) (LIBC_NAMESPACE::fputil::generic::FMod<float16, U>::eval)
diff --git a/libc/test/src/math/powf_test.cpp b/libc/test/src/math/powf_test.cpp
index 4d189d8..1d70724 100644
--- a/libc/test/src/math/powf_test.cpp
+++ b/libc/test/src/math/powf_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcPowfTest = LIBC_NAMESPACE::testing::FPTest<float>;
using LIBC_NAMESPACE::testing::tlog;
diff --git a/libc/test/src/math/sdcomp26094.h b/libc/test/src/math/sdcomp26094.h
index bb2b9f1..b08cfd2 100644
--- a/libc/test/src/math/sdcomp26094.h
+++ b/libc/test/src/math/sdcomp26094.h
@@ -9,11 +9,10 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_SDCOMP26094_H
#define LLVM_LIBC_TEST_SRC_MATH_SDCOMP26094_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/macros/config.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace testing {
diff --git a/libc/test/src/math/sincosf_test.cpp b/libc/test/src/math/sincosf_test.cpp
index 4aac1fa..9c2656f 100644
--- a/libc/test/src/math/sincosf_test.cpp
+++ b/libc/test/src/math/sincosf_test.cpp
@@ -15,7 +15,7 @@
#include "test/src/math/sdcomp26094.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcSinCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/sinf_test.cpp b/libc/test/src/math/sinf_test.cpp
index e0357e6..c4676d9 100644
--- a/libc/test/src/math/sinf_test.cpp
+++ b/libc/test/src/math/sinf_test.cpp
@@ -15,7 +15,7 @@
#include "test/src/math/sdcomp26094.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcSinfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/sinhf_test.cpp b/libc/test/src/math/sinhf_test.cpp
index 74f906e..a664010 100644
--- a/libc/test/src/math/sinhf_test.cpp
+++ b/libc/test/src/math/sinhf_test.cpp
@@ -15,7 +15,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcSinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/sinpif_test.cpp b/libc/test/src/math/sinpif_test.cpp
index 94e3dbc..2e66ae9 100644
--- a/libc/test/src/math/sinpif_test.cpp
+++ b/libc/test/src/math/sinpif_test.cpp
@@ -12,7 +12,7 @@
#include "test/src/math/sdcomp26094.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcSinpifTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 4aafe03..ec4c09c 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -3169,7 +3169,6 @@ add_fp_unittest(
libc.hdr.signal_macros
libc.src.math.nanf
libc.src.__support.FPUtil.fp_bits
- libc.src.__support.macros.sanitizer
# FIXME: The nan tests currently have death tests, which aren't supported for
# hermetic tests.
UNIT_TEST_ONLY
@@ -3185,7 +3184,6 @@ add_fp_unittest(
libc.hdr.signal_macros
libc.src.math.nan
libc.src.__support.FPUtil.fp_bits
- libc.src.__support.macros.sanitizer
# FIXME: The nan tests currently have death tests, which aren't supported for
# hermetic tests.
UNIT_TEST_ONLY
@@ -3201,7 +3199,6 @@ add_fp_unittest(
libc.hdr.signal_macros
libc.src.math.nanl
libc.src.__support.FPUtil.fp_bits
- libc.src.__support.macros.sanitizer
# FIXME: The nan tests currently have death tests, which aren't supported for
# hermetic tests.
UNIT_TEST_ONLY
@@ -3217,7 +3214,6 @@ add_fp_unittest(
libc.hdr.signal_macros
libc.src.math.nanf16
libc.src.__support.FPUtil.fp_bits
- libc.src.__support.macros.sanitizer
# FIXME: The nan tests currently have death tests, which aren't supported for
# hermetic tests.
UNIT_TEST_ONLY
@@ -3233,7 +3229,6 @@ add_fp_unittest(
libc.hdr.signal_macros
libc.src.math.nanf128
libc.src.__support.FPUtil.fp_bits
- libc.src.__support.macros.sanitizer
# FIXME: The nan tests currently have death tests, which aren't supported for
# hermetic tests.
UNIT_TEST_ONLY
diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h
index 094cc7e..8de70ad 100644
--- a/libc/test/src/math/smoke/LdExpTest.h
+++ b/libc/test/src/math/smoke/LdExpTest.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_LDEXPTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_LDEXPTEST_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/limits.h" // INT_MAX
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/NormalFloat.h"
@@ -16,8 +17,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LIBC_NAMESPACE::Sign;
template <typename T, typename U = int>
diff --git a/libc/test/src/math/smoke/acosf_test.cpp b/libc/test/src/math/smoke/acosf_test.cpp
index 257c6a3..733610a 100644
--- a/libc/test/src/math/smoke/acosf_test.cpp
+++ b/libc/test/src/math/smoke/acosf_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcAcosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/smoke/acoshf_test.cpp b/libc/test/src/math/smoke/acoshf_test.cpp
index b6abfab..19556b2 100644
--- a/libc/test/src/math/smoke/acoshf_test.cpp
+++ b/libc/test/src/math/smoke/acoshf_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcAcoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/smoke/asinf_test.cpp b/libc/test/src/math/smoke/asinf_test.cpp
index 2615a8d..6195a11 100644
--- a/libc/test/src/math/smoke/asinf_test.cpp
+++ b/libc/test/src/math/smoke/asinf_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcAsinfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/smoke/asinhf_test.cpp b/libc/test/src/math/smoke/asinhf_test.cpp
index d812a2d..e6326c1 100644
--- a/libc/test/src/math/smoke/asinhf_test.cpp
+++ b/libc/test/src/math/smoke/asinhf_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcAsinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/smoke/atanf_test.cpp b/libc/test/src/math/smoke/atanf_test.cpp
index b56b9d0..7d2dfee 100644
--- a/libc/test/src/math/smoke/atanf_test.cpp
+++ b/libc/test/src/math/smoke/atanf_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/smoke/atanhf_test.cpp b/libc/test/src/math/smoke/atanhf_test.cpp
index 038cb30..5588ae0 100644
--- a/libc/test/src/math/smoke/atanhf_test.cpp
+++ b/libc/test/src/math/smoke/atanhf_test.cpp
@@ -13,7 +13,7 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LIBC_NAMESPACE::Sign;
diff --git a/libc/test/src/math/smoke/cosf_test.cpp b/libc/test/src/math/smoke/cosf_test.cpp
index 470a876..837fee9 100644
--- a/libc/test/src/math/smoke/cosf_test.cpp
+++ b/libc/test/src/math/smoke/cosf_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/cosf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcCosfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/coshf_test.cpp b/libc/test/src/math/smoke/coshf_test.cpp
index ee8f019..81096fa 100644
--- a/libc/test/src/math/smoke/coshf_test.cpp
+++ b/libc/test/src/math/smoke/coshf_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
@@ -14,8 +15,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcCoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcCoshfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/cospif_test.cpp b/libc/test/src/math/smoke/cospif_test.cpp
index 3d48909..6f1bb24 100644
--- a/libc/test/src/math/smoke/cospif_test.cpp
+++ b/libc/test/src/math/smoke/cospif_test.cpp
@@ -6,12 +6,11 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/libc_errno.h"
#include "src/math/cospif.h"
#include "test/UnitTest/FPMatcher.h"
-#include <stdint.h>
-
using LlvmLibcCospifTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcCospifTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/erff_test.cpp b/libc/test/src/math/smoke/erff_test.cpp
index a9f4994..133b4b8 100644
--- a/libc/test/src/math/smoke/erff_test.cpp
+++ b/libc/test/src/math/smoke/erff_test.cpp
@@ -7,13 +7,12 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/erff.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcErffTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcErffTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/exp10_test.cpp b/libc/test/src/math/smoke/exp10_test.cpp
index 50d3de0..76e6c78 100644
--- a/libc/test/src/math/smoke/exp10_test.cpp
+++ b/libc/test/src/math/smoke/exp10_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/exp10.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcExp10Test = LIBC_NAMESPACE::testing::FPTest<double>;
TEST_F(LlvmLibcExp10Test, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/exp10f_test.cpp b/libc/test/src/math/smoke/exp10f_test.cpp
index fcd334b..cf2f976 100644
--- a/libc/test/src/math/smoke/exp10f_test.cpp
+++ b/libc/test/src/math/smoke/exp10f_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/exp10f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcExp10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcExp10fTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/exp2_test.cpp b/libc/test/src/math/smoke/exp2_test.cpp
index aebf808..3d26df1 100644
--- a/libc/test/src/math/smoke/exp2_test.cpp
+++ b/libc/test/src/math/smoke/exp2_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/exp2.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcExp2Test = LIBC_NAMESPACE::testing::FPTest<double>;
TEST_F(LlvmLibcExp2Test, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/exp2f_test.cpp b/libc/test/src/math/smoke/exp2f_test.cpp
index c524327..12bcbec 100644
--- a/libc/test/src/math/smoke/exp2f_test.cpp
+++ b/libc/test/src/math/smoke/exp2f_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/exp2f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcExp2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcExp2fTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/exp_test.cpp b/libc/test/src/math/smoke/exp_test.cpp
index c3b2ae7..4ce3227 100644
--- a/libc/test/src/math/smoke/exp_test.cpp
+++ b/libc/test/src/math/smoke/exp_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/exp.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcExpTest = LIBC_NAMESPACE::testing::FPTest<double>;
TEST_F(LlvmLibcExpTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/expf_test.cpp b/libc/test/src/math/smoke/expf_test.cpp
index d341517..a0e785f 100644
--- a/libc/test/src/math/smoke/expf_test.cpp
+++ b/libc/test/src/math/smoke/expf_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/expf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcExpfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcExpfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/expm1_test.cpp b/libc/test/src/math/smoke/expm1_test.cpp
index c842fe3..db7149d 100644
--- a/libc/test/src/math/smoke/expm1_test.cpp
+++ b/libc/test/src/math/smoke/expm1_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/expm1.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcExpm1Test = LIBC_NAMESPACE::testing::FPTest<double>;
TEST_F(LlvmLibcExpm1Test, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/expm1f_test.cpp b/libc/test/src/math/smoke/expm1f_test.cpp
index 214bfe8..9482bf6f 100644
--- a/libc/test/src/math/smoke/expm1f_test.cpp
+++ b/libc/test/src/math/smoke/expm1f_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/expm1f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcExpm1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcExpm1fTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/log10_test.cpp b/libc/test/src/math/smoke/log10_test.cpp
index 49cfda8..3af27d4 100644
--- a/libc/test/src/math/smoke/log10_test.cpp
+++ b/libc/test/src/math/smoke/log10_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/log10.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcLog10Test = LIBC_NAMESPACE::testing::FPTest<double>;
TEST_F(LlvmLibcLog10Test, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/log10f_test.cpp b/libc/test/src/math/smoke/log10f_test.cpp
index a638221..f15da75 100644
--- a/libc/test/src/math/smoke/log10f_test.cpp
+++ b/libc/test/src/math/smoke/log10f_test.cpp
@@ -7,13 +7,12 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/log10f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcLog10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcLog10fTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/log1pf_test.cpp b/libc/test/src/math/smoke/log1pf_test.cpp
index dc3489f..82c2f94 100644
--- a/libc/test/src/math/smoke/log1pf_test.cpp
+++ b/libc/test/src/math/smoke/log1pf_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/log1pf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcLog1pfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcLog1pfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/log2_test.cpp b/libc/test/src/math/smoke/log2_test.cpp
index 0534d00..6bf1ce3 100644
--- a/libc/test/src/math/smoke/log2_test.cpp
+++ b/libc/test/src/math/smoke/log2_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/log2.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcLog2Test = LIBC_NAMESPACE::testing::FPTest<double>;
TEST_F(LlvmLibcLog2Test, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/log2f_test.cpp b/libc/test/src/math/smoke/log2f_test.cpp
index 53d54ac..80e13a2 100644
--- a/libc/test/src/math/smoke/log2f_test.cpp
+++ b/libc/test/src/math/smoke/log2f_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/log2f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcLog2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcLog2fTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/log_test.cpp b/libc/test/src/math/smoke/log_test.cpp
index 09e9ab0..1d7761a 100644
--- a/libc/test/src/math/smoke/log_test.cpp
+++ b/libc/test/src/math/smoke/log_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/log.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcLogTest = LIBC_NAMESPACE::testing::FPTest<double>;
TEST_F(LlvmLibcLogTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/logf_test.cpp b/libc/test/src/math/smoke/logf_test.cpp
index faba50e..f58209e 100644
--- a/libc/test/src/math/smoke/logf_test.cpp
+++ b/libc/test/src/math/smoke/logf_test.cpp
@@ -7,13 +7,12 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/logf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcLogfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcLogfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/nan_test.cpp b/libc/test/src/math/smoke/nan_test.cpp
index e8376c0..9010b74 100644
--- a/libc/test/src/math/smoke/nan_test.cpp
+++ b/libc/test/src/math/smoke/nan_test.cpp
@@ -8,7 +8,6 @@
#include "hdr/signal_macros.h"
#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/macros/sanitizer.h"
#include "src/math/nan.h"
#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
@@ -44,8 +43,8 @@ TEST_F(LlvmLibcNanTest, RandomString) {
run_test("123 ", 0x7ff8000000000000);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST_F(LlvmLibcNanTest, InvalidInput) {
EXPECT_DEATH([] { LIBC_NAMESPACE::nan(nullptr); }, WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/math/smoke/nanf128_test.cpp b/libc/test/src/math/smoke/nanf128_test.cpp
index a63ce88..40b347d 100644
--- a/libc/test/src/math/smoke/nanf128_test.cpp
+++ b/libc/test/src/math/smoke/nanf128_test.cpp
@@ -8,7 +8,6 @@
#include "hdr/signal_macros.h"
#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/macros/sanitizer.h"
#include "src/__support/uint128.h"
#include "src/math/nanf128.h"
#include "test/UnitTest/FEnvSafeTest.h"
@@ -55,8 +54,8 @@ TEST_F(LlvmLibcNanf128Test, RandomString) {
QUIET_NAN);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST_F(LlvmLibcNanf128Test, InvalidInput) {
EXPECT_DEATH([] { LIBC_NAMESPACE::nanf128(nullptr); }, WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/math/smoke/nanf16_test.cpp b/libc/test/src/math/smoke/nanf16_test.cpp
index 694470b..e05f79c 100644
--- a/libc/test/src/math/smoke/nanf16_test.cpp
+++ b/libc/test/src/math/smoke/nanf16_test.cpp
@@ -8,7 +8,6 @@
#include "hdr/signal_macros.h"
#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/macros/sanitizer.h"
#include "src/math/nanf16.h"
#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
@@ -43,8 +42,8 @@ TEST_F(LlvmLibcNanf16Test, RandomString) {
run_test("123 ", 0x7e00);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST_F(LlvmLibcNanf16Test, InvalidInput) {
EXPECT_DEATH([] { LIBC_NAMESPACE::nanf16(nullptr); }, WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/math/smoke/nanf_test.cpp b/libc/test/src/math/smoke/nanf_test.cpp
index cb57f65..c2fef72 100644
--- a/libc/test/src/math/smoke/nanf_test.cpp
+++ b/libc/test/src/math/smoke/nanf_test.cpp
@@ -8,7 +8,6 @@
#include "hdr/signal_macros.h"
#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/macros/sanitizer.h"
#include "src/math/nanf.h"
#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
@@ -43,8 +42,8 @@ TEST_F(LlvmLibcNanfTest, RandomString) {
run_test("123 ", 0x7fc00000);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST_F(LlvmLibcNanfTest, InvalidInput) {
EXPECT_DEATH([] { LIBC_NAMESPACE::nanf(nullptr); }, WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/math/smoke/nanl_test.cpp b/libc/test/src/math/smoke/nanl_test.cpp
index 3bcb914..b1d46df 100644
--- a/libc/test/src/math/smoke/nanl_test.cpp
+++ b/libc/test/src/math/smoke/nanl_test.cpp
@@ -8,7 +8,6 @@
#include "hdr/signal_macros.h"
#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/macros/sanitizer.h"
#include "src/math/nanl.h"
#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
@@ -71,8 +70,8 @@ TEST_F(LlvmLibcNanlTest, RandomString) {
run_test("123 ", expected);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST_F(LlvmLibcNanlTest, InvalidInput) {
EXPECT_DEATH([] { LIBC_NAMESPACE::nanl(nullptr); }, WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/math/smoke/powf_test.cpp b/libc/test/src/math/smoke/powf_test.cpp
index 0d1a650..76e8e8c 100644
--- a/libc/test/src/math/smoke/powf_test.cpp
+++ b/libc/test/src/math/smoke/powf_test.cpp
@@ -7,13 +7,12 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/powf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcPowfTest = LIBC_NAMESPACE::testing::FPTest<float>;
using LIBC_NAMESPACE::fputil::testing::ForceRoundingMode;
using LIBC_NAMESPACE::fputil::testing::RoundingMode;
diff --git a/libc/test/src/math/smoke/sincosf_test.cpp b/libc/test/src/math/smoke/sincosf_test.cpp
index 8ba0d04..7ff0ba7 100644
--- a/libc/test/src/math/smoke/sincosf_test.cpp
+++ b/libc/test/src/math/smoke/sincosf_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/sincosf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcSinCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcSinCosfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/sinf_test.cpp b/libc/test/src/math/smoke/sinf_test.cpp
index 8173969..8ba66ed 100644
--- a/libc/test/src/math/smoke/sinf_test.cpp
+++ b/libc/test/src/math/smoke/sinf_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/sinf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcSinfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcSinfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/sinhf_test.cpp b/libc/test/src/math/smoke/sinhf_test.cpp
index ea6a447..5976a1f 100644
--- a/libc/test/src/math/smoke/sinhf_test.cpp
+++ b/libc/test/src/math/smoke/sinhf_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
@@ -14,8 +15,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcSinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcSinhfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/sinpif_test.cpp b/libc/test/src/math/smoke/sinpif_test.cpp
index b840f39..4a725e0 100644
--- a/libc/test/src/math/smoke/sinpif_test.cpp
+++ b/libc/test/src/math/smoke/sinpif_test.cpp
@@ -6,12 +6,11 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/libc_errno.h"
#include "src/math/sinpif.h"
#include "test/UnitTest/FPMatcher.h"
-#include <stdint.h>
-
using LlvmLibcSinpifTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcSinpifTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/tanf_test.cpp b/libc/test/src/math/smoke/tanf_test.cpp
index 12deca5..c85907c 100644
--- a/libc/test/src/math/smoke/tanf_test.cpp
+++ b/libc/test/src/math/smoke/tanf_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/tanf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcTanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcTanfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/smoke/tanhf_test.cpp b/libc/test/src/math/smoke/tanhf_test.cpp
index b12a331..57c0573 100644
--- a/libc/test/src/math/smoke/tanhf_test.cpp
+++ b/libc/test/src/math/smoke/tanhf_test.cpp
@@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===//
#include "hdr/math_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/libc_errno.h"
#include "src/math/tanhf.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
using LlvmLibcTanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
TEST_F(LlvmLibcTanhfTest, SpecialNumbers) {
diff --git a/libc/test/src/math/tanf_test.cpp b/libc/test/src/math/tanf_test.cpp
index ecc7019..27949eb 100644
--- a/libc/test/src/math/tanf_test.cpp
+++ b/libc/test/src/math/tanf_test.cpp
@@ -15,7 +15,7 @@
#include "test/src/math/sdcomp26094.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcTanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/tanhf_test.cpp b/libc/test/src/math/tanhf_test.cpp
index 966ce64..27a6cbc 100644
--- a/libc/test/src/math/tanhf_test.cpp
+++ b/libc/test/src/math/tanhf_test.cpp
@@ -14,7 +14,7 @@
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
-#include <stdint.h>
+#include "hdr/stdint_proxy.h"
using LlvmLibcTanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/signal/CMakeLists.txt b/libc/test/src/signal/CMakeLists.txt
index f86ce2a..6b5041d 100644
--- a/libc/test/src/signal/CMakeLists.txt
+++ b/libc/test/src/signal/CMakeLists.txt
@@ -119,6 +119,7 @@ add_libc_unittest(
sigaltstack_test.cpp
DEPENDS
libc.hdr.signal_macros
+ libc.hdr.stdint_proxy
libc.src.errno.errno
libc.src.signal.raise
libc.src.signal.sigaltstack
diff --git a/libc/test/src/signal/sigaltstack_test.cpp b/libc/test/src/signal/sigaltstack_test.cpp
index ce4dfdd..a9c5cd9 100644
--- a/libc/test/src/signal/sigaltstack_test.cpp
+++ b/libc/test/src/signal/sigaltstack_test.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "hdr/signal_macros.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/libc_errno.h"
#include "src/signal/linux/signal_utils.h"
@@ -16,7 +17,6 @@
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
#include <sys/syscall.h>
constexpr int LOCAL_VAR_SIZE = 512;
diff --git a/libc/test/src/spawn/CMakeLists.txt b/libc/test/src/spawn/CMakeLists.txt
index ce246d4..04814db 100644
--- a/libc/test/src/spawn/CMakeLists.txt
+++ b/libc/test/src/spawn/CMakeLists.txt
@@ -7,6 +7,7 @@ add_libc_unittest(
SRCS
posix_spawn_file_actions_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.spawn
libc.src.spawn.file_actions
libc.src.spawn.posix_spawn_file_actions_addclose
diff --git a/libc/test/src/spawn/posix_spawn_file_actions_test.cpp b/libc/test/src/spawn/posix_spawn_file_actions_test.cpp
index 01ccb82..935a354 100644
--- a/libc/test/src/spawn/posix_spawn_file_actions_test.cpp
+++ b/libc/test/src/spawn/posix_spawn_file_actions_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/libc_errno.h"
#include "src/spawn/file_actions.h"
#include "src/spawn/posix_spawn_file_actions_addclose.h"
@@ -16,7 +17,6 @@
#include "test/UnitTest/Test.h"
#include <spawn.h>
-#include <stdint.h>
TEST(LlvmLibcPosixSpawnFileActionsTest, AddActions) {
posix_spawn_file_actions_t actions;
diff --git a/libc/test/src/stdfix/IdivTest.h b/libc/test/src/stdfix/IdivTest.h
index 0e9cc40..28c39f4 100644
--- a/libc/test/src/stdfix/IdivTest.h
+++ b/libc/test/src/stdfix/IdivTest.h
@@ -71,7 +71,7 @@ public:
}
};
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
#define LIST_IDIV_TESTS(Name, T, XType, func) \
using LlvmLibcIdiv##Name##Test = IdivTest<T, XType>; \
TEST_F(LlvmLibcIdiv##Name##Test, InvalidNumbers) { \
@@ -88,4 +88,4 @@ public:
testSpecialNumbers(&func); \
} \
static_assert(true, "Require semicolon.")
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/stdio/fdopen_test.cpp b/libc/test/src/stdio/fdopen_test.cpp
index b53184c..bab1d33 100644
--- a/libc/test/src/stdio/fdopen_test.cpp
+++ b/libc/test/src/stdio/fdopen_test.cpp
@@ -24,7 +24,8 @@ using LlvmLibcStdioFdopenTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
TEST_F(LlvmLibcStdioFdopenTest, WriteAppendRead) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *TEST_FILE_NAME = "testdata/write_read_append.test";
+ constexpr const char *TEST_FILE_NAME =
+ APPEND_LIBC_TEST("testdata/write_read_append.test");
auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
auto *fp = LIBC_NAMESPACE::fdopen(fd, "w");
@@ -54,7 +55,8 @@ TEST_F(LlvmLibcStdioFdopenTest, WriteAppendRead) {
}
TEST_F(LlvmLibcStdioFdopenTest, InvalidFd) {
- constexpr const char *TEST_FILE_NAME = "testdata/invalid_fd.test";
+ constexpr const char *TEST_FILE_NAME =
+ APPEND_LIBC_TEST("testdata/invalid_fd.test");
auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC);
LIBC_NAMESPACE::close(fd);
@@ -65,7 +67,8 @@ TEST_F(LlvmLibcStdioFdopenTest, InvalidFd) {
}
TEST_F(LlvmLibcStdioFdopenTest, InvalidMode) {
- constexpr const char *TEST_FILE_NAME = "testdata/invalid_mode.test";
+ constexpr const char *TEST_FILE_NAME =
+ APPEND_LIBC_TEST("testdata/invalid_mode.test");
auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_RDONLY, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
diff --git a/libc/test/src/stdio/fgetc_test.cpp b/libc/test/src/stdio/fgetc_test.cpp
index be2e502..1d242a0 100644
--- a/libc/test/src/stdio/fgetc_test.cpp
+++ b/libc/test/src/stdio/fgetc_test.cpp
@@ -56,9 +56,10 @@ public:
};
TEST_F(LlvmLibcGetcTest, WriteAndReadCharactersWithFgetc) {
- test_with_func(&LIBC_NAMESPACE::fgetc, "testdata/fgetc.test");
+ test_with_func(&LIBC_NAMESPACE::fgetc,
+ APPEND_LIBC_TEST("testdata/fgetc.test"));
}
TEST_F(LlvmLibcGetcTest, WriteAndReadCharactersWithGetc) {
- test_with_func(&LIBC_NAMESPACE::getc, "testdata/getc.test");
+ test_with_func(&LIBC_NAMESPACE::getc, APPEND_LIBC_TEST("testdata/getc.test"));
}
diff --git a/libc/test/src/stdio/fgetc_unlocked_test.cpp b/libc/test/src/stdio/fgetc_unlocked_test.cpp
index bef9daf..16d7921 100644
--- a/libc/test/src/stdio/fgetc_unlocked_test.cpp
+++ b/libc/test/src/stdio/fgetc_unlocked_test.cpp
@@ -62,9 +62,10 @@ public:
TEST_F(LlvmLibcGetcTest, WriteAndReadCharactersWithFgetcUnlocked) {
test_with_func(&LIBC_NAMESPACE::fgetc_unlocked,
- "testdata/fgetc_unlocked.test");
+ APPEND_LIBC_TEST("testdata/fgetc_unlocked.test"));
}
TEST_F(LlvmLibcGetcTest, WriteAndReadCharactersWithGetcUnlocked) {
- test_with_func(&LIBC_NAMESPACE::getc_unlocked, "testdata/getc_unlocked.test");
+ test_with_func(&LIBC_NAMESPACE::getc_unlocked,
+ APPEND_LIBC_TEST("testdata/getc_unlocked.test"));
}
diff --git a/libc/test/src/stdio/fgets_test.cpp b/libc/test/src/stdio/fgets_test.cpp
index 8fc38b0..14f054e 100644
--- a/libc/test/src/stdio/fgets_test.cpp
+++ b/libc/test/src/stdio/fgets_test.cpp
@@ -20,7 +20,7 @@ using LlvmLibcFgetsTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
TEST_F(LlvmLibcFgetsTest, WriteAndReadCharacters) {
- constexpr char FILENAME[] = "testdata/fgets.test";
+ constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/fgets.test");
::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
constexpr char CONTENT[] = "123456789\n"
diff --git a/libc/test/src/stdio/fileop_test.cpp b/libc/test/src/stdio/fileop_test.cpp
index e097785..0232804 100644
--- a/libc/test/src/stdio/fileop_test.cpp
+++ b/libc/test/src/stdio/fileop_test.cpp
@@ -29,7 +29,8 @@ using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::NE;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::returns;
TEST_F(LlvmLibcFILETest, SimpleFileOperations) {
- constexpr char FILENAME[] = "testdata/simple_operations.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/simple_operations.test");
::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
ASSERT_GE(LIBC_NAMESPACE::fileno(file), 0);
@@ -127,7 +128,7 @@ TEST_F(LlvmLibcFILETest, SimpleFileOperations) {
}
TEST_F(LlvmLibcFILETest, FFlush) {
- constexpr char FILENAME[] = "testdata/fflush.test";
+ constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/fflush.test");
::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w+");
ASSERT_FALSE(file == nullptr);
constexpr char CONTENT[] = "1234567890987654321";
@@ -154,7 +155,7 @@ TEST_F(LlvmLibcFILETest, FOpenFWriteSizeGreaterThanOne) {
};
constexpr MyStruct WRITE_DATA[] = {{'a', 1}, {'b', 2}, {'c', 3}};
constexpr size_t WRITE_NMEMB = sizeof(WRITE_DATA) / sizeof(MyStruct);
- constexpr char FILENAME[] = "testdata/fread_fwrite.test";
+ constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/fread_fwrite.test");
FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
diff --git a/libc/test/src/stdio/fopen_test.cpp b/libc/test/src/stdio/fopen_test.cpp
index 42e7c57..3f651f7 100644
--- a/libc/test/src/stdio/fopen_test.cpp
+++ b/libc/test/src/stdio/fopen_test.cpp
@@ -17,7 +17,8 @@
TEST(LlvmLibcFOpenTest, PrintToFile) {
int result;
- FILE *file = LIBC_NAMESPACE::fopen("./testdata/test_data.txt", "w");
+ FILE *file =
+ LIBC_NAMESPACE::fopen(APPEND_LIBC_TEST("testdata/test.txt"), "w");
ASSERT_FALSE(file == nullptr);
static constexpr char STRING[] = "A simple string written to a file\n";
@@ -26,7 +27,8 @@ TEST(LlvmLibcFOpenTest, PrintToFile) {
ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
- FILE *new_file = LIBC_NAMESPACE::fopen("./testdata/test_data.txt", "r");
+ FILE *new_file =
+ LIBC_NAMESPACE::fopen(APPEND_LIBC_TEST("testdata/test.txt"), "r");
ASSERT_FALSE(new_file == nullptr);
static char data[64] = {0};
diff --git a/libc/test/src/stdio/fprintf_test.cpp b/libc/test/src/stdio/fprintf_test.cpp
index 82a3e03..6799323 100644
--- a/libc/test/src/stdio/fprintf_test.cpp
+++ b/libc/test/src/stdio/fprintf_test.cpp
@@ -32,7 +32,7 @@ using ::fread;
} // namespace printf_test
TEST(LlvmLibcFPrintfTest, WriteToFile) {
- const char *FILENAME = "fprintf_output.test";
+ const char *FILENAME = APPEND_LIBC_TEST("fprintf_output.test");
auto FILE_PATH = libc_make_test_file_path(FILENAME);
::FILE *file = printf_test::fopen(FILE_PATH, "w");
diff --git a/libc/test/src/stdio/fscanf_test.cpp b/libc/test/src/stdio/fscanf_test.cpp
index e5b8c4f..451ff94 100644
--- a/libc/test/src/stdio/fscanf_test.cpp
+++ b/libc/test/src/stdio/fscanf_test.cpp
@@ -34,7 +34,7 @@ using ::fwrite;
} // namespace scanf_test
TEST(LlvmLibcFScanfTest, WriteToFile) {
- const char *FILENAME = "fscanf_output.test";
+ const char *FILENAME = APPEND_LIBC_TEST("fscanf_output.test");
auto FILE_PATH = libc_make_test_file_path(FILENAME);
::FILE *file = scanf_test::fopen(FILE_PATH, "w");
ASSERT_FALSE(file == nullptr);
diff --git a/libc/test/src/stdio/ftell_test.cpp b/libc/test/src/stdio/ftell_test.cpp
index 01ff071..1f762f3 100644
--- a/libc/test/src/stdio/ftell_test.cpp
+++ b/libc/test/src/stdio/ftell_test.cpp
@@ -21,7 +21,7 @@
class LlvmLibcFTellTest : public LIBC_NAMESPACE::testing::Test {
protected:
void test_with_bufmode(int bufmode) {
- constexpr char FILENAME[] = "testdata/ftell.test";
+ constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/ftell.test");
// We will set a special buffer to the file so that we guarantee buffering.
constexpr size_t BUFFER_SIZE = 1024;
char buffer[BUFFER_SIZE];
diff --git a/libc/test/src/stdio/putc_test.cpp b/libc/test/src/stdio/putc_test.cpp
index e881a0e..6bf4827 100644
--- a/libc/test/src/stdio/putc_test.cpp
+++ b/libc/test/src/stdio/putc_test.cpp
@@ -16,7 +16,7 @@
#include "test/UnitTest/Test.h"
TEST(LlvmLibcPutcTest, WriteToFile) {
- constexpr char FILENAME[] = "testdata/putc_output.test";
+ constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/putc_output.test");
::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
diff --git a/libc/test/src/stdio/remove_test.cpp b/libc/test/src/stdio/remove_test.cpp
index 296bff1..20d166f0 100644
--- a/libc/test/src/stdio/remove_test.cpp
+++ b/libc/test/src/stdio/remove_test.cpp
@@ -25,7 +25,7 @@ TEST_F(LlvmLibcRemoveTest, CreateAndRemoveFile) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *FILENAME = "remove.test.file";
+ constexpr const char *FILENAME = APPEND_LIBC_TEST("remove.test.file");
auto TEST_FILE = libc_make_test_file_path(FILENAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
@@ -42,7 +42,7 @@ TEST_F(LlvmLibcRemoveTest, CreateAndRemoveDir) {
// it was removed.
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *FILENAME = "remove.test.dir";
+ constexpr const char *FILENAME = APPEND_LIBC_TEST("remove.test.dir");
auto TEST_DIR = libc_make_test_file_path(FILENAME);
ASSERT_THAT(LIBC_NAMESPACE::mkdirat(AT_FDCWD, TEST_DIR, S_IRWXU),
Succeeds(0));
diff --git a/libc/test/src/stdio/rename_test.cpp b/libc/test/src/stdio/rename_test.cpp
index 135fb98..af957e0 100644
--- a/libc/test/src/stdio/rename_test.cpp
+++ b/libc/test/src/stdio/rename_test.cpp
@@ -24,7 +24,7 @@ TEST_F(LlvmLibcRenameTest, CreateAndRenameFile) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
- constexpr const char *FILENAME0 = "rename.test.file0";
+ constexpr const char *FILENAME0 = APPEND_LIBC_TEST("rename.test.file0");
auto TEST_FILEPATH0 = libc_make_test_file_path(FILENAME0);
int fd = LIBC_NAMESPACE::open(TEST_FILEPATH0, O_WRONLY | O_CREAT, S_IRWXU);
@@ -33,7 +33,7 @@ TEST_F(LlvmLibcRenameTest, CreateAndRenameFile) {
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
ASSERT_THAT(LIBC_NAMESPACE::access(TEST_FILEPATH0, F_OK), Succeeds(0));
- constexpr const char *FILENAME1 = "rename.test.file1";
+ constexpr const char *FILENAME1 = APPEND_LIBC_TEST("rename.test.file1");
auto TEST_FILEPATH1 = libc_make_test_file_path(FILENAME1);
ASSERT_THAT(LIBC_NAMESPACE::rename(TEST_FILEPATH0, TEST_FILEPATH1),
Succeeds(0));
@@ -44,7 +44,7 @@ TEST_F(LlvmLibcRenameTest, CreateAndRenameFile) {
TEST_F(LlvmLibcRenameTest, RenameNonExistent) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
- constexpr const char *FILENAME1 = "rename.test.file1";
+ constexpr const char *FILENAME1 = APPEND_LIBC_TEST("rename.test.file1");
auto TEST_FILEPATH1 = libc_make_test_file_path(FILENAME1);
ASSERT_THAT(LIBC_NAMESPACE::rename("non-existent", TEST_FILEPATH1),
diff --git a/libc/test/src/stdio/setbuf_test.cpp b/libc/test/src/stdio/setbuf_test.cpp
index 25fea59..f1f98f7 100644
--- a/libc/test/src/stdio/setbuf_test.cpp
+++ b/libc/test/src/stdio/setbuf_test.cpp
@@ -18,7 +18,8 @@
TEST(LlvmLibcSetbufTest, DefaultBufsize) {
// The idea in this test is to change the buffer after opening a file and
// ensure that read and write work as expected.
- constexpr char FILENAME[] = "testdata/setbuf_test_default_bufsize.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/setbuf_test_default_bufsize.test");
::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
char buffer[BUFSIZ];
@@ -41,7 +42,8 @@ TEST(LlvmLibcSetbufTest, DefaultBufsize) {
TEST(LlvmLibcSetbufTest, NullBuffer) {
// The idea in this test is that we set a null buffer and ensure that
// everything works correctly.
- constexpr char FILENAME[] = "testdata/setbuf_test_null_buffer.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/setbuf_test_null_buffer.test");
::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
LIBC_NAMESPACE::setbuf(file, nullptr);
diff --git a/libc/test/src/stdio/setvbuf_test.cpp b/libc/test/src/stdio/setvbuf_test.cpp
index a0936ba..f55b8e2 100644
--- a/libc/test/src/stdio/setvbuf_test.cpp
+++ b/libc/test/src/stdio/setvbuf_test.cpp
@@ -23,7 +23,7 @@ TEST_F(LlvmLibcSetvbufTest, SetNBFBuffer) {
// then set a NBF buffer to the write handle. Since it is NBF, the data
// written using the write handle should be immediately readable by the read
// handle.
- constexpr char FILENAME[] = "testdata/setvbuf_nbf.test";
+ constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/setvbuf_nbf.test");
::FILE *fw = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(fw == nullptr);
@@ -59,7 +59,7 @@ TEST_F(LlvmLibcSetvbufTest, SetLBFBuffer) {
// then set a LBF buffer to the write handle. Since it is LBF, the data
// written using the write handle should be available right after a '\n' is
// written.
- constexpr char FILENAME[] = "testdata/setvbuf_lbf.test";
+ constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/setvbuf_lbf.test");
::FILE *fw = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(fw == nullptr);
@@ -96,7 +96,8 @@ TEST_F(LlvmLibcSetvbufTest, SetLBFBuffer) {
}
TEST(LlvmLibcSetbufTest, InvalidBufferMode) {
- constexpr char FILENAME[] = "testdata/setvbuf_invalid_bufmode.test";
+ constexpr char FILENAME[] =
+ APPEND_LIBC_TEST("testdata/setvbuf_invalid_bufmode.test");
::FILE *f = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(f == nullptr);
char buf[BUFSIZ];
diff --git a/libc/test/src/stdio/ungetc_test.cpp b/libc/test/src/stdio/ungetc_test.cpp
index b9d7530..917dbc2 100644
--- a/libc/test/src/stdio/ungetc_test.cpp
+++ b/libc/test/src/stdio/ungetc_test.cpp
@@ -17,7 +17,7 @@
#include "test/UnitTest/Test.h"
TEST(LlvmLibcUngetcTest, UngetAndReadBack) {
- constexpr char FILENAME[] = "testdata/ungetc_test.test";
+ constexpr char FILENAME[] = APPEND_LIBC_TEST("testdata/ungetc_test.test");
::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
constexpr char CONTENT[] = "abcdef";
diff --git a/libc/test/src/stdio/unlocked_fileop_test.cpp b/libc/test/src/stdio/unlocked_fileop_test.cpp
index e99b382..7af7eca 100644
--- a/libc/test/src/stdio/unlocked_fileop_test.cpp
+++ b/libc/test/src/stdio/unlocked_fileop_test.cpp
@@ -21,7 +21,8 @@
using LlvmLibcFILETest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
TEST_F(LlvmLibcFILETest, UnlockedReadAndWrite) {
- constexpr char fNAME[] = "testdata/unlocked_read_and_write.test";
+ constexpr char fNAME[] =
+ APPEND_LIBC_TEST("testdata/unlocked_read_and_write.test");
::FILE *f = LIBC_NAMESPACE::fopen(fNAME, "w");
ASSERT_FALSE(f == nullptr);
constexpr char CONTENT[] = "1234567890987654321";
diff --git a/libc/test/src/stdio/vfprintf_test.cpp b/libc/test/src/stdio/vfprintf_test.cpp
index 80d4845..f50565a 100644
--- a/libc/test/src/stdio/vfprintf_test.cpp
+++ b/libc/test/src/stdio/vfprintf_test.cpp
@@ -45,7 +45,7 @@ int call_vfprintf(::FILE *__restrict stream, const char *__restrict format,
}
TEST(LlvmLibcVFPrintfTest, WriteToFile) {
- const char *FILENAME = "vfprintf_output.test";
+ const char *FILENAME = APPEND_LIBC_TEST("vfprintf_output.test");
auto FILE_PATH = libc_make_test_file_path(FILENAME);
::FILE *file = printf_test::fopen(FILE_PATH, "w");
diff --git a/libc/test/src/stdio/vfscanf_test.cpp b/libc/test/src/stdio/vfscanf_test.cpp
index b665386..38a64611 100644
--- a/libc/test/src/stdio/vfscanf_test.cpp
+++ b/libc/test/src/stdio/vfscanf_test.cpp
@@ -42,7 +42,7 @@ static int call_vfscanf(::FILE *stream, const char *__restrict format, ...) {
}
TEST(LlvmLibcVFScanfTest, WriteToFile) {
- const char *FILENAME = "vfscanf_output.test";
+ const char *FILENAME = APPEND_LIBC_TEST("vfscanf_output.test");
auto FILE_PATH = libc_make_test_file_path(FILENAME);
::FILE *file = scanf_test::fopen(FILE_PATH, "w");
ASSERT_FALSE(file == nullptr);
diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
index 45fd49b..0eb373c 100644
--- a/libc/test/src/stdlib/CMakeLists.txt
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -99,6 +99,7 @@ add_libc_test(
SRCS
strtoint32_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.str_to_integer
libc.src.errno.errno
.strtol_test_support
@@ -111,6 +112,7 @@ add_libc_test(
SRCS
strtoint64_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.str_to_integer
libc.src.errno.errno
.strtol_test_support
@@ -380,6 +382,7 @@ add_libc_test(
SRCS
memalignment_test.cpp
DEPENDS
+ libc.hdr.stdint_proxy
libc.include.stdlib
libc.src.stdlib.memalignment
)
diff --git a/libc/test/src/stdlib/memalignment_test.cpp b/libc/test/src/stdlib/memalignment_test.cpp
index 2ca1b79..f1640e9 100644
--- a/libc/test/src/stdlib/memalignment_test.cpp
+++ b/libc/test/src/stdlib/memalignment_test.cpp
@@ -6,11 +6,10 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/stdlib/memalignment.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
TEST(LlvmLibcMemAlignmentTest, NullPointer) {
void *ptr = nullptr;
EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr), static_cast<size_t>(0));
diff --git a/libc/test/src/stdlib/strtoint32_test.cpp b/libc/test/src/stdlib/strtoint32_test.cpp
index e6da692..1bf1994 100644
--- a/libc/test/src/stdlib/strtoint32_test.cpp
+++ b/libc/test/src/stdlib/strtoint32_test.cpp
@@ -6,8 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <stdint.h>
-
+#include "hdr/stdint_proxy.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_integer.h"
diff --git a/libc/test/src/stdlib/strtoint64_test.cpp b/libc/test/src/stdlib/strtoint64_test.cpp
index 2c5d948..2b009d7 100644
--- a/libc/test/src/stdlib/strtoint64_test.cpp
+++ b/libc/test/src/stdlib/strtoint64_test.cpp
@@ -6,8 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include <stdint.h>
-
+#include "hdr/stdint_proxy.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/str_to_integer.h"
diff --git a/libc/test/src/string/memchr_test.cpp b/libc/test/src/string/memchr_test.cpp
index 1455183..4a7c88b 100644
--- a/libc/test/src/string/memchr_test.cpp
+++ b/libc/test/src/string/memchr_test.cpp
@@ -122,11 +122,11 @@ TEST(LlvmLibcMemChrTest, SignedCharacterFound) {
ASSERT_EQ(actual[0], c);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcMemChrTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::memchr(nullptr, 1, 1); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
diff --git a/libc/test/src/string/memcmp_test.cpp b/libc/test/src/string/memcmp_test.cpp
index 3dfbced..99d08a4 100644
--- a/libc/test/src/string/memcmp_test.cpp
+++ b/libc/test/src/string/memcmp_test.cpp
@@ -66,13 +66,13 @@ TEST(LlvmLibcMemcmpTest, SizeSweep) {
}
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcMemcmpTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::memcmp(nullptr, nullptr, 1); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/string/memcpy_test.cpp b/libc/test/src/string/memcpy_test.cpp
index 8c43ac8..03a3d13 100644
--- a/libc/test/src/string/memcpy_test.cpp
+++ b/libc/test/src/string/memcpy_test.cpp
@@ -73,12 +73,12 @@ TEST(LlvmLibcMemcpyTest, CheckAccess) {
#endif // !defined(LIBC_FULL_BUILD) && defined(LIBC_TARGET_OS_IS_LINUX)
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcMemcpyTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::memcpy(nullptr, nullptr, 1); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/string/memmove_test.cpp b/libc/test/src/string/memmove_test.cpp
index 0d47655..60ac680 100644
--- a/libc/test/src/string/memmove_test.cpp
+++ b/libc/test/src/string/memmove_test.cpp
@@ -104,13 +104,13 @@ TEST(LlvmLibcMemmoveTest, SizeSweep) {
}
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcMemmoveTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::memmove(nullptr, nullptr, 2); },
WITH_SIGNAL(-1));
}
-#endif // LIBC_TARGET_OS_IS_LINUX
+#endif // LIBC_ADD_NULL_CHECKS
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/string/memory_utils/CMakeLists.txt b/libc/test/src/string/memory_utils/CMakeLists.txt
index 8374be4..d6d6d09 100644
--- a/libc/test/src/string/memory_utils/CMakeLists.txt
+++ b/libc/test/src/string/memory_utils/CMakeLists.txt
@@ -9,6 +9,7 @@ add_libc_test(
COMPILE_OPTIONS
${LIBC_COMPILE_OPTIONS_NATIVE}
DEPENDS
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.array
libc.src.__support.CPP.cstddef
libc.src.__support.CPP.span
diff --git a/libc/test/src/string/memory_utils/memory_check_utils.h b/libc/test/src/string/memory_utils/memory_check_utils.h
index db9cfda..c38039e 100644
--- a/libc/test/src/string/memory_utils/memory_check_utils.h
+++ b/libc/test/src/string/memory_utils/memory_check_utils.h
@@ -9,13 +9,13 @@
#ifndef LIBC_TEST_SRC_STRING_MEMORY_UTILS_MEMORY_CHECK_UTILS_H
#define LIBC_TEST_SRC_STRING_MEMORY_UTILS_MEMORY_CHECK_UTILS_H
+#include "hdr/stdint_proxy.h" // uintxx_t
#include "src/__support/CPP/span.h"
#include "src/__support/libc_assert.h" // LIBC_ASSERT
#include "src/__support/macros/config.h"
#include "src/__support/macros/sanitizer.h"
#include "src/string/memory_utils/utils.h"
#include <stddef.h> // size_t
-#include <stdint.h> // uintxx_t
#include <stdlib.h> // malloc/free
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/src/string/memory_utils/protected_pages.h b/libc/test/src/string/memory_utils/protected_pages.h
index 50cfbaa..65578d1 100644
--- a/libc/test/src/string/memory_utils/protected_pages.h
+++ b/libc/test/src/string/memory_utils/protected_pages.h
@@ -18,9 +18,9 @@
#error "Protected pages requires mmap and cannot be used in full build mode."
#endif // defined(LIBC_FULL_BUILD) || !defined(LIBC_TARGET_OS_IS_LINUX)
+#include "hdr/stdint_proxy.h" // uint8_t
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include <stddef.h> // size_t
-#include <stdint.h> // uint8_t
#include <sys/mman.h> // mmap, munmap
#include <unistd.h> // sysconf, _SC_PAGESIZE
diff --git a/libc/test/src/string/mempcpy_test.cpp b/libc/test/src/string/mempcpy_test.cpp
index 24482a8..7351a82 100644
--- a/libc/test/src/string/mempcpy_test.cpp
+++ b/libc/test/src/string/mempcpy_test.cpp
@@ -27,11 +27,11 @@ TEST(LlvmLibcMempcpyTest, ZeroCount) {
ASSERT_EQ(static_cast<char *>(result), dest + 0);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcMempcpyTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::mempcpy(nullptr, nullptr, 1); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
diff --git a/libc/test/src/string/memrchr_test.cpp b/libc/test/src/string/memrchr_test.cpp
index c73a479..140395b 100644
--- a/libc/test/src/string/memrchr_test.cpp
+++ b/libc/test/src/string/memrchr_test.cpp
@@ -114,11 +114,11 @@ TEST(LlvmLibcMemRChrTest, ZeroLengthShouldReturnNullptr) {
ASSERT_STREQ(call_memrchr(src, 'd', 0), nullptr);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcMemRChrTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::memrchr(nullptr, 'd', 1); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
diff --git a/libc/test/src/string/memset_test.cpp b/libc/test/src/string/memset_test.cpp
index 9562d2d2..8268d31 100644
--- a/libc/test/src/string/memset_test.cpp
+++ b/libc/test/src/string/memset_test.cpp
@@ -60,13 +60,13 @@ TEST(LlvmLibcMemsetTest, CheckAccess) {
#endif // !defined(LIBC_FULL_BUILD) && defined(LIBC_TARGET_OS_IS_LINUX)
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcMemsetTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::memset(nullptr, 0, 1); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/string/stpncpy_test.cpp b/libc/test/src/string/stpncpy_test.cpp
index f5c61e2..8344926 100644
--- a/libc/test/src/string/stpncpy_test.cpp
+++ b/libc/test/src/string/stpncpy_test.cpp
@@ -73,11 +73,11 @@ TEST_F(LlvmLibcStpncpyTest, CopyTwoWithNull) {
check_stpncpy(dst, src, 2, expected, 1);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST_F(LlvmLibcStpncpyTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::stpncpy(nullptr, nullptr, 1); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
diff --git a/libc/test/src/string/strcat_test.cpp b/libc/test/src/string/strcat_test.cpp
index 20f8d11..baaf455 100644
--- a/libc/test/src/string/strcat_test.cpp
+++ b/libc/test/src/string/strcat_test.cpp
@@ -37,11 +37,11 @@ TEST(LlvmLibcStrCatTest, NonEmptyDest) {
ASSERT_STREQ(dest, "xyzabc");
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcStrCatTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::strcat(nullptr, nullptr); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
diff --git a/libc/test/src/string/strcoll_test.cpp b/libc/test/src/string/strcoll_test.cpp
index 268e232..1be7568 100644
--- a/libc/test/src/string/strcoll_test.cpp
+++ b/libc/test/src/string/strcoll_test.cpp
@@ -30,11 +30,11 @@ TEST(LlvmLibcStrcollTest, SimpleTest) {
ASSERT_GT(result, 0);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcStrcollTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::strcoll(nullptr, nullptr); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
diff --git a/libc/test/src/string/strcpy_test.cpp b/libc/test/src/string/strcpy_test.cpp
index ead60be..0041d38 100644
--- a/libc/test/src/string/strcpy_test.cpp
+++ b/libc/test/src/string/strcpy_test.cpp
@@ -44,11 +44,11 @@ TEST(LlvmLibcStrCpyTest, OffsetDest) {
ASSERT_STREQ(dest, "xyzabc");
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcStrCpyTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::strcpy(nullptr, nullptr); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
diff --git a/libc/test/src/string/strsep_test.cpp b/libc/test/src/string/strsep_test.cpp
index 6f02ce3..06318de 100644
--- a/libc/test/src/string/strsep_test.cpp
+++ b/libc/test/src/string/strsep_test.cpp
@@ -53,11 +53,11 @@ TEST(LlvmLibcStrsepTest, DelimitersShouldNotBeIncludedInToken) {
}
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcStrsepTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::strsep(nullptr, nullptr); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
diff --git a/libc/test/src/string/strspn_test.cpp b/libc/test/src/string/strspn_test.cpp
index adf9a45..82f9b2a 100644
--- a/libc/test/src/string/strspn_test.cpp
+++ b/libc/test/src/string/strspn_test.cpp
@@ -85,11 +85,11 @@ TEST(LlvmLibcStrSpnTest, DuplicatedCharactersToBeSearchedForShouldStillMatch) {
EXPECT_EQ(LIBC_NAMESPACE::strspn("aaaa", "aa"), size_t{4});
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcStrSpnTest, CrashOnNullPtr) {
ASSERT_DEATH([]() { LIBC_NAMESPACE::strspn(nullptr, nullptr); },
WITH_SIGNAL(-1));
}
-#endif // defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#endif // defined(LIBC_ADD_NULL_CHECKS)
diff --git a/libc/test/src/sys/epoll/linux/epoll_create_test.cpp b/libc/test/src/sys/epoll/linux/epoll_create_test.cpp
index 06c17c6..2bbfe4f 100644
--- a/libc/test/src/sys/epoll/linux/epoll_create_test.cpp
+++ b/libc/test/src/sys/epoll/linux/epoll_create_test.cpp
@@ -10,7 +10,6 @@
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"
-#include <sys/syscall.h> // For syscall numbers.
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
using LlvmLibcEpollCreateTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
@@ -23,8 +22,6 @@ TEST_F(LlvmLibcEpollCreateTest, Basic) {
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
}
-#ifdef SYS_epoll_create
TEST_F(LlvmLibcEpollCreateTest, Fails) {
ASSERT_THAT(LIBC_NAMESPACE::epoll_create(0), Fails(EINVAL));
}
-#endif
diff --git a/libc/test/src/wchar/CMakeLists.txt b/libc/test/src/wchar/CMakeLists.txt
index 176cf7c..fad89dc 100644
--- a/libc/test/src/wchar/CMakeLists.txt
+++ b/libc/test/src/wchar/CMakeLists.txt
@@ -25,6 +25,17 @@ add_libc_test(
)
add_libc_test(
+ wcsdup_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ wcsdup_test.cpp
+ DEPENDS
+ libc.hdr.types.wchar_t
+ libc.src.wchar.wcsdup
+)
+
+add_libc_test(
btowc_test
SUITE
libc_wchar_unittests
@@ -65,6 +76,48 @@ add_libc_test(
)
add_libc_test(
+ mblen_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ mblen_test.cpp
+ DEPENDS
+ libc.src.__support.libc_errno
+ libc.src.wchar.mblen
+ libc.test.UnitTest.ErrnoCheckingTest
+)
+
+add_libc_test(
+ mbrlen_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ mbrlen_test.cpp
+ DEPENDS
+ libc.src.__support.libc_errno
+ libc.src.__support.wchar.mbstate
+ libc.src.string.memset
+ libc.src.wchar.mbrlen
+ libc.hdr.types.mbstate_t
+ libc.hdr.types.wchar_t
+ libc.test.UnitTest.ErrnoCheckingTest
+)
+
+add_libc_test(
+ mbsinit_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ mbsinit_test.cpp
+ DEPENDS
+ libc.src.string.memset
+ libc.src.wchar.mbsinit
+ libc.src.wchar.mbrtowc
+ libc.hdr.types.mbstate_t
+ libc.hdr.types.wchar_t
+)
+
+add_libc_test(
wctob_test
SUITE
libc_wchar_unittests
@@ -102,6 +155,46 @@ add_libc_test(
)
add_libc_test(
+ wcstombs_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ wcstombs_test.cpp
+ DEPENDS
+ libc.src.wchar.wcstombs
+ libc.test.UnitTest.ErrnoCheckingTest
+ libc.hdr.types.wchar_t
+)
+
+add_libc_test(
+ wcsrtombs_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ wcsrtombs_test.cpp
+ DEPENDS
+ libc.src.wchar.wcsrtombs
+ libc.test.UnitTest.ErrnoCheckingTest
+ libc.hdr.types.wchar_t
+ libc.src.string.memset
+ libc.hdr.types.mbstate_t
+)
+
+add_libc_test(
+ wcsnrtombs_test
+ SUITE
+ libc_wchar_unittests
+ SRCS
+ wcsnrtombs_test.cpp
+ DEPENDS
+ libc.src.wchar.wcsnrtombs
+ libc.test.UnitTest.ErrnoCheckingTest
+ libc.hdr.types.wchar_t
+ libc.src.string.memset
+ libc.hdr.types.mbstate_t
+)
+
+add_libc_test(
wmemset_test
SUITE
libc_wchar_unittests
diff --git a/libc/test/src/wchar/mblen_test.cpp b/libc/test/src/wchar/mblen_test.cpp
new file mode 100644
index 0000000..efd4df7
--- /dev/null
+++ b/libc/test/src/wchar/mblen_test.cpp
@@ -0,0 +1,104 @@
+//===-- Unittests 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/libc_errno.h"
+#include "src/wchar/mblen.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcMBLenTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcMBLenTest, OneByte) {
+ const char *ch = "A";
+ int n = LIBC_NAMESPACE::mblen(ch, 1);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(n, 1);
+
+ // Should fail since we have not read enough
+ n = LIBC_NAMESPACE::mblen(ch, 0);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(n, -1);
+}
+
+TEST_F(LlvmLibcMBLenTest, TwoByte) {
+ const char ch[2] = {static_cast<char>(0xC2),
+ static_cast<char>(0x8E)}; // Ž car symbol
+ int n = LIBC_NAMESPACE::mblen(ch, 4);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(n, 2);
+
+ // Should fail since we have not read enough
+ n = LIBC_NAMESPACE::mblen(ch, 1);
+ ASSERT_EQ(n, -1);
+ ASSERT_ERRNO_SUCCESS();
+ // Should fail after trying to read next byte too
+ n = LIBC_NAMESPACE::mblen(ch + 1, 1);
+ ASSERT_EQ(n, -1);
+ // This one should be an invalid starting byte so should set errno
+ ASSERT_ERRNO_EQ(EILSEQ);
+}
+
+TEST_F(LlvmLibcMBLenTest, ThreeByte) {
+ const char ch[3] = {static_cast<char>(0xE2), static_cast<char>(0x88),
+ static_cast<char>(0x91)}; // ∑ sigma symbol
+ int n = LIBC_NAMESPACE::mblen(ch, 3);
+ ASSERT_EQ(n, 3);
+ ASSERT_ERRNO_SUCCESS();
+
+ // Should fail since we have not read enough
+ n = LIBC_NAMESPACE::mblen(ch, 2);
+ ASSERT_EQ(n, -1);
+ ASSERT_ERRNO_SUCCESS();
+}
+
+TEST_F(LlvmLibcMBLenTest, FourByte) {
+ const char ch[4] = {static_cast<char>(0xF0), static_cast<char>(0x9F),
+ static_cast<char>(0xA4),
+ static_cast<char>(0xA1)}; // 🤡 clown emoji
+ int n = LIBC_NAMESPACE::mblen(ch, 4);
+ ASSERT_EQ(n, 4);
+ ASSERT_ERRNO_SUCCESS();
+
+ // Should fail since we have not read enough
+ n = LIBC_NAMESPACE::mblen(ch, 2);
+ ASSERT_EQ(n, -1);
+ ASSERT_ERRNO_SUCCESS();
+}
+
+TEST_F(LlvmLibcMBLenTest, InvalidByte) {
+ const char ch[1] = {static_cast<char>(0x80)};
+ int n = LIBC_NAMESPACE::mblen(ch, 1);
+ ASSERT_EQ(n, -1);
+ ASSERT_ERRNO_EQ(EILSEQ);
+}
+
+TEST_F(LlvmLibcMBLenTest, InvalidMultiByte) {
+ const char ch[4] = {static_cast<char>(0x80), static_cast<char>(0x00),
+ static_cast<char>(0x80),
+ static_cast<char>(0x00)}; // invalid sequence of bytes
+ // Trying to push all 4 should error
+ int n = LIBC_NAMESPACE::mblen(ch, 4);
+ ASSERT_EQ(n, -1);
+ ASSERT_ERRNO_EQ(EILSEQ);
+
+ // Trying to push the second and third should correspond to null wc
+ n = LIBC_NAMESPACE::mblen(ch + 1, 2);
+ ASSERT_EQ(n, 0);
+ ASSERT_ERRNO_SUCCESS();
+}
+
+TEST_F(LlvmLibcMBLenTest, NullString) {
+ // reading on nullptr should return 0
+ int n = LIBC_NAMESPACE::mblen(nullptr, 2);
+ ASSERT_EQ(n, 0);
+ ASSERT_ERRNO_SUCCESS();
+ // reading a null terminator should return 0
+ const char *ch = "\0";
+ n = LIBC_NAMESPACE::mblen(ch, 1);
+ ASSERT_EQ(n, 0);
+}
diff --git a/libc/test/src/wchar/mbrlen_test.cpp b/libc/test/src/wchar/mbrlen_test.cpp
new file mode 100644
index 0000000..e1452bf4
--- /dev/null
+++ b/libc/test/src/wchar/mbrlen_test.cpp
@@ -0,0 +1,139 @@
+//===-- Unittests 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/wchar_t.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/wchar/mbstate.h"
+#include "src/string/memset.h"
+#include "src/wchar/mbrlen.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcMBRLenTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcMBRLenTest, OneByte) {
+ const char *ch = "A";
+ mbstate_t mb;
+ LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+ size_t n = LIBC_NAMESPACE::mbrlen(ch, 1, &mb);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(n, static_cast<size_t>(1));
+
+ // Should fail since we have not read enough
+ n = LIBC_NAMESPACE::mbrlen(ch, 0, &mb);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(n, static_cast<size_t>(-2));
+}
+
+TEST_F(LlvmLibcMBRLenTest, TwoByte) {
+ const char ch[2] = {static_cast<char>(0xC2),
+ static_cast<char>(0x8E)}; // Ž car symbol
+ mbstate_t mb;
+ LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+ size_t n = LIBC_NAMESPACE::mbrlen(ch, 4, nullptr);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(static_cast<int>(n), 2);
+
+ // Should fail since we have not read enough
+ n = LIBC_NAMESPACE::mbrlen(ch, 1, &mb);
+ ASSERT_EQ(static_cast<int>(n), -2);
+ ASSERT_ERRNO_SUCCESS();
+ // Should pass after trying to read next byte
+ n = LIBC_NAMESPACE::mbrlen(ch + 1, 1, &mb);
+ ASSERT_EQ(static_cast<int>(n), 1);
+ ASSERT_ERRNO_SUCCESS();
+}
+
+TEST_F(LlvmLibcMBRLenTest, ThreeByte) {
+ const char ch[3] = {static_cast<char>(0xE2), static_cast<char>(0x88),
+ static_cast<char>(0x91)}; // ∑ sigma symbol
+ mbstate_t mb;
+ LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+ size_t n = LIBC_NAMESPACE::mbrlen(ch, 3, &mb);
+ ASSERT_EQ(static_cast<int>(n), 3);
+ ASSERT_ERRNO_SUCCESS();
+
+ // Should fail since we have not read enough
+ n = LIBC_NAMESPACE::mbrlen(ch, 2, &mb);
+ ASSERT_EQ(static_cast<int>(n), -2);
+ ASSERT_ERRNO_SUCCESS();
+}
+
+TEST_F(LlvmLibcMBRLenTest, FourByte) {
+ const char ch[4] = {static_cast<char>(0xF0), static_cast<char>(0x9F),
+ static_cast<char>(0xA4),
+ static_cast<char>(0xA1)}; // 🤡 clown emoji
+ mbstate_t mb;
+ LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+ size_t n = LIBC_NAMESPACE::mbrlen(ch, 4, &mb);
+ ASSERT_EQ(static_cast<int>(n), 4);
+ ASSERT_ERRNO_SUCCESS();
+
+ // Should fail since we have not read enough
+ n = LIBC_NAMESPACE::mbrlen(ch, 2, &mb);
+ ASSERT_EQ(static_cast<int>(n), -2);
+ ASSERT_ERRNO_SUCCESS();
+
+ // Should fail since we have not read enough
+ n = LIBC_NAMESPACE::mbrlen(ch + 2, 1, &mb);
+ ASSERT_EQ(static_cast<int>(n), -2);
+ ASSERT_ERRNO_SUCCESS();
+
+ // Should pass after reading final byte
+ n = LIBC_NAMESPACE::mbrlen(ch + 3, 5, &mb);
+ ASSERT_EQ(static_cast<int>(n), 1);
+ ASSERT_ERRNO_SUCCESS();
+}
+
+TEST_F(LlvmLibcMBRLenTest, InvalidByte) {
+ const char ch[1] = {static_cast<char>(0x80)};
+ size_t n = LIBC_NAMESPACE::mbrlen(ch, 1, nullptr);
+ ASSERT_EQ(static_cast<int>(n), -1);
+ ASSERT_ERRNO_EQ(EILSEQ);
+}
+
+TEST_F(LlvmLibcMBRLenTest, InvalidMultiByte) {
+ const char ch[4] = {static_cast<char>(0x80), static_cast<char>(0x00),
+ static_cast<char>(0x80),
+ static_cast<char>(0x00)}; // invalid sequence of bytes
+ mbstate_t mb;
+ LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+ // Trying to push all 4 should error
+ size_t n = LIBC_NAMESPACE::mbrlen(ch, 4, &mb);
+ ASSERT_EQ(static_cast<int>(n), -1);
+ ASSERT_ERRNO_EQ(EILSEQ);
+
+ // Trying to push the second and third should correspond to null wc
+ n = LIBC_NAMESPACE::mbrlen(ch + 1, 2, &mb);
+ ASSERT_EQ(static_cast<int>(n), 0);
+ ASSERT_ERRNO_SUCCESS();
+}
+
+TEST_F(LlvmLibcMBRLenTest, NullString) {
+ // reading on nullptr should return 0
+ size_t n = LIBC_NAMESPACE::mbrlen(nullptr, 2, nullptr);
+ ASSERT_EQ(static_cast<int>(n), 0);
+ ASSERT_ERRNO_SUCCESS();
+ // reading a null terminator should return 0
+ const char *ch = "\0";
+ n = LIBC_NAMESPACE::mbrlen(ch, 1, nullptr);
+ ASSERT_EQ(static_cast<int>(n), 0);
+}
+
+TEST_F(LlvmLibcMBRLenTest, InvalidMBState) {
+ const char ch[4] = {static_cast<char>(0xC2), static_cast<char>(0x8E),
+ static_cast<char>(0xC7), static_cast<char>(0x8C)};
+ mbstate_t *mb;
+ LIBC_NAMESPACE::internal::mbstate inv;
+ inv.total_bytes = 6;
+ mb = reinterpret_cast<mbstate_t *>(&inv);
+ // invalid mbstate should error
+ size_t n = LIBC_NAMESPACE::mbrlen(ch, 2, mb);
+ ASSERT_EQ(static_cast<int>(n), -1);
+ ASSERT_ERRNO_EQ(EINVAL);
+}
diff --git a/libc/test/src/wchar/mbrtowc_test.cpp b/libc/test/src/wchar/mbrtowc_test.cpp
index 5a14d8e..c406300 100644
--- a/libc/test/src/wchar/mbrtowc_test.cpp
+++ b/libc/test/src/wchar/mbrtowc_test.cpp
@@ -190,6 +190,18 @@ TEST_F(LlvmLibcMBRToWCTest, NullString) {
ASSERT_ERRNO_SUCCESS();
}
+TEST_F(LlvmLibcMBRToWCTest, NullDest) {
+ const char ch[4] = {static_cast<char>(0xF0), static_cast<char>(0x9F),
+ static_cast<char>(0xA4),
+ static_cast<char>(0xA1)}; // 🤡 clown emoji
+ mbstate_t *mb;
+ LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
+ // reading nullptr should return correct size
+ size_t n = LIBC_NAMESPACE::mbrtowc(nullptr, ch, 10, mb);
+ ASSERT_EQ(static_cast<int>(n), 4);
+ ASSERT_ERRNO_SUCCESS();
+}
+
TEST_F(LlvmLibcMBRToWCTest, InvalidMBState) {
const char ch[4] = {static_cast<char>(0xC2), static_cast<char>(0x8E),
static_cast<char>(0xC7), static_cast<char>(0x8C)};
diff --git a/libc/test/src/wchar/mbsinit_test.cpp b/libc/test/src/wchar/mbsinit_test.cpp
new file mode 100644
index 0000000..ecb48aa
--- /dev/null
+++ b/libc/test/src/wchar/mbsinit_test.cpp
@@ -0,0 +1,33 @@
+//===-- Unittests 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/wchar_t.h"
+#include "src/string/memset.h"
+#include "src/wchar/mbrtowc.h"
+#include "src/wchar/mbsinit.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcMBSInitTest, EmptyState) {
+ mbstate_t ps;
+ LIBC_NAMESPACE::memset(&ps, 0, sizeof(mbstate_t));
+ ASSERT_NE(LIBC_NAMESPACE::mbsinit(&ps), 0);
+ ASSERT_NE(LIBC_NAMESPACE::mbsinit(nullptr), 0);
+}
+
+TEST(LlvmLibcMBSInitTest, ConversionTest) {
+ const char *src = "\xf0\x9f\xa4\xa3"; // 4 byte emoji
+ wchar_t dest[2];
+ mbstate_t ps;
+ LIBC_NAMESPACE::memset(&ps, 0, sizeof(mbstate_t));
+
+ ASSERT_NE(LIBC_NAMESPACE::mbsinit(&ps), 0);
+ LIBC_NAMESPACE::mbrtowc(dest, src, 2, &ps); // partial conversion
+ ASSERT_EQ(LIBC_NAMESPACE::mbsinit(&ps), 0);
+ LIBC_NAMESPACE::mbrtowc(dest, src + 2, 2, &ps); // complete conversion
+ ASSERT_NE(LIBC_NAMESPACE::mbsinit(&ps), 0); // state should be reset now
+}
diff --git a/libc/test/src/wchar/wcpncpy_test.cpp b/libc/test/src/wchar/wcpncpy_test.cpp
index bb72211..6c6faf8 100644
--- a/libc/test/src/wchar/wcpncpy_test.cpp
+++ b/libc/test/src/wchar/wcpncpy_test.cpp
@@ -84,10 +84,10 @@ TEST(LlvmLibcWCPNCpyTest, CopyAndFill) {
ASSERT_EQ(dest + 1, res);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcWCPNCpyTest, NullptrCrash) {
// Passing in a nullptr should crash the program.
EXPECT_DEATH([] { LIBC_NAMESPACE::wcpncpy(nullptr, nullptr, 1); },
WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/wchar/wcscmp_test.cpp b/libc/test/src/wchar/wcscmp_test.cpp
index 6572aad..ace95e83 100644
--- a/libc/test/src/wchar/wcscmp_test.cpp
+++ b/libc/test/src/wchar/wcscmp_test.cpp
@@ -86,7 +86,7 @@ TEST(LlvmLibcWcscmpTest, StringArgumentSwapChangesSign) {
ASSERT_LT(result, 0);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcWcscmpTest, NullptrCrash) {
// Passing in a nullptr should crash the program.
EXPECT_DEATH([] { LIBC_NAMESPACE::wcscmp(L"aaaaaaaaaaaaaa", nullptr); },
@@ -94,4 +94,4 @@ TEST(LlvmLibcWcscmpTest, NullptrCrash) {
EXPECT_DEATH([] { LIBC_NAMESPACE::wcscmp(nullptr, L"aaaaaaaaaaaaaa"); },
WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/wchar/wcsdup_test.cpp b/libc/test/src/wchar/wcsdup_test.cpp
new file mode 100644
index 0000000..eafbb2d
--- /dev/null
+++ b/libc/test/src/wchar/wcsdup_test.cpp
@@ -0,0 +1,48 @@
+//===-- Unittests 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/wchar_t.h"
+#include "src/wchar/wcsdup.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcWcsDupTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcWcsDupTest, EmptyString) {
+ const wchar_t *empty = L"";
+
+ wchar_t *result = LIBC_NAMESPACE::wcsdup(empty);
+ ASSERT_ERRNO_SUCCESS();
+
+ ASSERT_NE(result, static_cast<wchar_t *>(nullptr));
+ ASSERT_NE(empty, const_cast<const wchar_t *>(result));
+ ASSERT_TRUE(empty[0] == result[0]);
+ ::free(result);
+}
+
+TEST_F(LlvmLibcWcsDupTest, AnyString) {
+ const wchar_t *abc = L"abc";
+
+ wchar_t *result = LIBC_NAMESPACE::wcsdup(abc);
+ ASSERT_ERRNO_SUCCESS();
+
+ ASSERT_NE(result, static_cast<wchar_t *>(nullptr));
+ ASSERT_NE(abc, const_cast<const wchar_t *>(result));
+ ASSERT_TRUE(abc[0] == result[0]);
+ ASSERT_TRUE(abc[1] == result[1]);
+ ASSERT_TRUE(abc[2] == result[2]);
+ ASSERT_TRUE(abc[3] == result[3]);
+ ::free(result);
+}
+
+TEST_F(LlvmLibcWcsDupTest, NullPtr) {
+ wchar_t *result = LIBC_NAMESPACE::wcsdup(nullptr);
+ ASSERT_ERRNO_SUCCESS();
+
+ ASSERT_EQ(result, static_cast<wchar_t *>(nullptr));
+}
diff --git a/libc/test/src/wchar/wcsncmp_test.cpp b/libc/test/src/wchar/wcsncmp_test.cpp
index 28bbb52..c36c4db 100644
--- a/libc/test/src/wchar/wcsncmp_test.cpp
+++ b/libc/test/src/wchar/wcsncmp_test.cpp
@@ -93,7 +93,7 @@ TEST(LlvmLibcWcsncmpTest, StringArgumentSwapChangesSignWithSufficientLength) {
ASSERT_LT(result, 0);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcWcsncmpTest, NullptrCrash) {
// Passing in a nullptr should crash the program.
EXPECT_DEATH([] { LIBC_NAMESPACE::wcsncmp(L"aaaaaaaaaaaaaa", nullptr, 3); },
@@ -101,7 +101,7 @@ TEST(LlvmLibcWcsncmpTest, NullptrCrash) {
EXPECT_DEATH([] { LIBC_NAMESPACE::wcsncmp(nullptr, L"aaaaaaaaaaaaaa", 3); },
WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
// This group is actually testing wcsncmp functionality
diff --git a/libc/test/src/wchar/wcsnrtombs_test.cpp b/libc/test/src/wchar/wcsnrtombs_test.cpp
new file mode 100644
index 0000000..04cf426
--- /dev/null
+++ b/libc/test/src/wchar/wcsnrtombs_test.cpp
@@ -0,0 +1,192 @@
+//===-- Unittests 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/mbstate_t.h"
+#include "src/__support/macros/null_check.h"
+#include "src/string/memset.h"
+#include "src/wchar/wcsnrtombs.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcWcsnrtombs = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+// these tests are fairly simple as this function just calls into the internal
+// wcsnrtombs which is more thoroughly tested
+
+TEST_F(LlvmLibcWcsnrtombs, AllMultibyteLengths) {
+ mbstate_t state;
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+ char mbs[11];
+
+ ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 11, &state),
+ static_cast<size_t>(10));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, nullptr);
+ ASSERT_EQ(mbs[0], '\xF0'); // clown begin
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
+ ASSERT_EQ(mbs[5], '\x88');
+ ASSERT_EQ(mbs[6], '\x91');
+ ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin
+ ASSERT_EQ(mbs[8], '\xBF');
+ ASSERT_EQ(mbs[9], '\x41'); // A begin
+ ASSERT_EQ(mbs[10], '\0'); // null terminator
+}
+
+TEST_F(LlvmLibcWcsnrtombs, DestLimit) {
+ mbstate_t state;
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+
+ char mbs[11];
+ LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values
+
+ ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 4, &state),
+ static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes
+
+ LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+ cur = src;
+
+ // not enough bytes to convert the second character, so only converts one
+ ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 6, &state),
+ static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01');
+}
+
+TEST(LlvmLibcWcsnrtombs, SrcLimit) {
+ mbstate_t state;
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+
+ char mbs[11];
+ LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values
+
+ auto res = LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 2, 11, &state);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(res, static_cast<size_t>(7));
+ ASSERT_EQ(cur, src + 2);
+ ASSERT_EQ(mbs[0], '\xF0'); // clown begin
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
+ ASSERT_EQ(mbs[5], '\x88');
+ ASSERT_EQ(mbs[6], '\x91');
+ ASSERT_EQ(mbs[7], '\x01');
+
+ res = LIBC_NAMESPACE::wcsnrtombs(mbs + res, &cur, 100, 11, &state);
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(res, static_cast<size_t>(3));
+ ASSERT_EQ(cur, nullptr);
+ ASSERT_EQ(mbs[0], '\xF0'); // clown begin
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
+ ASSERT_EQ(mbs[5], '\x88');
+ ASSERT_EQ(mbs[6], '\x91');
+ ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin
+ ASSERT_EQ(mbs[8], '\xBF');
+ ASSERT_EQ(mbs[9], '\x41'); // A begin
+ ASSERT_EQ(mbs[10], '\0'); // null terminator
+}
+
+TEST_F(LlvmLibcWcsnrtombs, ErrnoTest) {
+ mbstate_t state;
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0x12ffff), // invalid widechar
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+ char mbs[11];
+
+ // n parameter ignored when dest is null
+ ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 7, &state),
+ static_cast<size_t>(7));
+ ASSERT_ERRNO_SUCCESS();
+
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+ ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 100, &state),
+ static_cast<size_t>(-1));
+ ASSERT_ERRNO_EQ(EILSEQ);
+}
+
+TEST_F(LlvmLibcWcsnrtombs, NullState) {
+ // this test is the same as DestLimit except it uses a nullptr mbstate*
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+
+ char mbs[11];
+ LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values
+
+ ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 4, nullptr),
+ static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes
+
+ LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values
+
+ // not enough bytes to convert the second character, so only converts one
+ cur = src;
+ ASSERT_EQ(LIBC_NAMESPACE::wcsnrtombs(mbs, &cur, 5, 6, nullptr),
+ static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01');
+}
diff --git a/libc/test/src/wchar/wcspbrk_test.cpp b/libc/test/src/wchar/wcspbrk_test.cpp
index bca9bff..4c85ca4 100644
--- a/libc/test/src/wchar/wcspbrk_test.cpp
+++ b/libc/test/src/wchar/wcspbrk_test.cpp
@@ -61,7 +61,7 @@ TEST(LlvmLibcWCSPBrkTest, FindsFirstInBreakset) {
EXPECT_EQ(LIBC_NAMESPACE::wcspbrk(src, L"43"), src + 2);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcWCSPBrkTest, NullptrCrash) {
// Passing in a nullptr should crash the program.
EXPECT_DEATH([] { LIBC_NAMESPACE::wcspbrk(L"aaaaaaaaaaaaaa", nullptr); },
@@ -69,4 +69,4 @@ TEST(LlvmLibcWCSPBrkTest, NullptrCrash) {
EXPECT_DEATH([] { LIBC_NAMESPACE::wcspbrk(nullptr, L"aaaaaaaaaaaaaa"); },
WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/wchar/wcsrchr_test.cpp b/libc/test/src/wchar/wcsrchr_test.cpp
index 707dfb6..52c28ac 100644
--- a/libc/test/src/wchar/wcsrchr_test.cpp
+++ b/libc/test/src/wchar/wcsrchr_test.cpp
@@ -60,9 +60,9 @@ TEST(LlvmLibcWCSRChrTest, EmptyStringShouldOnlyMatchNullTerminator) {
ASSERT_EQ(LIBC_NAMESPACE::wcsrchr(src, L'*'), nullptr);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcWCSRChrTest, NullptrCrash) {
// Passing in a nullptr should crash the program.
EXPECT_DEATH([] { LIBC_NAMESPACE::wcsrchr(nullptr, L'a'); }, WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/wchar/wcsrtombs_test.cpp b/libc/test/src/wchar/wcsrtombs_test.cpp
new file mode 100644
index 0000000..65c69e6
--- /dev/null
+++ b/libc/test/src/wchar/wcsrtombs_test.cpp
@@ -0,0 +1,150 @@
+//===-- Unittests 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/types/mbstate_t.h"
+#include "src/__support/macros/null_check.h"
+#include "src/string/memset.h"
+#include "src/wchar/wcsrtombs.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcWcsrtombs = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+// these tests are fairly simple as this function just calls into the internal
+// wcsnrtombs which is more thoroughly tested
+
+TEST_F(LlvmLibcWcsrtombs, AllMultibyteLengths) {
+ mbstate_t state;
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+ char mbs[11];
+
+ ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 11, &state),
+ static_cast<size_t>(10));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, nullptr);
+ ASSERT_EQ(mbs[0], '\xF0'); // clown begin
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
+ ASSERT_EQ(mbs[5], '\x88');
+ ASSERT_EQ(mbs[6], '\x91');
+ ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin
+ ASSERT_EQ(mbs[8], '\xBF');
+ ASSERT_EQ(mbs[9], '\x41'); // A begin
+ ASSERT_EQ(mbs[10], '\0'); // null terminator
+}
+
+TEST_F(LlvmLibcWcsrtombs, DestLimit) {
+ mbstate_t state;
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+
+ char mbs[11];
+ LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values
+
+ ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 4, &state),
+ static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes
+
+ LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+
+ // not enough bytes to convert the second character, so only converts one
+ cur = src;
+ ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 6, &state),
+ static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01');
+}
+
+TEST_F(LlvmLibcWcsrtombs, ErrnoTest) {
+ mbstate_t state;
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0x12ffff), // invalid widechar
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+ char mbs[11];
+
+ // n parameter ignored when dest is null
+ ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 7, &state),
+ static_cast<size_t>(7));
+ ASSERT_ERRNO_SUCCESS();
+
+ LIBC_NAMESPACE::memset(&state, 0, sizeof(mbstate_t));
+ cur = src;
+
+ ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 100, &state),
+ static_cast<size_t>(-1));
+ ASSERT_ERRNO_EQ(EILSEQ);
+}
+
+TEST_F(LlvmLibcWcsrtombs, NullState) {
+ // this test is the same as DestLimit except it uses a nullptr mbstate*
+
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ const wchar_t *cur = src;
+
+ char mbs[11];
+ LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values
+
+ ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 4, nullptr),
+ static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes
+
+ LIBC_NAMESPACE::memset(mbs, '\x01', 11); // dummy initial values
+
+ // not enough bytes to convert the second character, so only converts one
+ cur = src;
+ ASSERT_EQ(LIBC_NAMESPACE::wcsrtombs(mbs, &cur, 6, nullptr),
+ static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(cur, src + 1);
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01');
+}
diff --git a/libc/test/src/wchar/wcstol_test.cpp b/libc/test/src/wchar/wcstol_test.cpp
index 9ae32ba..2dd0bc7 100644
--- a/libc/test/src/wchar/wcstol_test.cpp
+++ b/libc/test/src/wchar/wcstol_test.cpp
@@ -12,4 +12,4 @@
#include "WcstolTest.h"
-WCSTOL_TEST(Wcstol, LIBC_NAMESPACE::wcstol) \ No newline at end of file
+WCSTOL_TEST(Wcstol, LIBC_NAMESPACE::wcstol)
diff --git a/libc/test/src/wchar/wcstoll_test.cpp b/libc/test/src/wchar/wcstoll_test.cpp
index c24c1f6..00a241a 100644
--- a/libc/test/src/wchar/wcstoll_test.cpp
+++ b/libc/test/src/wchar/wcstoll_test.cpp
@@ -12,4 +12,4 @@
#include "WcstolTest.h"
-WCSTOL_TEST(Wcstoll, LIBC_NAMESPACE::wcstoll) \ No newline at end of file
+WCSTOL_TEST(Wcstoll, LIBC_NAMESPACE::wcstoll)
diff --git a/libc/test/src/wchar/wcstombs_test.cpp b/libc/test/src/wchar/wcstombs_test.cpp
new file mode 100644
index 0000000..61e0873
--- /dev/null
+++ b/libc/test/src/wchar/wcstombs_test.cpp
@@ -0,0 +1,84 @@
+//===-- Unittests 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/wchar/wcstombs.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcWcstombs = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+// these tests are fairly simple as this function just calls into the internal
+// wcsnrtombs which is more thoroughly tested
+
+TEST_F(LlvmLibcWcstombs, AllMultibyteLengths) {
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ char mbs[11];
+
+ ASSERT_EQ(LIBC_NAMESPACE::wcstombs(mbs, src, 11), static_cast<size_t>(10));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(mbs[0], '\xF0'); // clown begin
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\xE2'); // sigma begin
+ ASSERT_EQ(mbs[5], '\x88');
+ ASSERT_EQ(mbs[6], '\x91');
+ ASSERT_EQ(mbs[7], '\xC3'); // y diaeresis begin
+ ASSERT_EQ(mbs[8], '\xBF');
+ ASSERT_EQ(mbs[9], '\x41'); // A begin
+ ASSERT_EQ(mbs[10], '\0'); // null terminator
+}
+
+TEST_F(LlvmLibcWcstombs, DestLimit) {
+ /// clown emoji, sigma symbol, y with diaeresis, letter A
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0xff), static_cast<wchar_t>(0x41),
+ static_cast<wchar_t>(0x0)};
+ char mbs[11];
+ for (int i = 0; i < 11; ++i)
+ mbs[i] = '\x01'; // dummy initial values
+
+ ASSERT_EQ(LIBC_NAMESPACE::wcstombs(mbs, src, 4), static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01'); // didn't write more than 4 bytes
+
+ for (int i = 0; i < 11; ++i)
+ mbs[i] = '\x01'; // dummy initial values
+
+ // not enough bytes to convert the second character, so only converts one
+ ASSERT_EQ(LIBC_NAMESPACE::wcstombs(mbs, src, 6), static_cast<size_t>(4));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(mbs[0], '\xF0');
+ ASSERT_EQ(mbs[1], '\x9F');
+ ASSERT_EQ(mbs[2], '\xA4');
+ ASSERT_EQ(mbs[3], '\xA1');
+ ASSERT_EQ(mbs[4], '\x01');
+}
+
+TEST_F(LlvmLibcWcstombs, ErrnoTest) {
+ const wchar_t src[] = {static_cast<wchar_t>(0x1f921),
+ static_cast<wchar_t>(0x2211),
+ static_cast<wchar_t>(0x12ffff), // invalid widechar
+ static_cast<wchar_t>(0x0)};
+ char mbs[11];
+
+ // n parameter ignored when dest is null
+ ASSERT_EQ(LIBC_NAMESPACE::wcstombs(mbs, src, 7), static_cast<size_t>(7));
+ ASSERT_ERRNO_SUCCESS();
+ ASSERT_EQ(LIBC_NAMESPACE::wcstombs(mbs, src, 100), static_cast<size_t>(-1));
+ ASSERT_ERRNO_EQ(EILSEQ);
+}
diff --git a/libc/test/src/wchar/wcstoul_test.cpp b/libc/test/src/wchar/wcstoul_test.cpp
index ab0afb9..63b630d 100644
--- a/libc/test/src/wchar/wcstoul_test.cpp
+++ b/libc/test/src/wchar/wcstoul_test.cpp
@@ -12,4 +12,4 @@
#include "WcstolTest.h"
-WCSTOL_TEST(Wcstoul, LIBC_NAMESPACE::wcstoul) \ No newline at end of file
+WCSTOL_TEST(Wcstoul, LIBC_NAMESPACE::wcstoul)
diff --git a/libc/test/src/wchar/wcstoull_test.cpp b/libc/test/src/wchar/wcstoull_test.cpp
index adba4f1..12895d3 100644
--- a/libc/test/src/wchar/wcstoull_test.cpp
+++ b/libc/test/src/wchar/wcstoull_test.cpp
@@ -12,4 +12,4 @@
#include "WcstolTest.h"
-WCSTOL_TEST(Wcstoull, LIBC_NAMESPACE::wcstoull) \ No newline at end of file
+WCSTOL_TEST(Wcstoull, LIBC_NAMESPACE::wcstoull)
diff --git a/libc/test/src/wchar/wmemcmp_test.cpp b/libc/test/src/wchar/wmemcmp_test.cpp
index 5b07ca7..c9c0839 100644
--- a/libc/test/src/wchar/wmemcmp_test.cpp
+++ b/libc/test/src/wchar/wmemcmp_test.cpp
@@ -67,7 +67,7 @@ TEST(LlvmLibcWMemcmpTest, LhsRhsAreTheSameLong) {
EXPECT_EQ(LIBC_NAMESPACE::wmemcmp(lhs, rhs, 15), 0);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcWMemcmpTest, NullptrCrash) {
// Passing in a nullptr should crash the program.
EXPECT_DEATH([] { LIBC_NAMESPACE::wmemcmp(L"aaaaaaaaaaaaaa", nullptr, 15); },
@@ -75,4 +75,4 @@ TEST(LlvmLibcWMemcmpTest, NullptrCrash) {
EXPECT_DEATH([] { LIBC_NAMESPACE::wmemcmp(nullptr, L"aaaaaaaaaaaaaa", 15); },
WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/wchar/wmemmove_test.cpp b/libc/test/src/wchar/wmemmove_test.cpp
index d23aa0f..102fc04 100644
--- a/libc/test/src/wchar/wmemmove_test.cpp
+++ b/libc/test/src/wchar/wmemmove_test.cpp
@@ -99,7 +99,7 @@ TEST(LlvmLibcWMemmoveTest, DstFollowSrc) {
EXPECT_TRUE(buffer[3] == expected[3]);
}
-#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcWMemmoveTest, NullptrCrash) {
wchar_t buffer[] = {L'a', L'b'};
// Passing in a nullptr should crash the program.
@@ -108,4 +108,4 @@ TEST(LlvmLibcWMemmoveTest, NullptrCrash) {
EXPECT_DEATH([&buffer] { LIBC_NAMESPACE::wmemmove(nullptr, buffer, 2); },
WITH_SIGNAL(-1));
}
-#endif // LIBC_HAS_ADDRESS_SANITIZER
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/utils/MPCWrapper/CMakeLists.txt b/libc/utils/MPCWrapper/CMakeLists.txt
index 7120eaf..2df8cfa 100644
--- a/libc/utils/MPCWrapper/CMakeLists.txt
+++ b/libc/utils/MPCWrapper/CMakeLists.txt
@@ -10,6 +10,7 @@ if(LIBC_TESTS_CAN_USE_MPC)
add_dependencies(
libcMPCWrapper
libcMPCommon
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.array
libc.src.__support.CPP.string
libc.src.__support.CPP.stringstream
diff --git a/libc/utils/MPCWrapper/MPCUtils.cpp b/libc/utils/MPCWrapper/MPCUtils.cpp
index 7c7821d..11e93ec 100644
--- a/libc/utils/MPCWrapper/MPCUtils.cpp
+++ b/libc/utils/MPCWrapper/MPCUtils.cpp
@@ -8,13 +8,12 @@
#include "MPCUtils.h"
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/stringstream.h"
#include "utils/MPCWrapper/mpc_inc.h"
#include "utils/MPFRWrapper/MPCommon.h"
-#include <stdint.h>
-
template <typename T> using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/utils/MPCWrapper/MPCUtils.h b/libc/utils/MPCWrapper/MPCUtils.h
index d4c5724..d4ab672 100644
--- a/libc/utils/MPCWrapper/MPCUtils.h
+++ b/libc/utils/MPCWrapper/MPCUtils.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_UTILS_MPCWRAPPER_MPCUTILS_H
#define LLVM_LIBC_UTILS_MPCWRAPPER_MPCUTILS_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/complex_type.h"
#include "src/__support/macros/config.h"
@@ -17,8 +18,6 @@
#include "test/UnitTest/RoundingModeUtils.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace testing {
namespace mpc {
diff --git a/libc/utils/MPFRWrapper/CMakeLists.txt b/libc/utils/MPFRWrapper/CMakeLists.txt
index bac4347..2669b23 100644
--- a/libc/utils/MPFRWrapper/CMakeLists.txt
+++ b/libc/utils/MPFRWrapper/CMakeLists.txt
@@ -10,6 +10,7 @@ if(LIBC_TESTS_CAN_USE_MPFR OR LIBC_TESTS_CAN_USE_MPC)
target_compile_options(libcMPCommon PRIVATE -O3 ${compile_options})
add_dependencies(
libcMPCommon
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.string
libc.src.__support.CPP.string_view
libc.src.__support.CPP.type_traits
@@ -39,6 +40,7 @@ if(LIBC_TESTS_CAN_USE_MPFR)
add_dependencies(
libcMPFRWrapper
libcMPCommon
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.array
libc.src.__support.CPP.stringstream
libc.src.__support.FPUtil.fp_bits
diff --git a/libc/utils/MPFRWrapper/MPCommon.h b/libc/utils/MPFRWrapper/MPCommon.h
index af03ff0..8bcc69c2 100644
--- a/libc/utils/MPFRWrapper/MPCommon.h
+++ b/libc/utils/MPFRWrapper/MPCommon.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_UTILS_MPFRWRAPPER_MPCOMMON_H
#define LLVM_LIBC_UTILS_MPFRWRAPPER_MPCOMMON_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/string.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FPBits.h"
@@ -16,8 +17,6 @@
#include "src/__support/macros/properties/types.h"
#include "test/UnitTest/RoundingModeUtils.h"
-#include <stdint.h>
-
#include "mpfr_inc.h"
#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h
index c77a6aa..45468c6 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.h
+++ b/libc/utils/MPFRWrapper/MPFRUtils.h
@@ -9,13 +9,12 @@
#ifndef LLVM_LIBC_UTILS_MPFRWRAPPER_MPFRUTILS_H
#define LLVM_LIBC_UTILS_MPFRWRAPPER_MPFRUTILS_H
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/macros/config.h"
#include "test/UnitTest/RoundingModeUtils.h"
#include "test/UnitTest/Test.h"
-#include <stdint.h>
-
namespace LIBC_NAMESPACE_DECL {
namespace testing {
namespace mpfr {