aboutsummaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/benchmarks/gpu/BenchmarkLogger.cpp97
-rw-r--r--libc/benchmarks/gpu/BenchmarkLogger.h29
-rw-r--r--libc/benchmarks/gpu/CMakeLists.txt27
-rw-r--r--libc/benchmarks/gpu/LibcGpuBenchmark.cpp193
-rw-r--r--libc/benchmarks/gpu/LibcGpuBenchmark.h209
-rw-r--r--libc/benchmarks/gpu/Random.h190
-rw-r--r--libc/benchmarks/gpu/src/math/CMakeLists.txt157
-rw-r--r--libc/benchmarks/gpu/src/math/atan2_benchmark.cpp23
-rw-r--r--libc/benchmarks/gpu/src/math/exp_benchmark.cpp59
-rw-r--r--libc/benchmarks/gpu/src/math/expf16_benchmark.cpp56
-rw-r--r--libc/benchmarks/gpu/src/math/expf_benchmark.cpp59
-rw-r--r--libc/benchmarks/gpu/src/math/log_benchmark.cpp68
-rw-r--r--libc/benchmarks/gpu/src/math/logf16_benchmark.cpp62
-rw-r--r--libc/benchmarks/gpu/src/math/logf_benchmark.cpp68
-rw-r--r--libc/benchmarks/gpu/src/math/platform.h19
-rw-r--r--libc/benchmarks/gpu/src/math/sin_benchmark.cpp31
-rw-r--r--libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt6
-rw-r--r--libc/benchmarks/gpu/timing/amdgpu/timing.h105
-rw-r--r--libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt6
-rw-r--r--libc/benchmarks/gpu/timing/nvptx/timing.h110
-rw-r--r--libc/cmake/modules/LLVMLibCCompileOptionRules.cmake22
-rw-r--r--libc/cmake/modules/LLVMLibCLibraryRules.cmake29
-rw-r--r--libc/cmake/modules/LLVMLibCObjectRules.cmake83
-rw-r--r--libc/cmake/modules/LLVMLibCTestRules.cmake6
-rw-r--r--libc/config/baremetal/aarch64/entrypoints.txt77
-rw-r--r--libc/config/baremetal/arm/entrypoints.txt77
-rw-r--r--libc/config/baremetal/riscv/entrypoints.txt77
-rw-r--r--libc/config/config.json2
-rw-r--r--libc/config/darwin/aarch64/entrypoints.txt75
-rw-r--r--libc/config/darwin/x86_64/entrypoints.txt66
-rw-r--r--libc/config/gpu/amdgpu/entrypoints.txt67
-rw-r--r--libc/config/gpu/config.json (renamed from libc/config/gpu/amdgpu/config.json)2
-rw-r--r--libc/config/gpu/nvptx/config.json45
-rw-r--r--libc/config/gpu/nvptx/entrypoints.txt67
-rw-r--r--libc/config/linux/aarch64/entrypoints.txt78
-rw-r--r--libc/config/linux/arm/config.json7
-rw-r--r--libc/config/linux/arm/entrypoints.txt66
-rw-r--r--libc/config/linux/config.json7
-rw-r--r--libc/config/linux/riscv/config.json7
-rw-r--r--libc/config/linux/riscv/entrypoints.txt77
-rw-r--r--libc/config/linux/x86_64/entrypoints.txt81
-rw-r--r--libc/config/windows/README.md2
-rw-r--r--libc/config/windows/entrypoints.txt66
-rw-r--r--libc/docs/configure.rst2
-rw-r--r--libc/docs/headers/math/index.rst291
-rw-r--r--libc/hdr/types/CMakeLists.txt9
-rw-r--r--libc/hdr/types/dl_info.h21
-rw-r--r--libc/include/CMakeLists.txt1
-rw-r--r--libc/include/__llvm-libc-common.h7
-rw-r--r--libc/include/dlfcn.yaml74
-rw-r--r--libc/include/llvm-libc-types/CMakeLists.txt1
-rw-r--r--libc/include/llvm-libc-types/Dl_info.h19
-rw-r--r--libc/include/math.yaml114
-rw-r--r--libc/include/sched.yaml2
-rw-r--r--libc/include/sys/ioctl.yaml10
-rw-r--r--libc/shared/math.h8
-rw-r--r--libc/shared/math/cbrtf.h23
-rw-r--r--libc/shared/math/cos.h23
-rw-r--r--libc/shared/math/cosf.h23
-rw-r--r--libc/shared/math/cosf16.h28
-rw-r--r--libc/shared/math/coshf.h23
-rw-r--r--libc/shared/math/coshf16.h28
-rw-r--r--libc/shared/math/cospif.h23
-rw-r--r--libc/shared/math/cospif16.h28
-rw-r--r--libc/shared/rpc.h3
-rw-r--r--libc/src/__support/CPP/CMakeLists.txt6
-rw-r--r--libc/src/__support/CPP/algorithm.h6
-rw-r--r--libc/src/__support/CPP/simd.h276
-rw-r--r--libc/src/__support/FPUtil/BasicOperations.h2
-rw-r--r--libc/src/__support/FPUtil/CMakeLists.txt4
-rw-r--r--libc/src/__support/FPUtil/Hypot.h15
-rw-r--r--libc/src/__support/FPUtil/bfloat16.h38
-rw-r--r--libc/src/__support/FPUtil/cast.h66
-rw-r--r--libc/src/__support/FPUtil/dyadic_float.h2
-rw-r--r--libc/src/__support/FPUtil/generic/CMakeLists.txt2
-rw-r--r--libc/src/__support/FPUtil/generic/add_sub.h35
-rw-r--r--libc/src/__support/FPUtil/generic/div.h8
-rw-r--r--libc/src/__support/FPUtil/rounding_mode.h93
-rw-r--r--libc/src/__support/File/file.cpp2
-rw-r--r--libc/src/__support/GPU/CMakeLists.txt7
-rw-r--r--libc/src/__support/GPU/allocator.cpp62
-rw-r--r--libc/src/__support/GPU/fixedstack.h111
-rw-r--r--libc/src/__support/OSUtil/linux/aarch64/vdso.h2
-rw-r--r--libc/src/__support/OSUtil/linux/vdso_sym.h6
-rw-r--r--libc/src/__support/OSUtil/linux/x86_64/vdso.h2
-rw-r--r--libc/src/__support/libc_errno.h17
-rw-r--r--libc/src/__support/macros/attributes.h35
-rw-r--r--libc/src/__support/macros/properties/cpu_features.h4
-rw-r--r--libc/src/__support/math/CMakeLists.txt198
-rw-r--r--libc/src/__support/math/cbrtf.h161
-rw-r--r--libc/src/__support/math/cos.h173
-rw-r--r--libc/src/__support/math/cosf.h152
-rw-r--r--libc/src/__support/math/cosf16.h106
-rw-r--r--libc/src/__support/math/coshf.h65
-rw-r--r--libc/src/__support/math/coshf16.h124
-rw-r--r--libc/src/__support/math/cospif.h109
-rw-r--r--libc/src/__support/math/cospif16.h99
-rw-r--r--libc/src/__support/math/expxf16_utils.h (renamed from libc/src/math/generic/expxf16.h)21
-rw-r--r--libc/src/__support/math/range_reduction.h (renamed from libc/src/math/generic/range_reduction.h)6
-rw-r--r--libc/src/__support/math/range_reduction_double_common.h (renamed from libc/src/math/generic/range_reduction_double_common.h)24
-rw-r--r--libc/src/__support/math/range_reduction_double_fma.h (renamed from libc/src/math/generic/range_reduction_double_fma.h)18
-rw-r--r--libc/src/__support/math/range_reduction_double_nofma.h (renamed from libc/src/math/generic/range_reduction_double_nofma.h)16
-rw-r--r--libc/src/__support/math/range_reduction_fma.h (renamed from libc/src/math/generic/range_reduction_fma.h)6
-rw-r--r--libc/src/__support/math/sincos_eval.h (renamed from libc/src/math/generic/sincos_eval.h)8
-rw-r--r--libc/src/__support/math/sincosf16_utils.h (renamed from libc/src/math/generic/sincosf16_utils.h)6
-rw-r--r--libc/src/__support/math/sincosf_utils.h (renamed from libc/src/math/generic/sincosf_utils.h)6
-rw-r--r--libc/src/__support/math/sinhfcoshf_utils.h (renamed from libc/src/math/generic/explogxf.h)26
-rw-r--r--libc/src/__support/math_extras.h6
-rw-r--r--libc/src/__support/threads/linux/barrier.h21
-rw-r--r--libc/src/__support/threads/mutex.h22
-rw-r--r--libc/src/__support/threads/thread.cpp2
-rw-r--r--libc/src/__support/threads/thread.h2
-rw-r--r--libc/src/__support/wchar/character_converter.cpp14
-rw-r--r--libc/src/__support/wchar/character_converter.h5
-rw-r--r--libc/src/__support/wchar/mbrtowc.cpp1
-rw-r--r--libc/src/__support/wchar/mbsnrtowcs.h4
-rw-r--r--libc/src/__support/wchar/string_converter.h38
-rw-r--r--libc/src/__support/wchar/wcsnrtombs.h4
-rw-r--r--libc/src/dlfcn/CMakeLists.txt24
-rw-r--r--libc/src/dlfcn/dladdr.cpp23
-rw-r--r--libc/src/dlfcn/dladdr.h22
-rw-r--r--libc/src/dlfcn/dlinfo.cpp24
-rw-r--r--libc/src/dlfcn/dlinfo.h20
-rw-r--r--libc/src/dlfcn/dlsym.cpp4
-rw-r--r--libc/src/dlfcn/dlsym.h2
-rw-r--r--libc/src/errno/libc_errno.cpp5
-rw-r--r--libc/src/math/CMakeLists.txt82
-rw-r--r--libc/src/math/asinpif16.h21
-rw-r--r--libc/src/math/atanpif16.h21
-rw-r--r--libc/src/math/bf16add.h21
-rw-r--r--libc/src/math/bf16addf.h21
-rw-r--r--libc/src/math/bf16addf128.h21
-rw-r--r--libc/src/math/bf16addl.h21
-rw-r--r--libc/src/math/bf16div.h21
-rw-r--r--libc/src/math/bf16divf.h21
-rw-r--r--libc/src/math/bf16divf128.h21
-rw-r--r--libc/src/math/bf16divl.h21
-rw-r--r--libc/src/math/bf16fma.h21
-rw-r--r--libc/src/math/bf16fmaf.h21
-rw-r--r--libc/src/math/bf16fmaf128.h21
-rw-r--r--libc/src/math/bf16fmal.h21
-rw-r--r--libc/src/math/bf16mul.h21
-rw-r--r--libc/src/math/bf16mulf.h21
-rw-r--r--libc/src/math/bf16mulf128.h21
-rw-r--r--libc/src/math/bf16mull.h21
-rw-r--r--libc/src/math/bf16sub.h21
-rw-r--r--libc/src/math/bf16subf.h21
-rw-r--r--libc/src/math/bf16subf128.h21
-rw-r--r--libc/src/math/bf16subl.h21
-rw-r--r--libc/src/math/canonicalizebf16.h21
-rw-r--r--libc/src/math/ceilbf16.h21
-rw-r--r--libc/src/math/copysignbf16.h21
-rw-r--r--libc/src/math/fdimbf16.h21
-rw-r--r--libc/src/math/floorbf16.h21
-rw-r--r--libc/src/math/fmaxbf16.h21
-rw-r--r--libc/src/math/fmaximum_mag_numbf16.h21
-rw-r--r--libc/src/math/fmaximum_magbf16.h21
-rw-r--r--libc/src/math/fmaximum_numbf16.h21
-rw-r--r--libc/src/math/fmaximumbf16.h21
-rw-r--r--libc/src/math/fminbf16.h21
-rw-r--r--libc/src/math/fminimum_mag_numbf16.h21
-rw-r--r--libc/src/math/fminimum_magbf16.h21
-rw-r--r--libc/src/math/fminimum_numbf16.h21
-rw-r--r--libc/src/math/fminimumbf16.h21
-rw-r--r--libc/src/math/fmodbf16.h21
-rw-r--r--libc/src/math/frexpbf16.h21
-rw-r--r--libc/src/math/fromfpbf16.h21
-rw-r--r--libc/src/math/fromfpxbf16.h21
-rw-r--r--libc/src/math/generic/CMakeLists.txt1267
-rw-r--r--libc/src/math/generic/acoshf.cpp1
-rw-r--r--libc/src/math/generic/asinpif16.cpp127
-rw-r--r--libc/src/math/generic/atanpif16.cpp157
-rw-r--r--libc/src/math/generic/bf16add.cpp21
-rw-r--r--libc/src/math/generic/bf16addf.cpp21
-rw-r--r--libc/src/math/generic/bf16addf128.cpp21
-rw-r--r--libc/src/math/generic/bf16addl.cpp21
-rw-r--r--libc/src/math/generic/bf16div.cpp21
-rw-r--r--libc/src/math/generic/bf16divf.cpp21
-rw-r--r--libc/src/math/generic/bf16divf128.cpp21
-rw-r--r--libc/src/math/generic/bf16divl.cpp21
-rw-r--r--libc/src/math/generic/bf16fma.cpp21
-rw-r--r--libc/src/math/generic/bf16fmaf.cpp21
-rw-r--r--libc/src/math/generic/bf16fmaf128.cpp22
-rw-r--r--libc/src/math/generic/bf16fmal.cpp22
-rw-r--r--libc/src/math/generic/bf16mul.cpp21
-rw-r--r--libc/src/math/generic/bf16mulf.cpp21
-rw-r--r--libc/src/math/generic/bf16mulf128.cpp21
-rw-r--r--libc/src/math/generic/bf16mull.cpp21
-rw-r--r--libc/src/math/generic/bf16sub.cpp21
-rw-r--r--libc/src/math/generic/bf16subf.cpp21
-rw-r--r--libc/src/math/generic/bf16subf128.cpp21
-rw-r--r--libc/src/math/generic/bf16subl.cpp21
-rw-r--r--libc/src/math/generic/canonicalizebf16.cpp21
-rw-r--r--libc/src/math/generic/cbrtf.cpp147
-rw-r--r--libc/src/math/generic/ceilbf16.cpp19
-rw-r--r--libc/src/math/generic/copysignbf16.cpp21
-rw-r--r--libc/src/math/generic/cos.cpp155
-rw-r--r--libc/src/math/generic/cosf.cpp133
-rw-r--r--libc/src/math/generic/cosf16.cpp81
-rw-r--r--libc/src/math/generic/coshf.cpp44
-rw-r--r--libc/src/math/generic/coshf16.cpp99
-rw-r--r--libc/src/math/generic/cospif.cpp89
-rw-r--r--libc/src/math/generic/cospif16.cpp73
-rw-r--r--libc/src/math/generic/exp10m1f.cpp3
-rw-r--r--libc/src/math/generic/exp2.cpp2
-rw-r--r--libc/src/math/generic/exp2f16.cpp3
-rw-r--r--libc/src/math/generic/exp2f_impl.h3
-rw-r--r--libc/src/math/generic/exp2m1f.cpp3
-rw-r--r--libc/src/math/generic/exp2m1f16.cpp3
-rw-r--r--libc/src/math/generic/expm1.cpp3
-rw-r--r--libc/src/math/generic/expm1f16.cpp3
-rw-r--r--libc/src/math/generic/fdimbf16.cpp21
-rw-r--r--libc/src/math/generic/floorbf16.cpp21
-rw-r--r--libc/src/math/generic/fmaxbf16.cpp21
-rw-r--r--libc/src/math/generic/fmaximum_mag_numbf16.cpp21
-rw-r--r--libc/src/math/generic/fmaximum_magbf16.cpp21
-rw-r--r--libc/src/math/generic/fmaximum_numbf16.cpp21
-rw-r--r--libc/src/math/generic/fmaximumbf16.cpp21
-rw-r--r--libc/src/math/generic/fminbf16.cpp21
-rw-r--r--libc/src/math/generic/fminimum_mag_numbf16.cpp21
-rw-r--r--libc/src/math/generic/fminimum_magbf16.cpp21
-rw-r--r--libc/src/math/generic/fminimum_numbf16.cpp21
-rw-r--r--libc/src/math/generic/fminimumbf16.cpp21
-rw-r--r--libc/src/math/generic/fmodbf16.cpp21
-rw-r--r--libc/src/math/generic/frexpbf16.cpp21
-rw-r--r--libc/src/math/generic/fromfpbf16.cpp22
-rw-r--r--libc/src/math/generic/fromfpxbf16.cpp22
-rw-r--r--libc/src/math/generic/getpayloadbf16.cpp21
-rw-r--r--libc/src/math/generic/hypotf16.cpp13
-rw-r--r--libc/src/math/generic/ilogbbf16.cpp21
-rw-r--r--libc/src/math/generic/iscanonicalbf16.cpp22
-rw-r--r--libc/src/math/generic/issignalingbf16.cpp21
-rw-r--r--libc/src/math/generic/ldexpbf16.cpp21
-rw-r--r--libc/src/math/generic/llogbbf16.cpp21
-rw-r--r--libc/src/math/generic/llrintbf16.cpp23
-rw-r--r--libc/src/math/generic/llroundbf16.cpp21
-rw-r--r--libc/src/math/generic/log10f16.cpp3
-rw-r--r--libc/src/math/generic/log2f16.cpp3
-rw-r--r--libc/src/math/generic/logbbf16.cpp19
-rw-r--r--libc/src/math/generic/logf16.cpp3
-rw-r--r--libc/src/math/generic/lrintbf16.cpp22
-rw-r--r--libc/src/math/generic/lroundbf16.cpp21
-rw-r--r--libc/src/math/generic/modfbf16.cpp21
-rw-r--r--libc/src/math/generic/nanbf16.cpp25
-rw-r--r--libc/src/math/generic/nearbyintbf16.cpp21
-rw-r--r--libc/src/math/generic/nextafterbf16.cpp21
-rw-r--r--libc/src/math/generic/nextdownbf16.cpp21
-rw-r--r--libc/src/math/generic/nexttowardbf16.cpp22
-rw-r--r--libc/src/math/generic/nextupbf16.cpp21
-rw-r--r--libc/src/math/generic/remainderbf16.cpp22
-rw-r--r--libc/src/math/generic/remquobf16.cpp21
-rw-r--r--libc/src/math/generic/rintbf16.cpp21
-rw-r--r--libc/src/math/generic/roundbf16.cpp21
-rw-r--r--libc/src/math/generic/roundevenbf16.cpp21
-rw-r--r--libc/src/math/generic/scalblnbf16.cpp26
-rw-r--r--libc/src/math/generic/scalbnbf16.cpp26
-rw-r--r--libc/src/math/generic/setpayloadbf16.cpp21
-rw-r--r--libc/src/math/generic/setpayloadsigbf16.cpp21
-rw-r--r--libc/src/math/generic/sin.cpp14
-rw-r--r--libc/src/math/generic/sincos.cpp14
-rw-r--r--libc/src/math/generic/sincosf.cpp2
-rw-r--r--libc/src/math/generic/sinf.cpp6
-rw-r--r--libc/src/math/generic/sinf16.cpp3
-rw-r--r--libc/src/math/generic/sinhf.cpp5
-rw-r--r--libc/src/math/generic/sinhf16.cpp3
-rw-r--r--libc/src/math/generic/sinpif.cpp2
-rw-r--r--libc/src/math/generic/sinpif16.cpp3
-rw-r--r--libc/src/math/generic/tan.cpp7
-rw-r--r--libc/src/math/generic/tanf.cpp2
-rw-r--r--libc/src/math/generic/tanf16.cpp3
-rw-r--r--libc/src/math/generic/tanhf.cpp2
-rw-r--r--libc/src/math/generic/tanhf16.cpp3
-rw-r--r--libc/src/math/generic/tanpif.cpp2
-rw-r--r--libc/src/math/generic/tanpif16.cpp3
-rw-r--r--libc/src/math/generic/totalorderbf16.cpp22
-rw-r--r--libc/src/math/generic/totalordermagbf16.cpp22
-rw-r--r--libc/src/math/generic/truncbf16.cpp21
-rw-r--r--libc/src/math/generic/ufromfpbf16.cpp22
-rw-r--r--libc/src/math/generic/ufromfpxbf16.cpp22
-rw-r--r--libc/src/math/getpayloadbf16.h21
-rw-r--r--libc/src/math/ilogbbf16.h21
-rw-r--r--libc/src/math/iscanonicalbf16.h21
-rw-r--r--libc/src/math/issignalingbf16.h21
-rw-r--r--libc/src/math/ldexpbf16.h21
-rw-r--r--libc/src/math/llogbbf16.h21
-rw-r--r--libc/src/math/llrintbf16.h21
-rw-r--r--libc/src/math/llroundbf16.h21
-rw-r--r--libc/src/math/logbbf16.h21
-rw-r--r--libc/src/math/lrintbf16.h21
-rw-r--r--libc/src/math/lroundbf16.h21
-rw-r--r--libc/src/math/modfbf16.h21
-rw-r--r--libc/src/math/nanbf16.h21
-rw-r--r--libc/src/math/nearbyintbf16.h21
-rw-r--r--libc/src/math/nextafterbf16.h21
-rw-r--r--libc/src/math/nextdownbf16.h21
-rw-r--r--libc/src/math/nexttowardbf16.h21
-rw-r--r--libc/src/math/nextupbf16.h21
-rw-r--r--libc/src/math/remainderbf16.h21
-rw-r--r--libc/src/math/remquobf16.h21
-rw-r--r--libc/src/math/rintbf16.h21
-rw-r--r--libc/src/math/roundbf16.h22
-rw-r--r--libc/src/math/roundevenbf16.h21
-rw-r--r--libc/src/math/scalblnbf16.h21
-rw-r--r--libc/src/math/scalbnbf16.h21
-rw-r--r--libc/src/math/setpayloadbf16.h21
-rw-r--r--libc/src/math/setpayloadsigbf16.h21
-rw-r--r--libc/src/math/totalorderbf16.h21
-rw-r--r--libc/src/math/totalordermagbf16.h21
-rw-r--r--libc/src/math/truncbf16.h21
-rw-r--r--libc/src/math/ufromfpbf16.h21
-rw-r--r--libc/src/math/ufromfpxbf16.h21
-rw-r--r--libc/src/stdlib/exit.cpp10
-rw-r--r--libc/src/string/CMakeLists.txt1
-rw-r--r--libc/src/string/memory_utils/aarch64/inline_strlen.h53
-rw-r--r--libc/src/string/memory_utils/generic/inline_strlen.h54
-rw-r--r--libc/src/string/memory_utils/x86_64/inline_strlen.h107
-rw-r--r--libc/src/string/string_utils.h75
-rw-r--r--libc/src/sys/time/linux/utimes.cpp22
-rw-r--r--libc/src/unistd/linux/setsid.cpp8
-rw-r--r--libc/src/wchar/wcsncmp.cpp3
-rw-r--r--libc/src/wctype/iswalpha.cpp2
-rw-r--r--libc/src/wctype/iswalpha.h2
-rw-r--r--libc/startup/baremetal/aarch64/CMakeLists.txt16
-rw-r--r--libc/startup/baremetal/aarch64/start.cpp112
-rw-r--r--libc/startup/baremetal/arm/start.cpp112
-rw-r--r--libc/test/IntegrationTest/CMakeLists.txt1
-rw-r--r--libc/test/IntegrationTest/test.cpp21
-rw-r--r--libc/test/UnitTest/CMakeLists.txt1
-rw-r--r--libc/test/UnitTest/FEnvSafeTest.cpp6
-rw-r--r--libc/test/UnitTest/FEnvSafeTest.h3
-rw-r--r--libc/test/UnitTest/FPMatcher.h11
-rw-r--r--libc/test/integration/src/__support/GPU/CMakeLists.txt13
-rw-r--r--libc/test/integration/src/__support/GPU/fixedstack_test.cpp44
-rw-r--r--libc/test/integration/src/__support/GPU/match.cpp4
-rw-r--r--libc/test/integration/src/__support/threads/CMakeLists.txt21
-rw-r--r--libc/test/integration/src/__support/threads/double_exit_test.cpp33
-rw-r--r--libc/test/integration/src/__support/threads/main_exit_test.cpp30
-rw-r--r--libc/test/shared/CMakeLists.txt8
-rw-r--r--libc/test/shared/shared_math_test.cpp11
-rw-r--r--libc/test/src/__support/File/file_test.cpp19
-rw-r--r--libc/test/src/__support/OSUtil/linux/vdso_test.cpp30
-rw-r--r--libc/test/src/__support/wchar/string_converter_test.cpp110
-rw-r--r--libc/test/src/math/CMakeLists.txt424
-rw-r--r--libc/test/src/math/RoundToIntegerTest.h4
-rw-r--r--libc/test/src/math/asinpif16_test.cpp40
-rw-r--r--libc/test/src/math/atanpif16_test.cpp40
-rw-r--r--libc/test/src/math/bf16add_test.cpp14
-rw-r--r--libc/test/src/math/bf16addf128_test.cpp14
-rw-r--r--libc/test/src/math/bf16addf_test.cpp14
-rw-r--r--libc/test/src/math/bf16addl_test.cpp14
-rw-r--r--libc/test/src/math/bf16div_test.cpp14
-rw-r--r--libc/test/src/math/bf16divf128_test.cpp14
-rw-r--r--libc/test/src/math/bf16divf_test.cpp14
-rw-r--r--libc/test/src/math/bf16divl_test.cpp14
-rw-r--r--libc/test/src/math/bf16fma_test.cpp14
-rw-r--r--libc/test/src/math/bf16fmaf128_test.cpp14
-rw-r--r--libc/test/src/math/bf16fmaf_test.cpp14
-rw-r--r--libc/test/src/math/bf16fmal_test.cpp14
-rw-r--r--libc/test/src/math/bf16mul_test.cpp15
-rw-r--r--libc/test/src/math/bf16mulf128_test.cpp15
-rw-r--r--libc/test/src/math/bf16mulf_test.cpp15
-rw-r--r--libc/test/src/math/bf16mull_test.cpp15
-rw-r--r--libc/test/src/math/bf16sub_test.cpp14
-rw-r--r--libc/test/src/math/bf16subf128_test.cpp14
-rw-r--r--libc/test/src/math/bf16subf_test.cpp14
-rw-r--r--libc/test/src/math/bf16subl_test.cpp14
-rw-r--r--libc/test/src/math/exhaustive/CMakeLists.txt88
-rw-r--r--libc/test/src/math/exhaustive/bfloat16_add_test.cpp65
-rw-r--r--libc/test/src/math/exhaustive/bfloat16_div_test.cpp65
-rw-r--r--libc/test/src/math/exhaustive/bfloat16_mul_test.cpp65
-rw-r--r--libc/test/src/math/exhaustive/bfloat16_sub_test.cpp65
-rw-r--r--libc/test/src/math/exhaustive/exhaustive_test.h2
-rw-r--r--libc/test/src/math/exhaustive/fmodbf16_test.cpp42
-rw-r--r--libc/test/src/math/explogxf_test.cpp4
-rw-r--r--libc/test/src/math/llrintbf16_test.cpp15
-rw-r--r--libc/test/src/math/llroundbf16_test.cpp14
-rw-r--r--libc/test/src/math/lrintbf16_test.cpp15
-rw-r--r--libc/test/src/math/lroundbf16_test.cpp14
-rw-r--r--libc/test/src/math/nearbyintbf16_test.cpp14
-rw-r--r--libc/test/src/math/rintbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/AddTest.h4
-rw-r--r--libc/test/src/math/smoke/CMakeLists.txt1134
-rw-r--r--libc/test/src/math/smoke/CeilTest.h4
-rw-r--r--libc/test/src/math/smoke/DivTest.h5
-rw-r--r--libc/test/src/math/smoke/FModTest.h58
-rw-r--r--libc/test/src/math/smoke/FloorTest.h5
-rw-r--r--libc/test/src/math/smoke/FromfpTest.h54
-rw-r--r--libc/test/src/math/smoke/FromfpxTest.h60
-rw-r--r--libc/test/src/math/smoke/GetPayloadTest.h61
-rw-r--r--libc/test/src/math/smoke/LdExpTest.h11
-rw-r--r--libc/test/src/math/smoke/ModfTest.h10
-rw-r--r--libc/test/src/math/smoke/MulTest.h10
-rw-r--r--libc/test/src/math/smoke/NextAfterTest.h43
-rw-r--r--libc/test/src/math/smoke/NextTowardTest.h4
-rw-r--r--libc/test/src/math/smoke/RoundTest.h6
-rw-r--r--libc/test/src/math/smoke/RoundToIntegerTest.h6
-rw-r--r--libc/test/src/math/smoke/SetPayloadSigTest.h34
-rw-r--r--libc/test/src/math/smoke/SetPayloadTest.h36
-rw-r--r--libc/test/src/math/smoke/SubTest.h4
-rw-r--r--libc/test/src/math/smoke/TotalOrderMagTest.h47
-rw-r--r--libc/test/src/math/smoke/TotalOrderTest.h47
-rw-r--r--libc/test/src/math/smoke/TruncTest.h4
-rw-r--r--libc/test/src/math/smoke/UfromfpTest.h26
-rw-r--r--libc/test/src/math/smoke/UfromfpxTest.h28
-rw-r--r--libc/test/src/math/smoke/asinpif16_test.cpp86
-rw-r--r--libc/test/src/math/smoke/atanpif16_test.cpp64
-rw-r--r--libc/test/src/math/smoke/bf16add_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16addf128_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16addf_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16addl_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16div_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16divf128_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16divf_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16divl_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16fma_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16fmaf128_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16fmaf_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16fmal_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16mul_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16mulf128_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16mulf_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16mull_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16sub_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16subf128_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16subf_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bf16subl_test.cpp14
-rw-r--r--libc/test/src/math/smoke/bfloat16_add_test.cpp15
-rw-r--r--libc/test/src/math/smoke/bfloat16_div_test.cpp15
-rw-r--r--libc/test/src/math/smoke/bfloat16_mul_test.cpp15
-rw-r--r--libc/test/src/math/smoke/bfloat16_sub_test.cpp15
-rw-r--r--libc/test/src/math/smoke/canonicalizebf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/ceilbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/copysignbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fdimbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/floorbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fmaxbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fmaximum_mag_numbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fmaximum_magbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fmaximum_numbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fmaximumbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fminbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fminimum_mag_numbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fminimum_magbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fminimum_numbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fminimumbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fmodbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/frexpbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fromfpbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/fromfpxbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/getpayloadbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/ilogbbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/iscanonicalbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/issignalingbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/ldexpbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/llogbbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/llrintbf16_test.cpp15
-rw-r--r--libc/test/src/math/smoke/llroundbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/logbbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/lrintbf16_test.cpp15
-rw-r--r--libc/test/src/math/smoke/lroundbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/modfbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/nanbf16_test.cpp55
-rw-r--r--libc/test/src/math/smoke/nearbyintbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/nextafterbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/nextdownbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/nexttowardbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/nextupbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/remquobf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/rintbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/roundbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/roundevenbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/scalblnbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/scalbnbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/setpayloadbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/setpayloadsigbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/totalorderbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/totalordermagbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/truncbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/ufromfpbf16_test.cpp14
-rw-r--r--libc/test/src/math/smoke/ufromfpxbf16_test.cpp14
-rw-r--r--libc/test/src/stdfix/BitsFxTest.h10
-rw-r--r--libc/test/src/string/strcspn_test.cpp4
-rw-r--r--libc/test/src/string/strpbrk_test.cpp4
-rw-r--r--libc/test/src/string/strsep_test.cpp24
-rw-r--r--libc/test/src/string/strspn_test.cpp4
-rw-r--r--libc/test/src/string/strtok_r_test.cpp17
-rw-r--r--libc/test/src/string/strtok_test.cpp14
-rw-r--r--libc/test/src/sys/random/linux/getrandom_test.cpp5
-rw-r--r--libc/test/src/time/timespec_get_test.cpp3
-rw-r--r--libc/test/src/wchar/mbrtowc_test.cpp60
-rw-r--r--libc/test/src/wctype/iswalpha_test.cpp78
-rw-r--r--libc/utils/MPFRWrapper/CMakeLists.txt1
-rw-r--r--libc/utils/MPFRWrapper/MPCommon.cpp30
-rw-r--r--libc/utils/MPFRWrapper/MPCommon.h2
-rw-r--r--libc/utils/MPFRWrapper/MPFRUtils.cpp87
-rw-r--r--libc/utils/MPFRWrapper/MPFRUtils.h2
-rw-r--r--libc/utils/hdrgen/hdrgen/header.py5
497 files changed, 14524 insertions, 2389 deletions
diff --git a/libc/benchmarks/gpu/BenchmarkLogger.cpp b/libc/benchmarks/gpu/BenchmarkLogger.cpp
deleted file mode 100644
index d5996a7..0000000
--- a/libc/benchmarks/gpu/BenchmarkLogger.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-#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
-#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"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace benchmarks {
-
-// cpp::string_view specialization
-template <>
-BenchmarkLogger &
- BenchmarkLogger::operator<< <cpp::string_view>(cpp::string_view str) {
- LIBC_NAMESPACE::write_to_stderr(str);
- return *this;
-}
-
-// cpp::string specialization
-template <>
-BenchmarkLogger &BenchmarkLogger::operator<< <cpp::string>(cpp::string str) {
- return *this << static_cast<cpp::string_view>(str);
-}
-
-// const char* specialization
-template <>
-BenchmarkLogger &BenchmarkLogger::operator<< <const char *>(const char *str) {
- return *this << cpp::string_view(str);
-}
-
-// char* specialization
-template <> BenchmarkLogger &BenchmarkLogger::operator<< <char *>(char *str) {
- return *this << cpp::string_view(str);
-}
-
-// char specialization
-template <> BenchmarkLogger &BenchmarkLogger::operator<<(char ch) {
- return *this << cpp::string_view(&ch, 1);
-}
-
-// bool specialization
-template <> BenchmarkLogger &BenchmarkLogger::operator<<(bool cond) {
- return *this << (cond ? "true" : "false");
-}
-
-// void * specialization
-template <> BenchmarkLogger &BenchmarkLogger::operator<<(void *addr) {
- return *this << "0x" << cpp::to_string(reinterpret_cast<uintptr_t>(addr));
-}
-
-template <typename T> BenchmarkLogger &BenchmarkLogger::operator<<(T t) {
- if constexpr (is_big_int_v<T> ||
- (cpp::is_integral_v<T> && cpp::is_unsigned_v<T> &&
- (sizeof(T) > sizeof(uint64_t)))) {
- static_assert(sizeof(T) % 8 == 0, "Unsupported size of UInt");
- const IntegerToString<T, radix::Hex::WithPrefix> buffer(t);
- return *this << buffer.view();
- } else {
- return *this << cpp::to_string(t);
- }
-}
-
-// is_integral specializations
-// char is already specialized to handle character
-template BenchmarkLogger &BenchmarkLogger::operator<< <short>(short);
-template BenchmarkLogger &BenchmarkLogger::operator<< <int>(int);
-template BenchmarkLogger &BenchmarkLogger::operator<< <long>(long);
-template BenchmarkLogger &BenchmarkLogger::operator<< <long long>(long long);
-template BenchmarkLogger &
- BenchmarkLogger::operator<< <unsigned char>(unsigned char);
-template BenchmarkLogger &
- BenchmarkLogger::operator<< <unsigned short>(unsigned short);
-template BenchmarkLogger &
- BenchmarkLogger::operator<< <unsigned int>(unsigned int);
-template BenchmarkLogger &
- BenchmarkLogger::operator<< <unsigned long>(unsigned long);
-template BenchmarkLogger &
- BenchmarkLogger::operator<< <unsigned long long>(unsigned long long);
-
-#ifdef LIBC_TYPES_HAS_INT128
-template BenchmarkLogger &
- BenchmarkLogger::operator<< <__uint128_t>(__uint128_t);
-#endif // LIBC_TYPES_HAS_INT128
-template BenchmarkLogger &BenchmarkLogger::operator<< <UInt<128>>(UInt<128>);
-template BenchmarkLogger &BenchmarkLogger::operator<< <UInt<192>>(UInt<192>);
-template BenchmarkLogger &BenchmarkLogger::operator<< <UInt<256>>(UInt<256>);
-template BenchmarkLogger &BenchmarkLogger::operator<< <UInt<320>>(UInt<320>);
-
-// TODO: Add floating point formatting once it's supported by StringStream.
-
-BenchmarkLogger log;
-
-} // namespace benchmarks
-} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/benchmarks/gpu/BenchmarkLogger.h b/libc/benchmarks/gpu/BenchmarkLogger.h
deleted file mode 100644
index 2b22aba..0000000
--- a/libc/benchmarks/gpu/BenchmarkLogger.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===-- Utilities to log to standard output during tests --------*- 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_BENCHMARKS_GPU_BENCHMARKLOGGER_H
-#define LLVM_LIBC_BENCHMARKS_GPU_BENCHMARKLOGGER_H
-
-#include "src/__support/macros/config.h"
-
-namespace LIBC_NAMESPACE_DECL {
-namespace benchmarks {
-
-// A class to log to standard output in the context of hermetic tests.
-struct BenchmarkLogger {
- constexpr BenchmarkLogger() = default;
- template <typename T> BenchmarkLogger &operator<<(T);
-};
-
-// A global TestLogger instance to be used in tests.
-extern BenchmarkLogger log;
-
-} // namespace benchmarks
-} // namespace LIBC_NAMESPACE_DECL
-
-#endif /* LLVM_LIBC_BENCHMARKS_GPU_BENCHMARKLOGGER_H */
diff --git a/libc/benchmarks/gpu/CMakeLists.txt b/libc/benchmarks/gpu/CMakeLists.txt
index 6ec64bf2..cf8c990 100644
--- a/libc/benchmarks/gpu/CMakeLists.txt
+++ b/libc/benchmarks/gpu/CMakeLists.txt
@@ -22,8 +22,6 @@ function(add_benchmark benchmark_name)
${BENCHMARK_LINK_LIBRARIES}
DEPENDS
libc.src.stdio.printf
- libc.src.stdlib.srand
- libc.src.stdlib.rand
${BENCHMARK_DEPENDS}
${BENCHMARK_UNPARSED_ARGUMENTS}
COMPILE_OPTIONS
@@ -40,34 +38,31 @@ add_unittest_framework_library(
SRCS
LibcGpuBenchmark.cpp
LibcGpuBenchmarkMain.cpp
- BenchmarkLogger.cpp
HDRS
LibcGpuBenchmark.h
- BenchmarkLogger.h
+ Random.h
DEPENDS
+ libc.benchmarks.gpu.timing.timing
libc.hdr.stdint_proxy
- libc.src.__support.big_int
- libc.src.__support.c_string
libc.src.__support.CPP.string
libc.src.__support.CPP.string_view
libc.src.__support.CPP.type_traits
- libc.src.__support.CPP.functional
- libc.src.__support.CPP.limits
libc.src.__support.CPP.algorithm
libc.src.__support.CPP.atomic
libc.src.__support.CPP.array
- libc.src.__support.fixed_point.fx_rep
- libc.src.__support.macros.properties.types
- libc.src.__support.OSUtil.osutil
- libc.src.__support.uint128
+ libc.src.__support.CPP.optional
libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.FPUtil.sqrt
+ libc.src.__support.sign
libc.src.__support.fixedvector
- libc.src.time.clock
- libc.src.stdlib.rand
- libc.src.stdlib.srand
- libc.benchmarks.gpu.timing.timing
+ libc.src.__support.GPU.utils
+ libc.src.__support.time.gpu.time_utils
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
libc.src.stdio.printf
+ libc.src.time.clock
)
add_subdirectory(src)
diff --git a/libc/benchmarks/gpu/LibcGpuBenchmark.cpp b/libc/benchmarks/gpu/LibcGpuBenchmark.cpp
index 57ff5b9..a4a0ff4 100644
--- a/libc/benchmarks/gpu/LibcGpuBenchmark.cpp
+++ b/libc/benchmarks/gpu/LibcGpuBenchmark.cpp
@@ -1,15 +1,18 @@
#include "LibcGpuBenchmark.h"
+
+#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/algorithm.h"
-#include "src/__support/CPP/array.h"
#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/string.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/GPU/utils.h"
#include "src/__support/fixedvector.h"
#include "src/__support/macros/config.h"
#include "src/__support/time/gpu/time_utils.h"
#include "src/stdio/printf.h"
-#include "src/stdlib/srand.h"
+#include "src/time/clock.h"
namespace LIBC_NAMESPACE_DECL {
namespace benchmarks {
@@ -20,37 +23,56 @@ void Benchmark::add_benchmark(Benchmark *benchmark) {
benchmarks.push_back(benchmark);
}
+static void atomic_add_double(cpp::Atomic<uint64_t> &atomic_bits,
+ double value) {
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<double>;
+
+ uint64_t expected_bits = atomic_bits.load(cpp::MemoryOrder::RELAXED);
+
+ while (true) {
+ double current_value = FPBits(expected_bits).get_val();
+ double next_value = current_value + value;
+
+ uint64_t desired_bits = FPBits(next_value).uintval();
+ if (atomic_bits.compare_exchange_strong(expected_bits, desired_bits,
+ cpp::MemoryOrder::ACQUIRE,
+ cpp::MemoryOrder::RELAXED))
+ break;
+ }
+}
+
struct AtomicBenchmarkSums {
- cpp::Atomic<uint64_t> cycles_sum = 0;
- cpp::Atomic<uint64_t> standard_deviation_sum = 0;
+ cpp::Atomic<uint32_t> active_threads = 0;
+ cpp::Atomic<uint64_t> iterations_sum = 0;
+ cpp::Atomic<uint64_t> weighted_cycles_sum_bits = 0;
+ cpp::Atomic<uint64_t> weighted_squared_cycles_sum_bits = 0;
cpp::Atomic<uint64_t> min = UINT64_MAX;
cpp::Atomic<uint64_t> max = 0;
- cpp::Atomic<uint32_t> samples_sum = 0;
- cpp::Atomic<uint32_t> iterations_sum = 0;
- cpp::Atomic<clock_t> time_sum = 0;
- cpp::Atomic<uint64_t> active_threads = 0;
void reset() {
cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE);
active_threads.store(0, cpp::MemoryOrder::RELAXED);
- cycles_sum.store(0, cpp::MemoryOrder::RELAXED);
- standard_deviation_sum.store(0, cpp::MemoryOrder::RELAXED);
+ iterations_sum.store(0, cpp::MemoryOrder::RELAXED);
+ weighted_cycles_sum_bits.store(0, cpp::MemoryOrder::RELAXED);
+ weighted_squared_cycles_sum_bits.store(0, cpp::MemoryOrder::RELAXED);
min.store(UINT64_MAX, cpp::MemoryOrder::RELAXED);
max.store(0, cpp::MemoryOrder::RELAXED);
- samples_sum.store(0, cpp::MemoryOrder::RELAXED);
- iterations_sum.store(0, cpp::MemoryOrder::RELAXED);
- time_sum.store(0, cpp::MemoryOrder::RELAXED);
cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE);
}
void update(const BenchmarkResult &result) {
cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE);
active_threads.fetch_add(1, cpp::MemoryOrder::RELAXED);
+ iterations_sum.fetch_add(result.total_iterations,
+ cpp::MemoryOrder::RELAXED);
- cycles_sum.fetch_add(result.cycles, cpp::MemoryOrder::RELAXED);
- standard_deviation_sum.fetch_add(
- static_cast<uint64_t>(result.standard_deviation),
- cpp::MemoryOrder::RELAXED);
+ const double n_i = static_cast<double>(result.total_iterations);
+ const double mean_i = result.cycles;
+ const double stddev_i = result.standard_deviation;
+ const double variance_i = stddev_i * stddev_i;
+ atomic_add_double(weighted_cycles_sum_bits, n_i * mean_i);
+ atomic_add_double(weighted_squared_cycles_sum_bits,
+ n_i * (variance_i + mean_i * mean_i));
// Perform a CAS loop to atomically update the min
uint64_t orig_min = min.load(cpp::MemoryOrder::RELAXED);
@@ -66,10 +88,6 @@ struct AtomicBenchmarkSums {
cpp::MemoryOrder::RELAXED))
;
- samples_sum.fetch_add(result.samples, cpp::MemoryOrder::RELAXED);
- iterations_sum.fetch_add(result.total_iterations,
- cpp::MemoryOrder::RELAXED);
- time_sum.fetch_add(result.total_time, cpp::MemoryOrder::RELAXED);
cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE);
}
};
@@ -79,46 +97,51 @@ constexpr auto GREEN = "\033[32m";
constexpr auto RESET = "\033[0m";
void print_results(Benchmark *b) {
- BenchmarkResult result;
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<double>;
+
+ BenchmarkResult final_result;
cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE);
- int num_threads = all_results.active_threads.load(cpp::MemoryOrder::RELAXED);
- result.cycles =
- all_results.cycles_sum.load(cpp::MemoryOrder::RELAXED) / num_threads;
- result.standard_deviation =
- all_results.standard_deviation_sum.load(cpp::MemoryOrder::RELAXED) /
- num_threads;
- result.min = all_results.min.load(cpp::MemoryOrder::RELAXED);
- result.max = all_results.max.load(cpp::MemoryOrder::RELAXED);
- result.samples =
- all_results.samples_sum.load(cpp::MemoryOrder::RELAXED) / num_threads;
- result.total_iterations =
- all_results.iterations_sum.load(cpp::MemoryOrder::RELAXED) / num_threads;
- const uint64_t duration_ns =
- all_results.time_sum.load(cpp::MemoryOrder::RELAXED) / num_threads;
- const uint64_t duration_us = duration_ns / 1000;
- const uint64_t duration_ms = duration_ns / (1000 * 1000);
- uint64_t converted_duration = duration_ns;
- const char *time_unit;
- if (duration_ms != 0) {
- converted_duration = duration_ms;
- time_unit = "ms";
- } else if (duration_us != 0) {
- converted_duration = duration_us;
- time_unit = "us";
+
+ const uint32_t num_threads =
+ all_results.active_threads.load(cpp::MemoryOrder::RELAXED);
+ final_result.total_iterations =
+ all_results.iterations_sum.load(cpp::MemoryOrder::RELAXED);
+
+ if (final_result.total_iterations > 0) {
+ const uint64_t s1_bits =
+ all_results.weighted_cycles_sum_bits.load(cpp::MemoryOrder::RELAXED);
+ const uint64_t s2_bits = all_results.weighted_squared_cycles_sum_bits.load(
+ cpp::MemoryOrder::RELAXED);
+
+ const double S1 = FPBits(s1_bits).get_val();
+ const double S2 = FPBits(s2_bits).get_val();
+ const double N = static_cast<double>(final_result.total_iterations);
+
+ const double global_mean = S1 / N;
+ const double global_mean_of_squares = S2 / N;
+ const double global_variance =
+ global_mean_of_squares - (global_mean * global_mean);
+
+ final_result.cycles = global_mean;
+ final_result.standard_deviation =
+ fputil::sqrt<double>(global_variance < 0.0 ? 0.0 : global_variance);
} else {
- converted_duration = duration_ns;
- time_unit = "ns";
+ final_result.cycles = 0.0;
+ final_result.standard_deviation = 0.0;
}
- result.total_time = converted_duration;
- // result.total_time =
- // all_results.time_sum.load(cpp::MemoryOrder::RELAXED) / num_threads;
+
+ final_result.min = all_results.min.load(cpp::MemoryOrder::RELAXED);
+ final_result.max = all_results.max.load(cpp::MemoryOrder::RELAXED);
cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE);
LIBC_NAMESPACE::printf(
- "%-24s |%8ld |%8ld |%8ld |%11d |%14ld %2s |%9ld |%9d |\n",
- b->get_test_name().data(), result.cycles, result.min, result.max,
- result.total_iterations, result.total_time, time_unit,
- static_cast<uint64_t>(result.standard_deviation), num_threads);
+ "%-24s |%15.0f |%9.0f |%8llu |%8llu |%15llu |%9u |\n",
+ b->get_test_name().data(), final_result.cycles,
+ final_result.standard_deviation,
+ static_cast<unsigned long long>(final_result.min),
+ static_cast<unsigned long long>(final_result.max),
+ static_cast<unsigned long long>(final_result.total_iterations),
+ static_cast<unsigned>(num_threads));
}
void print_header() {
@@ -126,9 +149,8 @@ void print_header() {
LIBC_NAMESPACE::printf("Running Suite: %-10s\n",
benchmarks[0]->get_suite_name().data());
LIBC_NAMESPACE::printf("%s", RESET);
- cpp::string titles =
- "Benchmark | Cycles | Min | Max | "
- "Iterations | Time / Iteration | Stddev | Threads |\n";
+ cpp::string titles = "Benchmark | Cycles (Mean) | Stddev | "
+ " Min | Max | Iterations | Threads |\n";
LIBC_NAMESPACE::printf(titles.data());
cpp::string separator(titles.size(), '-');
@@ -139,10 +161,8 @@ void print_header() {
void Benchmark::run_benchmarks() {
uint64_t id = gpu::get_thread_id();
- if (id == 0) {
+ if (id == 0)
print_header();
- LIBC_NAMESPACE::srand(gpu::processor_clock());
- }
gpu::sync_threads();
@@ -164,69 +184,64 @@ void Benchmark::run_benchmarks() {
}
BenchmarkResult benchmark(const BenchmarkOptions &options,
- cpp::function<uint64_t(void)> wrapper_func) {
+ const BenchmarkTarget &target) {
BenchmarkResult result;
RuntimeEstimationProgression rep;
- uint32_t total_iterations = 0;
uint32_t iterations = options.initial_iterations;
+
if (iterations < 1u)
iterations = 1;
uint32_t samples = 0;
uint64_t total_time = 0;
- uint64_t best_guess = 0;
- uint64_t cycles_squared = 0;
uint64_t min = UINT64_MAX;
uint64_t max = 0;
- uint64_t overhead = UINT64_MAX;
- int overhead_iterations = 10;
- for (int i = 0; i < overhead_iterations; i++)
- overhead = cpp::min(overhead, LIBC_NAMESPACE::overhead());
+ uint32_t call_index = 0;
for (int64_t time_budget = options.max_duration; time_budget >= 0;) {
- uint64_t sample_cycles = 0;
- const clock_t start = static_cast<double>(clock());
- for (uint32_t i = 0; i < iterations; i++) {
- auto wrapper_intermediate = wrapper_func();
- uint64_t current_result = wrapper_intermediate - overhead;
+ RefinableRuntimeEstimator sample_estimator;
+
+ const clock_t start = clock();
+ while (sample_estimator.get_iterations() < iterations) {
+ auto current_result = target(call_index++);
max = cpp::max(max, current_result);
min = cpp::min(min, current_result);
- sample_cycles += current_result;
+ sample_estimator.update(current_result);
}
const clock_t end = clock();
+
const clock_t duration_ns =
((end - start) * 1000 * 1000 * 1000) / CLOCKS_PER_SEC;
total_time += duration_ns;
time_budget -= duration_ns;
samples++;
- cycles_squared += sample_cycles * sample_cycles;
- total_iterations += iterations;
- const double change_ratio =
- rep.compute_improvement({iterations, sample_cycles});
- best_guess = rep.current_estimation;
+ const double change_ratio = rep.compute_improvement(sample_estimator);
if (samples >= options.max_samples || iterations >= options.max_iterations)
break;
+
+ const auto total_iterations = rep.get_estimator().get_iterations();
+
if (total_time >= options.min_duration && samples >= options.min_samples &&
total_iterations >= options.min_iterations &&
change_ratio < options.epsilon)
break;
- iterations *= options.scaling_factor;
+ iterations = static_cast<uint32_t>(
+ fputil::ceil(iterations * options.scaling_factor));
}
- result.cycles = best_guess;
- result.standard_deviation = fputil::sqrt<double>(
- static_cast<double>(cycles_squared) / total_iterations -
- static_cast<double>(best_guess * best_guess));
+
+ const auto &estimator = rep.get_estimator();
+ result.total_iterations = estimator.get_iterations();
+ result.cycles = estimator.get_mean();
+ result.standard_deviation = estimator.get_stddev();
result.min = min;
result.max = max;
- result.samples = samples;
- result.total_iterations = total_iterations;
- result.total_time = total_time / total_iterations;
+
return result;
-};
+}
} // namespace benchmarks
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/benchmarks/gpu/LibcGpuBenchmark.h b/libc/benchmarks/gpu/LibcGpuBenchmark.h
index a6cf62d..b310d49 100644
--- a/libc/benchmarks/gpu/LibcGpuBenchmark.h
+++ b/libc/benchmarks/gpu/LibcGpuBenchmark.h
@@ -1,18 +1,18 @@
#ifndef LLVM_LIBC_BENCHMARKS_LIBC_GPU_BENCHMARK_H
#define LLVM_LIBC_BENCHMARKS_LIBC_GPU_BENCHMARK_H
-#include "benchmarks/gpu/BenchmarkLogger.h"
+#include "benchmarks/gpu/Random.h"
+
#include "benchmarks/gpu/timing/timing.h"
+
#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/array.h"
-#include "src/__support/CPP/functional.h"
-#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/macros/config.h"
-#include "src/stdlib/rand.h"
-#include "src/time/clock.h"
namespace LIBC_NAMESPACE_DECL {
@@ -30,68 +30,136 @@ struct BenchmarkOptions {
double scaling_factor = 1.4;
};
-struct Measurement {
+class RefinableRuntimeEstimator {
uint32_t iterations = 0;
- uint64_t elapsed_cycles = 0;
-};
-
-class RefinableRuntimeEstimation {
- uint64_t total_cycles = 0;
- uint32_t total_iterations = 0;
+ uint64_t sum_of_cycles = 0;
+ uint64_t sum_of_squared_cycles = 0;
public:
- uint64_t update(const Measurement &M) {
- total_cycles += M.elapsed_cycles;
- total_iterations += M.iterations;
- return total_cycles / total_iterations;
+ void update(uint64_t cycles) noexcept {
+ iterations += 1;
+ sum_of_cycles += cycles;
+ sum_of_squared_cycles += cycles * cycles;
+ }
+
+ void update(const RefinableRuntimeEstimator &other) noexcept {
+ iterations += other.iterations;
+ sum_of_cycles += other.sum_of_cycles;
+ sum_of_squared_cycles += other.sum_of_squared_cycles;
}
+
+ double get_mean() const noexcept {
+ if (iterations == 0)
+ return 0.0;
+
+ return static_cast<double>(sum_of_cycles) / iterations;
+ }
+
+ double get_variance() const noexcept {
+ if (iterations == 0)
+ return 0.0;
+
+ const double num = static_cast<double>(iterations);
+ const double sum_x = static_cast<double>(sum_of_cycles);
+ const double sum_x2 = static_cast<double>(sum_of_squared_cycles);
+
+ const double mean_of_squares = sum_x2 / num;
+ const double mean = sum_x / num;
+ const double mean_squared = mean * mean;
+ const double variance = mean_of_squares - mean_squared;
+
+ return variance < 0.0 ? 0.0 : variance;
+ }
+
+ double get_stddev() const noexcept {
+ return fputil::sqrt<double>(get_variance());
+ }
+
+ uint32_t get_iterations() const noexcept { return iterations; }
};
// Tracks the progression of the runtime estimation
class RuntimeEstimationProgression {
- RefinableRuntimeEstimation rre;
+ RefinableRuntimeEstimator estimator;
+ double current_mean = 0.0;
public:
- uint64_t current_estimation = 0;
+ const RefinableRuntimeEstimator &get_estimator() const noexcept {
+ return estimator;
+ }
+
+ double
+ compute_improvement(const RefinableRuntimeEstimator &sample_estimator) {
+ if (sample_estimator.get_iterations() == 0)
+ return 1.0;
- double compute_improvement(const Measurement &M) {
- const uint64_t new_estimation = rre.update(M);
- double ratio =
- (static_cast<double>(current_estimation) / new_estimation) - 1.0;
+ estimator.update(sample_estimator);
- // Get absolute value
+ const double new_mean = estimator.get_mean();
+ if (current_mean == 0.0 || new_mean == 0.0) {
+ current_mean = new_mean;
+ return 1.0;
+ }
+
+ double ratio = (current_mean / new_mean) - 1.0;
if (ratio < 0)
- ratio *= -1;
+ ratio = -ratio;
- current_estimation = new_estimation;
+ current_mean = new_mean;
return ratio;
}
};
struct BenchmarkResult {
- uint64_t cycles = 0;
+ uint64_t total_iterations = 0;
+ double cycles = 0;
double standard_deviation = 0;
uint64_t min = UINT64_MAX;
uint64_t max = 0;
- uint32_t samples = 0;
- uint32_t total_iterations = 0;
- clock_t total_time = 0;
+};
+
+struct BenchmarkTarget {
+ using IndexedFnPtr = uint64_t (*)(uint32_t);
+ using IndexlessFnPtr = uint64_t (*)();
+
+ enum class Kind : uint8_t { Indexed, Indexless } kind;
+ union {
+ IndexedFnPtr indexed_fn_ptr;
+ IndexlessFnPtr indexless_fn_ptr;
+ };
+
+ LIBC_INLINE BenchmarkTarget(IndexedFnPtr func)
+ : kind(Kind::Indexed), indexed_fn_ptr(func) {}
+ LIBC_INLINE BenchmarkTarget(IndexlessFnPtr func)
+ : kind(Kind::Indexless), indexless_fn_ptr(func) {}
+
+ LIBC_INLINE uint64_t operator()([[maybe_unused]] uint32_t call_index) const {
+ return kind == Kind::Indexed ? indexed_fn_ptr(call_index)
+ : indexless_fn_ptr();
+ }
};
BenchmarkResult benchmark(const BenchmarkOptions &options,
- cpp::function<uint64_t(void)> wrapper_func);
+ const BenchmarkTarget &target);
class Benchmark {
- const cpp::function<uint64_t(void)> func;
+ const BenchmarkTarget target;
const cpp::string_view suite_name;
const cpp::string_view test_name;
const uint32_t num_threads;
public:
- Benchmark(cpp::function<uint64_t(void)> func, char const *suite_name,
+ Benchmark(uint64_t (*f)(), const char *suite, const char *test,
+ uint32_t threads)
+ : target(BenchmarkTarget(f)), suite_name(suite), test_name(test),
+ num_threads(threads) {
+ add_benchmark(this);
+ }
+
+ Benchmark(uint64_t (*f)(uint32_t), char const *suite_name,
char const *test_name, uint32_t num_threads)
- : func(func), suite_name(suite_name), test_name(test_name),
- num_threads(num_threads) {
+ : target(BenchmarkTarget(f)), suite_name(suite_name),
+ test_name(test_name), num_threads(num_threads) {
add_benchmark(this);
}
@@ -105,67 +173,49 @@ protected:
private:
BenchmarkResult run() {
BenchmarkOptions options;
- return benchmark(options, func);
+ return benchmark(options, target);
}
};
-// We want our random values to be approximately
-// Output: a random number with the exponent field between min_exp and max_exp,
-// i.e. 2^min_exp <= |real_value| < 2^(max_exp + 1),
-// Caveats:
-// -EXP_BIAS corresponding to denormal values,
-// EXP_BIAS + 1 corresponding to inf or nan.
-template <typename T>
-static T
-get_rand_input(int max_exp = LIBC_NAMESPACE::fputil::FPBits<T>::EXP_BIAS,
- int min_exp = -LIBC_NAMESPACE::fputil::FPBits<T>::EXP_BIAS) {
- using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
-
- // Required to correctly instantiate FPBits for floats and doubles.
- using RandType = typename cpp::conditional_t<(cpp::is_same_v<T, double>),
- uint64_t, uint32_t>;
- RandType bits;
- if constexpr (cpp::is_same_v<T, uint64_t>)
- bits = (static_cast<uint64_t>(LIBC_NAMESPACE::rand()) << 32) |
- static_cast<uint64_t>(LIBC_NAMESPACE::rand());
- else
- bits = LIBC_NAMESPACE::rand();
- double scale =
- static_cast<double>(max_exp - min_exp + 1) / (2 * FPBits::EXP_BIAS + 1);
- FPBits fp(bits);
- fp.set_biased_exponent(
- static_cast<uint32_t>(fp.get_biased_exponent() * scale + min_exp));
- return fp.get_val();
-}
-
template <typename T> class MathPerf {
- using FPBits = fputil::FPBits<T>;
- using StorageType = typename FPBits::StorageType;
- static constexpr StorageType UIntMax =
- cpp::numeric_limits<StorageType>::max();
+ static LIBC_INLINE uint64_t make_seed(uint64_t base_seed, uint64_t salt) {
+ const uint64_t tid = gpu::get_thread_id();
+ return base_seed ^ (salt << 32) ^ (tid * 0x9E3779B97F4A7C15ULL);
+ }
public:
- template <size_t N = 1>
- static uint64_t run_throughput_in_range(T f(T), int min_exp, int max_exp) {
+ // Returns cycles-per-call (lower is better)
+ template <size_t N = 1, typename Dist>
+ static uint64_t run_throughput(T (*f)(T), const Dist &dist,
+ uint32_t call_index) {
cpp::array<T, N> inputs;
+
+ uint64_t base_seed = static_cast<uint64_t>(call_index);
+ uint64_t salt = static_cast<uint64_t>(N);
+ RandomGenerator rng(make_seed(base_seed, salt));
+
for (size_t i = 0; i < N; ++i)
- inputs[i] = get_rand_input<T>(min_exp, max_exp);
+ inputs[i] = dist(rng);
uint64_t total_time = LIBC_NAMESPACE::throughput(f, inputs);
return total_time / N;
}
- // Throughput benchmarking for functions that take 2 inputs.
- template <size_t N = 1>
- static uint64_t run_throughput_in_range(T f(T, T), int arg1_min_exp,
- int arg1_max_exp, int arg2_min_exp,
- int arg2_max_exp) {
+ // Returns cycles-per-call (lower is better)
+ template <size_t N = 1, typename Dist1, typename Dist2>
+ static uint64_t run_throughput(T (*f)(T, T), const Dist1 &dist1,
+ const Dist2 &dist2, uint32_t call_index) {
cpp::array<T, N> inputs1;
cpp::array<T, N> inputs2;
+
+ uint64_t base_seed = static_cast<uint64_t>(call_index);
+ uint64_t salt = static_cast<uint64_t>(N);
+ RandomGenerator rng(make_seed(base_seed, salt));
+
for (size_t i = 0; i < N; ++i) {
- inputs1[i] = get_rand_input<T>(arg1_min_exp, arg1_max_exp);
- inputs2[i] = get_rand_input<T>(arg2_min_exp, arg2_max_exp);
+ inputs1[i] = dist1(rng);
+ inputs2[i] = dist2(rng);
}
uint64_t total_time = LIBC_NAMESPACE::throughput(f, inputs1, inputs2);
@@ -193,4 +243,5 @@ public:
#define SINGLE_WAVE_BENCHMARK(SuiteName, TestName, Func) \
BENCHMARK_N_THREADS(SuiteName, TestName, Func, \
LIBC_NAMESPACE::gpu::get_lane_size())
-#endif
+
+#endif // LLVM_LIBC_BENCHMARKS_LIBC_GPU_BENCHMARK_H
diff --git a/libc/benchmarks/gpu/Random.h b/libc/benchmarks/gpu/Random.h
new file mode 100644
index 0000000..f7d2722
--- /dev/null
+++ b/libc/benchmarks/gpu/Random.h
@@ -0,0 +1,190 @@
+//===-- Pseudo-random number generation utilities ---------------*- 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_BENCHMARKS_GPU_RANDOM_H
+#define LLVM_LIBC_BENCHMARKS_GPU_RANDOM_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/algorithm.h"
+#include "src/__support/CPP/optional.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+#include "src/__support/sign.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace benchmarks {
+
+// Pseudo-random number generator (PRNG) that produces unsigned 64-bit, 32-bit,
+// and 16-bit integers. The implementation is based on the xorshift* generator,
+// seeded using SplitMix64 for robust initialization. For more details, see:
+// https://en.wikipedia.org/wiki/Xorshift
+class RandomGenerator {
+ uint64_t state;
+
+ static LIBC_INLINE uint64_t splitmix64(uint64_t x) noexcept {
+ x += 0x9E3779B97F4A7C15ULL;
+ x = (x ^ (x >> 30)) * 0xBF58476D1CE4E5B9ULL;
+ x = (x ^ (x >> 27)) * 0x94D049BB133111EBULL;
+ x = (x ^ (x >> 31));
+ return x ? x : 0x9E3779B97F4A7C15ULL;
+ }
+
+public:
+ explicit LIBC_INLINE RandomGenerator(uint64_t seed) noexcept
+ : state(splitmix64(seed)) {}
+
+ LIBC_INLINE uint64_t next64() noexcept {
+ uint64_t x = state;
+ x ^= x >> 12;
+ x ^= x << 25;
+ x ^= x >> 27;
+ state = x;
+ return x * 0x2545F4914F6CDD1DULL;
+ }
+
+ LIBC_INLINE uint32_t next32() noexcept {
+ return static_cast<uint32_t>(next64() >> 32);
+ }
+
+ LIBC_INLINE uint16_t next16() noexcept {
+ return static_cast<uint16_t>(next64() >> 48);
+ }
+};
+
+// Generates random floating-point numbers where the unbiased binary exponent
+// is sampled uniformly in `[min_exp, max_exp]`. The significand bits are
+// always randomized, while the sign is randomized by default but can be fixed.
+// Evenly covers orders of magnitude; never yields Inf/NaN.
+template <typename T> class UniformExponent {
+ static_assert(cpp::is_same_v<T, float16> || cpp::is_same_v<T, float> ||
+ cpp::is_same_v<T, double>,
+ "UniformExponent supports float16, float, and double");
+
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
+ using Storage = typename FPBits::StorageType;
+
+public:
+ explicit UniformExponent(int min_exp = -FPBits::EXP_BIAS,
+ int max_exp = FPBits::EXP_BIAS,
+ cpp::optional<Sign> forced_sign = cpp::nullopt)
+ : min_exp(clamp_exponent(cpp::min(min_exp, max_exp))),
+ max_exp(clamp_exponent(cpp::max(min_exp, max_exp))),
+ forced_sign(forced_sign) {}
+
+ LIBC_INLINE T operator()(RandomGenerator &rng) const noexcept {
+ // Sample unbiased exponent e uniformly in [min_exp, max_exp] without modulo
+ // bias, using rejection sampling
+ auto sample_in_range = [&](uint64_t r) -> int32_t {
+ const uint64_t range = static_cast<uint64_t>(
+ static_cast<int64_t>(max_exp) - static_cast<int64_t>(min_exp) + 1);
+ const uint64_t threshold = (-range) % range;
+ while (r < threshold)
+ r = rng.next64();
+ return static_cast<int32_t>(min_exp + static_cast<int64_t>(r % range));
+ };
+ const int32_t e = sample_in_range(rng.next64());
+
+ // Start from random bits to get random sign and mantissa
+ FPBits xbits([&] {
+ if constexpr (cpp::is_same_v<T, double>)
+ return FPBits(rng.next64());
+ else if constexpr (cpp::is_same_v<T, float>)
+ return FPBits(rng.next32());
+ else
+ return FPBits(rng.next16());
+ }());
+
+ if (e == -FPBits::EXP_BIAS) {
+ // Subnormal: biased exponent must be 0; ensure mantissa != 0 to avoid 0
+ xbits.set_biased_exponent(Storage(0));
+ if (xbits.get_mantissa() == Storage(0))
+ xbits.set_mantissa(Storage(1));
+ } else {
+ // Normal: biased exponent in [1, 2 * FPBits::EXP_BIAS]
+ const int32_t biased = e + FPBits::EXP_BIAS;
+ xbits.set_biased_exponent(static_cast<Storage>(biased));
+ }
+
+ if (forced_sign)
+ xbits.set_sign(*forced_sign);
+
+ return xbits.get_val();
+ }
+
+private:
+ static LIBC_INLINE int clamp_exponent(int val) noexcept {
+ if (val < -FPBits::EXP_BIAS)
+ return -FPBits::EXP_BIAS;
+
+ if (val > FPBits::EXP_BIAS)
+ return FPBits::EXP_BIAS;
+
+ return val;
+ }
+
+ const int min_exp;
+ const int max_exp;
+ const cpp::optional<Sign> forced_sign;
+};
+
+// Generates random floating-point numbers that are uniformly distributed on
+// a linear scale. Values are sampled from `[min_val, max_val)`.
+template <typename T> class UniformLinear {
+ static_assert(cpp::is_same_v<T, float16> || cpp::is_same_v<T, float> ||
+ cpp::is_same_v<T, double>,
+ "UniformLinear supports float16, float, and double");
+
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
+ using Storage = typename FPBits::StorageType;
+
+ static constexpr T MAX_NORMAL = FPBits::max_normal().get_val();
+
+public:
+ explicit UniformLinear(T min_val = -MAX_NORMAL, T max_val = MAX_NORMAL)
+ : min_val(clamp_val(cpp::min(min_val, max_val))),
+ max_val(clamp_val(cpp::max(min_val, max_val))) {}
+
+ LIBC_INLINE T operator()(RandomGenerator &rng) const noexcept {
+ double u = standard_uniform(rng.next64());
+ double a = static_cast<double>(min_val);
+ double b = static_cast<double>(max_val);
+ double y = a + (b - a) * u;
+ return static_cast<T>(y);
+ }
+
+private:
+ static LIBC_INLINE T clamp_val(T val) noexcept {
+ if (val < -MAX_NORMAL)
+ return -MAX_NORMAL;
+
+ if (val > MAX_NORMAL)
+ return MAX_NORMAL;
+
+ return val;
+ }
+
+ static LIBC_INLINE double standard_uniform(uint64_t x) noexcept {
+ constexpr int PREC_BITS =
+ LIBC_NAMESPACE::fputil::FPBits<double>::SIG_LEN + 1;
+ constexpr int SHIFT_BITS = LIBC_NAMESPACE::fputil::FPBits<double>::EXP_LEN;
+ constexpr double INV = 1.0 / static_cast<double>(1ULL << PREC_BITS);
+
+ return static_cast<double>(x >> SHIFT_BITS) * INV;
+ }
+
+ const T min_val;
+ const T max_val;
+};
+
+} // namespace benchmarks
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif
diff --git a/libc/benchmarks/gpu/src/math/CMakeLists.txt b/libc/benchmarks/gpu/src/math/CMakeLists.txt
index 7a12ce4e..53da45d 100644
--- a/libc/benchmarks/gpu/src/math/CMakeLists.txt
+++ b/libc/benchmarks/gpu/src/math/CMakeLists.txt
@@ -25,20 +25,19 @@ if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU)
endif()
add_benchmark(
- sin_benchmark
+ atan2_benchmark
SUITE
libc-gpu-math-benchmarks
SRCS
- sin_benchmark.cpp
+ atan2_benchmark.cpp
+ HDRS
+ platform.h
DEPENDS
libc.hdr.stdint_proxy
- libc.src.math.sin
- libc.src.math.sinf
- libc.src.stdlib.srand
- libc.src.stdlib.rand
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.CPP.bit
- libc.src.__support.CPP.array
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.math.atan2
COMPILE_OPTIONS
${math_benchmark_flags}
LOADER_ARGS
@@ -46,19 +45,143 @@ add_benchmark(
)
add_benchmark(
- atan2_benchmark
+ exp_benchmark
SUITE
libc-gpu-math-benchmarks
SRCS
- atan2_benchmark.cpp
+ exp_benchmark.cpp
+ HDRS
+ platform.h
DEPENDS
libc.hdr.stdint_proxy
- libc.src.math.atan2
- libc.src.stdlib.srand
- libc.src.stdlib.rand
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.CPP.bit
- libc.src.__support.CPP.array
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.math.exp
+ COMPILE_OPTIONS
+ ${math_benchmark_flags}
+ LOADER_ARGS
+ --threads 64
+)
+
+add_benchmark(
+ expf_benchmark
+ SUITE
+ libc-gpu-math-benchmarks
+ SRCS
+ expf_benchmark.cpp
+ HDRS
+ platform.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.math.expf
+ COMPILE_OPTIONS
+ ${math_benchmark_flags}
+ LOADER_ARGS
+ --threads 64
+)
+
+add_benchmark(
+ expf16_benchmark
+ SUITE
+ libc-gpu-math-benchmarks
+ SRCS
+ expf16_benchmark.cpp
+ HDRS
+ platform.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.math.expf16
+ COMPILE_OPTIONS
+ ${math_benchmark_flags}
+ LOADER_ARGS
+ --threads 64
+)
+
+add_benchmark(
+ log_benchmark
+ SUITE
+ libc-gpu-math-benchmarks
+ SRCS
+ log_benchmark.cpp
+ HDRS
+ platform.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.sign
+ libc.src.math.log
+ COMPILE_OPTIONS
+ ${math_benchmark_flags}
+ LOADER_ARGS
+ --threads 64
+)
+
+add_benchmark(
+ logf_benchmark
+ SUITE
+ libc-gpu-math-benchmarks
+ SRCS
+ logf_benchmark.cpp
+ HDRS
+ platform.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.sign
+ libc.src.math.logf
+ COMPILE_OPTIONS
+ ${math_benchmark_flags}
+ LOADER_ARGS
+ --threads 64
+)
+
+add_benchmark(
+ logf16_benchmark
+ SUITE
+ libc-gpu-math-benchmarks
+ SRCS
+ logf16_benchmark.cpp
+ HDRS
+ platform.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.sign
+ libc.src.math.logf16
+ COMPILE_OPTIONS
+ ${math_benchmark_flags}
+ LOADER_ARGS
+ --threads 64
+)
+
+add_benchmark(
+ sin_benchmark
+ SUITE
+ libc-gpu-math-benchmarks
+ SRCS
+ sin_benchmark.cpp
+ HDRS
+ platform.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.math.sin
+ libc.src.math.sinf
COMPILE_OPTIONS
${math_benchmark_flags}
LOADER_ARGS
diff --git a/libc/benchmarks/gpu/src/math/atan2_benchmark.cpp b/libc/benchmarks/gpu/src/math/atan2_benchmark.cpp
index 1f91a9a..6039f0c 100644
--- a/libc/benchmarks/gpu/src/math/atan2_benchmark.cpp
+++ b/libc/benchmarks/gpu/src/math/atan2_benchmark.cpp
@@ -1,27 +1,30 @@
#include "benchmarks/gpu/LibcGpuBenchmark.h"
+#include "hdr/stdint_proxy.h"
#include "src/math/atan2.h"
-#include "src/stdlib/rand.h"
#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND)
#include "platform.h"
#endif
-#define BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, N) \
- []() { \
- return LIBC_NAMESPACE::benchmarks::MathPerf<T>::run_throughput_in_range< \
- N>(Func, MIN_EXP, MAX_EXP, MIN_EXP, MAX_EXP); \
+#define BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const UniformExponent<T> dist(MinExp, MaxExp); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, dist, \
+ call_index); \
}
-#define BENCH(T, Name, Func, MIN_EXP, MAX_EXP) \
+#define BENCH(T, Name, Func, MinExp, MaxExp) \
SINGLE_WAVE_BENCHMARK(LlvmLibcAtan2GpuBenchmark, Name##_1, \
- BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 1)); \
+ BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, 1)); \
SINGLE_WAVE_BENCHMARK(LlvmLibcAtan2GpuBenchmark, Name##_128, \
- BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 128)); \
+ BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, 128)); \
SINGLE_WAVE_BENCHMARK(LlvmLibcAtan2GpuBenchmark, Name##_1024, \
- BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 1024)); \
+ BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, 1024)); \
SINGLE_WAVE_BENCHMARK(LlvmLibcAtan2GpuBenchmark, Name##_4096, \
- BM_TWO_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 4096))
+ BM_RANDOM_INPUTS(T, Func, MinExp, MaxExp, 4096))
BENCH(double, Atan2, LIBC_NAMESPACE::atan2, -1023, 1023);
BENCH(double, Atan2TwoPi, LIBC_NAMESPACE::atan2, -10, 3);
diff --git a/libc/benchmarks/gpu/src/math/exp_benchmark.cpp b/libc/benchmarks/gpu/src/math/exp_benchmark.cpp
new file mode 100644
index 0000000..2398c4b
--- /dev/null
+++ b/libc/benchmarks/gpu/src/math/exp_benchmark.cpp
@@ -0,0 +1,59 @@
+//===-- GPU benchmark for exp ---------------------------------------------===//
+//
+// 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 "benchmarks/gpu/LibcGpuBenchmark.h"
+#include "benchmarks/gpu/Random.h"
+
+#include "hdr/stdint_proxy.h"
+#include "src/math/exp.h"
+
+#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND)
+#include "platform.h"
+#endif
+
+#define RANDOM_INPUT(T, Func, Dist, Min, Max, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const Dist<T> dist(Min, Max); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
+ }
+
+#define BENCH(T, Name, Func, Dist, Min, Max) \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpGpuBenchmark, Name##_1, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 1)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpGpuBenchmark, Name##_128, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 128)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpGpuBenchmark, Name##_1024, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 1024)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpGpuBenchmark, Name##_4096, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 4096))
+
+using LIBC_NAMESPACE::exp;
+
+BENCH(double, ExpSubnormal, exp, UniformExponent, -1022, -1022);
+BENCH(double, ExpCoreRange, exp, UniformLinear, -10.0, 10.0);
+BENCH(double, ExpFinite, exp, UniformLinear, -745.0, 709.0);
+BENCH(double, ExpUnderflow, exp, UniformLinear, -746.0, -745.0);
+BENCH(double, ExpOverflow, exp, UniformLinear, 709.0, 710.0);
+
+#ifdef NVPTX_MATH_FOUND
+BENCH(double, NvExpSubnormal, __nv_exp, UniformExponent, -1022, -1022);
+BENCH(double, NvExpCoreRange, __nv_exp, UniformLinear, -10.0, 10.0);
+BENCH(double, NvExpFinite, __nv_exp, UniformLinear, -745.0, 709.0);
+BENCH(double, NvExpUnderflow, __nv_exp, UniformLinear, -746.0, -745.0);
+BENCH(double, NvExpOverflow, __nv_exp, UniformLinear, 709.0, 710.0);
+#endif
+
+#ifdef AMDGPU_MATH_FOUND
+BENCH(double, AmdExpSubnormal, __ocml_exp_f64, UniformExponent, -1022, -1022);
+BENCH(double, AmdExpCoreRange, __ocml_exp_f64, UniformLinear, -10.0, 10.0);
+BENCH(double, AmdExpFinite, __ocml_exp_f64, UniformLinear, -745.0, 709.0);
+BENCH(double, AmdExpUnderflow, __ocml_exp_f64, UniformLinear, -746.0, -745.0);
+BENCH(double, AmdExpOverflow, __ocml_exp_f64, UniformLinear, 709.0, 710.0);
+#endif
diff --git a/libc/benchmarks/gpu/src/math/expf16_benchmark.cpp b/libc/benchmarks/gpu/src/math/expf16_benchmark.cpp
new file mode 100644
index 0000000..20e045b
--- /dev/null
+++ b/libc/benchmarks/gpu/src/math/expf16_benchmark.cpp
@@ -0,0 +1,56 @@
+//===-- GPU benchmark for expf16 ------------------------------------------===//
+//
+// 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 "benchmarks/gpu/LibcGpuBenchmark.h"
+#include "benchmarks/gpu/Random.h"
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/macros/properties/types.h"
+#include "src/math/expf16.h"
+
+#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND)
+#include "platform.h"
+#endif
+
+#define RANDOM_INPUT(T, Func, Dist, Min, Max, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const Dist<T> dist(Min, Max); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
+ }
+
+#define BENCH(T, Name, Func, Dist, Min, Max) \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpf16GpuBenchmark, Name##_1, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 1)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpf16GpuBenchmark, Name##_128, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 128)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpf16GpuBenchmark, Name##_1024, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 1024)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpf16GpuBenchmark, Name##_4096, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 4096))
+
+using LIBC_NAMESPACE::expf16;
+
+BENCH(float16, Expf16Subnormal, expf16, UniformExponent, -14, -14);
+BENCH(float16, Expf16CoreRange, expf16, UniformLinear, -10.0f16, 10.0f16);
+BENCH(float16, Expf16Finite, expf16, UniformLinear, -16.0f16, 11.0f16);
+BENCH(float16, Expf16Underflow, expf16, UniformLinear, -17.0f16, -16.0f16);
+BENCH(float16, Expf16Overflow, expf16, UniformLinear, 11.0f16, 12.0f16);
+
+#ifdef AMDGPU_MATH_FOUND
+BENCH(float16, AmdExpf16Subnormal, __ocml_exp_f16, UniformExponent, -14, -14);
+BENCH(float16, AmdExpf16CoreRange, __ocml_exp_f16, UniformLinear, -10.0f16,
+ 10.0f16);
+BENCH(float16, AmdExpf16Finite, __ocml_exp_f16, UniformLinear, -16.0f16,
+ 11.0f16);
+BENCH(float16, AmdExpf16Underflow, __ocml_exp_f16, UniformLinear, -17.0f16,
+ -16.0f16);
+BENCH(float16, AmdExpf16Overflow, __ocml_exp_f16, UniformLinear, 11.0f16,
+ 12.0f16);
+#endif
diff --git a/libc/benchmarks/gpu/src/math/expf_benchmark.cpp b/libc/benchmarks/gpu/src/math/expf_benchmark.cpp
new file mode 100644
index 0000000..4ef54c5
--- /dev/null
+++ b/libc/benchmarks/gpu/src/math/expf_benchmark.cpp
@@ -0,0 +1,59 @@
+//===-- GPU benchmark for expf --------------------------------------------===//
+//
+// 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 "benchmarks/gpu/LibcGpuBenchmark.h"
+#include "benchmarks/gpu/Random.h"
+
+#include "hdr/stdint_proxy.h"
+#include "src/math/expf.h"
+
+#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND)
+#include "platform.h"
+#endif
+
+#define RANDOM_INPUT(T, Func, Dist, Min, Max, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const Dist<T> dist(Min, Max); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
+ }
+
+#define BENCH(T, Name, Func, Dist, Min, Max) \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpfGpuBenchmark, Name##_1, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 1)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpfGpuBenchmark, Name##_128, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 128)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpfGpuBenchmark, Name##_1024, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 1024)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcExpfGpuBenchmark, Name##_4096, \
+ RANDOM_INPUT(T, Func, Dist, Min, Max, 4096))
+
+using LIBC_NAMESPACE::expf;
+
+BENCH(float, ExpfSubnormal, expf, UniformExponent, -126, -126);
+BENCH(float, ExpfCoreRange, expf, UniformLinear, -10.0f, 10.0f);
+BENCH(float, ExpfFinite, expf, UniformLinear, -103.0f, 88.0f);
+BENCH(float, ExpfUnderflow, expf, UniformLinear, -104.0f, -103.0f);
+BENCH(float, ExpfOverflow, expf, UniformLinear, 88.0f, 89.0f);
+
+#ifdef NVPTX_MATH_FOUND
+BENCH(float, NvExpfSubnormal, __nv_expf, UniformExponent, -126, -126);
+BENCH(float, NvExpfCoreRange, __nv_expf, UniformLinear, -10.0f, 10.0f);
+BENCH(float, NvExpfFinite, __nv_expf, UniformLinear, -103.0f, 88.0f);
+BENCH(float, NvExpfUnderflow, __nv_expf, UniformLinear, -104.0f, -103.0f);
+BENCH(float, NvExpfOverflow, __nv_expf, UniformLinear, 88.0f, 89.0f);
+#endif
+
+#ifdef AMDGPU_MATH_FOUND
+BENCH(float, AmdExpfSubnormal, __ocml_exp_f32, UniformExponent, -126, -126);
+BENCH(float, AmdExpfCoreRange, __ocml_exp_f32, UniformLinear, -10.0f, 10.0f);
+BENCH(float, AmdExpfFinite, __ocml_exp_f32, UniformLinear, -103.0f, 88.0f);
+BENCH(float, AmdExpfUnderflow, __ocml_exp_f32, UniformLinear, -104.0f, -103.0f);
+BENCH(float, AmdExpfOverflow, __ocml_exp_f32, UniformLinear, 88.0f, 89.0f);
+#endif
diff --git a/libc/benchmarks/gpu/src/math/log_benchmark.cpp b/libc/benchmarks/gpu/src/math/log_benchmark.cpp
new file mode 100644
index 0000000..0ea1906
--- /dev/null
+++ b/libc/benchmarks/gpu/src/math/log_benchmark.cpp
@@ -0,0 +1,68 @@
+//===-- GPU benchmark for log ---------------------------------------------===//
+//
+// 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 "benchmarks/gpu/LibcGpuBenchmark.h"
+#include "benchmarks/gpu/Random.h"
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/sign.h"
+#include "src/math/log.h"
+
+#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND)
+#include "platform.h"
+#endif
+
+#define RANDOM_INPUT_UniformExponent(T, Func, Min, Max, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const UniformExponent<T> dist(Min, Max, LIBC_NAMESPACE::Sign::POS); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
+ }
+
+#define RANDOM_INPUT_UniformLinear(T, Func, Min, Max, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const UniformLinear<T> dist(Min, Max); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
+ }
+
+#define BENCH(T, Name, Func, Dist, Min, Max) \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogGpuBenchmark, Name##_1, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 1)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogGpuBenchmark, Name##_128, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 128)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogGpuBenchmark, Name##_1024, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 1024)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogGpuBenchmark, Name##_4096, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 4096))
+
+using LIBC_NAMESPACE::log;
+
+static constexpr double INV_E = 0x1.78b56362cef38p-2; // exp(-1.0)
+static constexpr double E = 0x1.5bf0a8b145769p+1; // exp(+1.0)
+
+BENCH(double, LogSubnormal, log, UniformExponent, -1022, -1022);
+BENCH(double, LogAroundOne, log, UniformLinear, INV_E, E);
+BENCH(double, LogMedMag, log, UniformExponent, -10, 10);
+BENCH(double, LogNormal, log, UniformExponent, -1021, 1023);
+
+#ifdef NVPTX_MATH_FOUND
+BENCH(double, NvLogSubnormal, __nv_log, UniformExponent, -1022, -1022);
+BENCH(double, NvLogAroundOne, __nv_log, UniformLinear, INV_E, E);
+BENCH(double, NvLogMedMag, __nv_log, UniformExponent, -10, 10);
+BENCH(double, NvLogNormal, __nv_log, UniformExponent, -1021, 1023);
+#endif
+
+#ifdef AMDGPU_MATH_FOUND
+BENCH(double, AmdLogSubnormal, __ocml_log_f64, UniformExponent, -1022, -1022);
+BENCH(double, AmdLogAroundOne, __ocml_log_f64, UniformLinear, INV_E, E);
+BENCH(double, AmdLogMedMag, __ocml_log_f64, UniformExponent, -10, 10);
+BENCH(double, AmdLogNormal, __ocml_log_f64, UniformExponent, -1021, 1023);
+#endif
diff --git a/libc/benchmarks/gpu/src/math/logf16_benchmark.cpp b/libc/benchmarks/gpu/src/math/logf16_benchmark.cpp
new file mode 100644
index 0000000..9748e15
--- /dev/null
+++ b/libc/benchmarks/gpu/src/math/logf16_benchmark.cpp
@@ -0,0 +1,62 @@
+//===-- GPU benchmark for logf16 ------------------------------------------===//
+//
+// 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 "benchmarks/gpu/LibcGpuBenchmark.h"
+#include "benchmarks/gpu/Random.h"
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/macros/properties/types.h"
+#include "src/__support/sign.h"
+#include "src/math/logf16.h"
+
+#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND)
+#include "platform.h"
+#endif
+
+#define RANDOM_INPUT_UniformExponent(T, Func, Min, Max, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const UniformExponent<T> dist(Min, Max, LIBC_NAMESPACE::Sign::POS); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
+ }
+
+#define RANDOM_INPUT_UniformLinear(T, Func, Min, Max, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const UniformLinear<T> dist(Min, Max); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
+ }
+
+#define BENCH(T, Name, Func, Dist, Min, Max) \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogf16GpuBenchmark, Name##_1, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 1)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogf16GpuBenchmark, Name##_128, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 128)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogf16GpuBenchmark, Name##_1024, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 1024)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogf16GpuBenchmark, Name##_4096, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 4096))
+
+using LIBC_NAMESPACE::logf16;
+
+static constexpr float16 INV_E = 0x1.78b56362cef38p-2f16; // exp(-1.0)
+static constexpr float16 E = 0x1.5bf0a8b145769p+1f16; // exp(+1.0)
+
+BENCH(float16, Logf16Subnormal, logf16, UniformExponent, -14, -14);
+BENCH(float16, Logf16AroundOne, logf16, UniformLinear, INV_E, E);
+BENCH(float16, Logf16MedMag, logf16, UniformExponent, -10, 10);
+BENCH(float16, Logf16Normal, logf16, UniformExponent, -13, 15);
+
+#ifdef AMDGPU_MATH_FOUND
+BENCH(float16, AmdLogf16Subnormal, __ocml_log_f16, UniformExponent, -14, -14);
+BENCH(float16, AmdLogf16AroundOne, __ocml_log_f16, UniformLinear, INV_E, E);
+BENCH(float16, AmdLogf16MedMag, __ocml_log_f16, UniformExponent, -10, 10);
+BENCH(float16, AmdLogf16Normal, __ocml_log_f16, UniformExponent, -13, 15);
+#endif
diff --git a/libc/benchmarks/gpu/src/math/logf_benchmark.cpp b/libc/benchmarks/gpu/src/math/logf_benchmark.cpp
new file mode 100644
index 0000000..c4e5a22
--- /dev/null
+++ b/libc/benchmarks/gpu/src/math/logf_benchmark.cpp
@@ -0,0 +1,68 @@
+//===-- GPU benchmark for logf --------------------------------------------===//
+//
+// 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 "benchmarks/gpu/LibcGpuBenchmark.h"
+#include "benchmarks/gpu/Random.h"
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/sign.h"
+#include "src/math/logf.h"
+
+#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND)
+#include "platform.h"
+#endif
+
+#define RANDOM_INPUT_UniformExponent(T, Func, Min, Max, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const UniformExponent<T> dist(Min, Max, LIBC_NAMESPACE::Sign::POS); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
+ }
+
+#define RANDOM_INPUT_UniformLinear(T, Func, Min, Max, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const UniformLinear<T> dist(Min, Max); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
+ }
+
+#define BENCH(T, Name, Func, Dist, Min, Max) \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogfGpuBenchmark, Name##_1, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 1)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogfGpuBenchmark, Name##_128, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 128)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogfGpuBenchmark, Name##_1024, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 1024)); \
+ SINGLE_WAVE_BENCHMARK(LlvmLibcLogfGpuBenchmark, Name##_4096, \
+ RANDOM_INPUT_##Dist(T, Func, Min, Max, 4096))
+
+using LIBC_NAMESPACE::logf;
+
+static constexpr float INV_E = 0x1.78b56362cef38p-2f; // exp(-1.0)
+static constexpr float E = 0x1.5bf0a8b145769p+1f; // exp(+1.0)
+
+BENCH(float, LogfSubnormal, logf, UniformExponent, -126, -126);
+BENCH(float, LogfAroundOne, logf, UniformLinear, INV_E, E);
+BENCH(float, LogfMedMag, logf, UniformExponent, -10, 10);
+BENCH(float, LogfNormal, logf, UniformExponent, -125, 127);
+
+#ifdef NVPTX_MATH_FOUND
+BENCH(float, NvLogfSubnormal, __nv_logf, UniformExponent, -126, -126);
+BENCH(float, NvLogfAroundOne, __nv_logf, UniformLinear, INV_E, E);
+BENCH(float, NvLogfMedMag, __nv_logf, UniformExponent, -10, 10);
+BENCH(float, NvLogfNormal, __nv_logf, UniformExponent, -125, 127);
+#endif
+
+#ifdef AMDGPU_MATH_FOUND
+BENCH(float, AmdLogfSubnormal, __ocml_log_f32, UniformExponent, -126, -126);
+BENCH(float, AmdLogfAroundOne, __ocml_log_f32, UniformLinear, INV_E, E);
+BENCH(float, AmdLogfMedMag, __ocml_log_f32, UniformExponent, -10, 10);
+BENCH(float, AmdLogfNormal, __ocml_log_f32, UniformExponent, -125, 127);
+#endif
diff --git a/libc/benchmarks/gpu/src/math/platform.h b/libc/benchmarks/gpu/src/math/platform.h
index 2dfa9f2..e675d1e 100644
--- a/libc/benchmarks/gpu/src/math/platform.h
+++ b/libc/benchmarks/gpu/src/math/platform.h
@@ -11,6 +11,7 @@
#include "hdr/stdint_proxy.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
namespace LIBC_NAMESPACE_DECL {
@@ -41,17 +42,27 @@ extern const LIBC_INLINE_VAR uint32_t __oclc_ISA_version = 9000;
// Forward declarations for the vendor math libraries.
extern "C" {
#ifdef AMDGPU_MATH_FOUND
-double __ocml_sin_f64(double);
-float __ocml_sin_f32(float);
double __ocml_atan2_f64(double, double);
float __ocml_atan2_f32(float, float);
+double __ocml_exp_f64(double);
+float __ocml_exp_f32(float);
+float16 __ocml_exp_f16(float16);
+double __ocml_log_f64(double);
+float __ocml_log_f32(float);
+float16 __ocml_log_f16(float16);
+double __ocml_sin_f64(double);
+float __ocml_sin_f32(float);
#endif
#ifdef NVPTX_MATH_FOUND
-double __nv_sin(double);
-float __nv_sinf(float);
double __nv_atan2(double, double);
float __nv_atan2f(float, float);
+double __nv_exp(double);
+float __nv_expf(float);
+double __nv_log(double);
+float __nv_logf(float);
+double __nv_sin(double);
+float __nv_sinf(float);
#endif
}
diff --git a/libc/benchmarks/gpu/src/math/sin_benchmark.cpp b/libc/benchmarks/gpu/src/math/sin_benchmark.cpp
index a759db2..5ed82c8 100644
--- a/libc/benchmarks/gpu/src/math/sin_benchmark.cpp
+++ b/libc/benchmarks/gpu/src/math/sin_benchmark.cpp
@@ -1,36 +1,31 @@
#include "benchmarks/gpu/LibcGpuBenchmark.h"
+#include "benchmarks/gpu/Random.h"
-#include "src/__support/CPP/array.h"
-#include "src/__support/CPP/bit.h"
-#include "src/__support/CPP/functional.h"
-#include "src/__support/FPUtil/FPBits.h"
+#include "hdr/stdint_proxy.h"
#include "src/math/sin.h"
#include "src/math/sinf.h"
-#include "src/stdlib/rand.h"
#if defined(NVPTX_MATH_FOUND) || defined(AMDGPU_MATH_FOUND)
#include "platform.h"
#endif
-// BENCHMARK() expects a function that with no parameters that returns a
-// uint64_t representing the latency. Defining each benchmark using macro that
-// expands to a lambda to allow us to switch the implementation of `sin()` to
-// easily register NVPTX benchmarks.
-#define BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, N) \
- []() { \
- return LIBC_NAMESPACE::benchmarks::MathPerf<T>::run_throughput_in_range< \
- N>(Func, MIN_EXP, MAX_EXP); \
+#define BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, N) \
+ [](uint32_t call_index) { \
+ using namespace LIBC_NAMESPACE::benchmarks; \
+ \
+ const UniformExponent<T> dist(MinExp, MaxExp); \
+ return MathPerf<T>::template run_throughput<N>(Func, dist, call_index); \
}
-#define BENCH(T, Name, Func, MIN_EXP, MAX_EXP) \
+#define BENCH(T, Name, Func, MinExp, MaxExp) \
SINGLE_WAVE_BENCHMARK(LlvmLibcSinGpuBenchmark, Name##_1, \
- BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 1)); \
+ BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, 1)); \
SINGLE_WAVE_BENCHMARK(LlvmLibcSinGpuBenchmark, Name##_128, \
- BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 128)); \
+ BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, 128)); \
SINGLE_WAVE_BENCHMARK(LlvmLibcSinGpuBenchmark, Name##_1024, \
- BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 1024)); \
+ BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, 1024)); \
SINGLE_WAVE_BENCHMARK(LlvmLibcSinGpuBenchmark, Name##_4096, \
- BM_RANDOM_INPUT(T, Func, MIN_EXP, MAX_EXP, 4096))
+ BM_RANDOM_INPUT(T, Func, MinExp, MaxExp, 4096))
BENCH(double, Sin, LIBC_NAMESPACE::sin, -1023, 1023);
BENCH(double, SinTwoPi, LIBC_NAMESPACE::sin, -10, 3);
diff --git a/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt b/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt
index dd7c2d3..f85152e 100644
--- a/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt
+++ b/libc/benchmarks/gpu/timing/amdgpu/CMakeLists.txt
@@ -4,9 +4,11 @@ add_header_library(
timing.h
DEPENDS
libc.hdr.stdint_proxy
- libc.src.__support.common
libc.src.__support.macros.config
libc.src.__support.macros.attributes
- libc.src.__support.CPP.type_traits
+ libc.src.__support.CPP.algorithm
libc.src.__support.CPP.array
+ libc.src.__support.CPP.atomic
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.GPU.utils
)
diff --git a/libc/benchmarks/gpu/timing/amdgpu/timing.h b/libc/benchmarks/gpu/timing/amdgpu/timing.h
index 37dbb9a..8b92584 100644
--- a/libc/benchmarks/gpu/timing/amdgpu/timing.h
+++ b/libc/benchmarks/gpu/timing/amdgpu/timing.h
@@ -10,11 +10,11 @@
#define LLVM_LIBC_UTILS_GPU_TIMING_AMDGPU
#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/GPU/utils.h"
-#include "src/__support/common.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
@@ -105,20 +105,86 @@ template <typename F, typename T1, typename T2>
return stop - start;
}
-// Provides throughput benchmarking.
-template <typename F, typename T, size_t N>
-[[gnu::noinline]] static LIBC_INLINE uint64_t
-throughput(F f, const cpp::array<T, N> &inputs) {
+// Provides the *baseline* for throughput: measures loop and measurement costs
+// without calling the f function
+template <typename T, size_t N>
+static LIBC_INLINE uint64_t
+throughput_baseline(const cpp::array<T, N> &inputs) {
asm("" ::"v"(&inputs));
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
uint64_t start = gpu::processor_clock();
+ asm("" ::"s"(start));
+
+ T result{};
+
+#pragma clang loop unroll(disable)
+ for (auto input : inputs) {
+ asm("" ::"v"(input));
+ result = input;
+ asm("" ::"v"(result));
+ }
+
+ uint64_t stop = gpu::processor_clock();
+ asm("" ::"s"(stop));
+ cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+
+ volatile auto output = result;
+ return stop - start;
+}
+
+// Provides throughput benchmarking
+template <typename F, typename T, size_t N>
+static LIBC_INLINE uint64_t throughput(F f, const cpp::array<T, N> &inputs) {
+ uint64_t baseline = UINT64_MAX;
+ for (int i = 0; i < 5; ++i)
+ baseline = cpp::min(baseline, throughput_baseline<T, N>(inputs));
+
+ asm("" ::"v"(&inputs));
+
+ cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+ uint64_t start = gpu::processor_clock();
asm("" ::"s"(start));
+ T result{};
+
+#pragma clang loop unroll(disable)
for (auto input : inputs) {
- auto result = f(input);
+ asm("" ::"v"(input));
+ result = f(input);
+ asm("" ::"v"(result));
+ }
+
+ uint64_t stop = gpu::processor_clock();
+ asm("" ::"s"(stop));
+ cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+
+ volatile auto output = result;
+
+ const uint64_t measured = stop - start;
+ return measured > baseline ? (measured - baseline) : 0;
+}
+
+// Provides the *baseline* for throughput with 2 arguments: measures loop and
+// measurement costs without calling the f function
+template <typename T, size_t N>
+static LIBC_INLINE uint64_t throughput_baseline(
+ const cpp::array<T, N> &inputs1, const cpp::array<T, N> &inputs2) {
+ asm("" ::"v"(&inputs1), "v"(&inputs2));
+
+ cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+ uint64_t start = gpu::processor_clock();
+ asm("" ::"s"(start));
+ T result{};
+
+#pragma clang loop unroll(disable)
+ for (size_t i = 0; i < N; i++) {
+ T x = inputs1[i];
+ T y = inputs2[i];
+ asm("" ::"v"(x), "v"(y));
+ result = x;
asm("" ::"v"(result));
}
@@ -126,24 +192,33 @@ throughput(F f, const cpp::array<T, N> &inputs) {
asm("" ::"s"(stop));
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
- // Return the time elapsed.
+ volatile auto output = result;
+
return stop - start;
}
// Provides throughput benchmarking for 2 arguments (e.g. atan2())
template <typename F, typename T, size_t N>
-[[gnu::noinline]] static LIBC_INLINE uint64_t throughput(
- F f, const cpp::array<T, N> &inputs1, const cpp::array<T, N> &inputs2) {
+static LIBC_INLINE uint64_t throughput(F f, const cpp::array<T, N> &inputs1,
+ const cpp::array<T, N> &inputs2) {
+ uint64_t baseline = UINT64_MAX;
+ for (int i = 0; i < 5; ++i)
+ baseline = cpp::min(baseline, throughput_baseline<T, N>(inputs1, inputs2));
+
asm("" ::"v"(&inputs1), "v"(&inputs2));
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
uint64_t start = gpu::processor_clock();
-
asm("" ::"s"(start));
- for (size_t i = 0; i < inputs1.size(); i++) {
- auto result = f(inputs1[i], inputs2[i]);
+ T result{};
+#pragma clang loop unroll(disable)
+ for (size_t i = 0; i < N; i++) {
+ T x = inputs1[i];
+ T y = inputs2[i];
+ asm("" ::"v"(x), "v"(y));
+ result = f(x, y);
asm("" ::"v"(result));
}
@@ -151,8 +226,10 @@ template <typename F, typename T, size_t N>
asm("" ::"s"(stop));
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
- // Return the time elapsed.
- return stop - start;
+ volatile auto output = result;
+
+ const uint64_t measured = stop - start;
+ return measured > baseline ? (measured - baseline) : 0;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt b/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt
index a19c16e..4615f53 100644
--- a/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt
+++ b/libc/benchmarks/gpu/timing/nvptx/CMakeLists.txt
@@ -4,9 +4,11 @@ add_header_library(
timing.h
DEPENDS
libc.hdr.stdint_proxy
- libc.src.__support.common
libc.src.__support.macros.config
libc.src.__support.macros.attributes
- libc.src.__support.CPP.type_traits
+ libc.src.__support.CPP.algorithm
libc.src.__support.CPP.array
+ libc.src.__support.CPP.atomic
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.GPU.utils
)
diff --git a/libc/benchmarks/gpu/timing/nvptx/timing.h b/libc/benchmarks/gpu/timing/nvptx/timing.h
index 3c72963..944d373 100644
--- a/libc/benchmarks/gpu/timing/nvptx/timing.h
+++ b/libc/benchmarks/gpu/timing/nvptx/timing.h
@@ -10,11 +10,10 @@
#define LLVM_LIBC_UTILS_GPU_TIMING_NVPTX
#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/atomic.h"
-#include "src/__support/CPP/type_traits.h"
#include "src/__support/GPU/utils.h"
-#include "src/__support/common.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
@@ -65,7 +64,7 @@ template <typename F, typename T>
uint64_t stop = gpu::processor_clock();
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
asm("" ::"r"(stop));
- volatile T output = result;
+ volatile auto output = result;
// Return the time elapsed.
return stop - start;
@@ -95,18 +94,51 @@ static LIBC_INLINE uint64_t latency(F f, T1 t1, T2 t2) {
return stop - start;
}
-// Provides throughput benchmarking.
-template <typename F, typename T, size_t N>
-[[gnu::noinline]] static LIBC_INLINE uint64_t
-throughput(F f, const cpp::array<T, N> &inputs) {
+// Provides the *baseline* for throughput: measures loop and measurement costs
+// without calling the f function
+template <typename T, size_t N>
+static LIBC_INLINE uint64_t
+throughput_baseline(const cpp::array<T, N> &inputs) {
asm("" ::"r"(&inputs));
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
uint64_t start = gpu::processor_clock();
+ asm("" ::"llr"(start));
+
+ T result{};
+
+#pragma clang loop unroll(disable)
+ for (auto input : inputs) {
+ asm("" ::"r"(input));
+ result = input;
+ asm("" ::"r"(result));
+ }
+ uint64_t stop = gpu::processor_clock();
+ asm("" ::"r"(stop));
+ cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+
+ volatile auto output = result;
+
+ return stop - start;
+}
+
+// Provides throughput benchmarking
+template <typename F, typename T, size_t N>
+static LIBC_INLINE uint64_t throughput(F f, const cpp::array<T, N> &inputs) {
+ uint64_t baseline = UINT64_MAX;
+ for (int i = 0; i < 5; ++i)
+ baseline = cpp::min(baseline, throughput_baseline<T, N>(inputs));
+
+ asm("" ::"r"(&inputs));
+
+ cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+ uint64_t start = gpu::processor_clock();
asm("" ::"llr"(start));
- uint64_t result;
+ T result{};
+
+#pragma clang loop unroll(disable)
for (auto input : inputs) {
asm("" ::"r"(input));
result = f(input);
@@ -114,39 +146,81 @@ throughput(F f, const cpp::array<T, N> &inputs) {
}
uint64_t stop = gpu::processor_clock();
+ asm("" ::"r"(stop));
+ cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+
+ volatile auto output = result;
+
+ const uint64_t measured = stop - start;
+ return measured > baseline ? (measured - baseline) : 0;
+}
+
+// Provides the *baseline* for throughput with 2 arguments: measures loop and
+// measurement costs without calling the f function
+template <typename T, size_t N>
+static LIBC_INLINE uint64_t throughput_baseline(
+ const cpp::array<T, N> &inputs1, const cpp::array<T, N> &inputs2) {
+ asm("" ::"r"(&inputs1), "r"(&inputs2));
+
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+ uint64_t start = gpu::processor_clock();
+ asm("" ::"llr"(start));
+
+ T result{};
+
+#pragma clang loop unroll(disable)
+ for (size_t i = 0; i < N; i++) {
+ T x = inputs1[i];
+ T y = inputs2[i];
+ asm("" ::"r"(x), "r"(y));
+ result = x;
+ asm("" ::"r"(result));
+ }
+
+ uint64_t stop = gpu::processor_clock();
asm("" ::"r"(stop));
+ cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+
volatile auto output = result;
- // Return the time elapsed.
return stop - start;
}
// Provides throughput benchmarking for 2 arguments (e.g. atan2())
template <typename F, typename T, size_t N>
-[[gnu::noinline]] static LIBC_INLINE uint64_t throughput(
- F f, const cpp::array<T, N> &inputs1, const cpp::array<T, N> &inputs2) {
+static LIBC_INLINE uint64_t throughput(F f, const cpp::array<T, N> &inputs1,
+ const cpp::array<T, N> &inputs2) {
+ uint64_t baseline = UINT64_MAX;
+ for (int i = 0; i < 5; ++i)
+ baseline = cpp::min(baseline, throughput_baseline<T, N>(inputs1, inputs2));
+
asm("" ::"r"(&inputs1), "r"(&inputs2));
cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
uint64_t start = gpu::processor_clock();
-
asm("" ::"llr"(start));
- uint64_t result;
- for (size_t i = 0; i < inputs1.size(); i++) {
- result = f(inputs1[i], inputs2[i]);
+ T result{};
+
+#pragma clang loop unroll(disable)
+ for (size_t i = 0; i < N; i++) {
+ T x = inputs1[i];
+ T y = inputs2[i];
+ asm("" ::"r"(x), "r"(y));
+ result = f(x, y);
asm("" ::"r"(result));
}
uint64_t stop = gpu::processor_clock();
- cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
asm("" ::"r"(stop));
+ cpp::atomic_thread_fence(cpp::MemoryOrder::ACQ_REL);
+
volatile auto output = result;
- // Return the time elapsed.
- return stop - start;
+ const uint64_t measured = stop - start;
+ return measured > baseline ? (measured - baseline) : 0;
}
+
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_UTILS_GPU_TIMING_NVPTX
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index d85c393..2eb0f06 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -115,11 +115,31 @@ function(_get_compile_options_from_config output_var)
set(${output_var} ${config_options} PARENT_SCOPE)
endfunction(_get_compile_options_from_config)
+function(_get_compile_options_from_arch output_var)
+ # Set options that are not found in src/__support/macros/properties/architectures.h
+ # and src/__support/macros/properties/os.h
+ # TODO: we probably want to unify these at some point for consistency
+ set(config_options "")
+
+ if (LIBC_TARGET_OS_IS_BAREMETAL)
+ list(APPEND config_options "-DLIBC_TARGET_OS_IS_BAREMETAL")
+ endif()
+ if (LIBC_TARGET_OS_IS_GPU)
+ list(APPEND config_options "-DLIBC_TARGET_OS_IS_GPU")
+ endif()
+ if (LIBC_TARGET_OS_IS_UEFI)
+ list(APPEND config_options "-DLIBC_TARGET_OS_IS_UEFI")
+ endif()
+
+ set(${output_var} ${config_options} PARENT_SCOPE)
+endfunction(_get_compile_options_from_arch)
+
function(_get_common_compile_options output_var flags)
_get_compile_options_from_flags(compile_flags ${flags})
_get_compile_options_from_config(config_flags)
+ _get_compile_options_from_arch(arch_flags)
- set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT} ${compile_flags} ${config_flags})
+ set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT} ${compile_flags} ${config_flags} ${arch_flags})
if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE)
list(APPEND compile_options "-fpie")
diff --git a/libc/cmake/modules/LLVMLibCLibraryRules.cmake b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
index b464c18..80439de 100644
--- a/libc/cmake/modules/LLVMLibCLibraryRules.cmake
+++ b/libc/cmake/modules/LLVMLibCLibraryRules.cmake
@@ -151,35 +151,6 @@ function(add_entrypoint_library target_name)
set_target_properties(${target_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR})
endfunction(add_entrypoint_library)
-# Rule to build a shared library of redirector objects.
-function(add_redirector_library target_name)
- cmake_parse_arguments(
- "REDIRECTOR_LIBRARY"
- ""
- ""
- "DEPENDS"
- ${ARGN}
- )
-
- set(obj_files "")
- foreach(dep IN LISTS REDIRECTOR_LIBRARY_DEPENDS)
- # TODO: Ensure that each dep is actually a add_redirector_object target.
- list(APPEND obj_files $<TARGET_OBJECTS:${dep}>)
- endforeach(dep)
-
- # TODO: Call the linker explicitly instead of calling the compiler driver to
- # prevent DT_NEEDED on C++ runtime.
- add_library(
- ${target_name}
- EXCLUDE_FROM_ALL
- SHARED
- ${obj_files}
- )
- set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR})
- target_link_libraries(${target_name} -nostdlib -lc -lm)
- set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE "C")
-endfunction(add_redirector_library)
-
set(HDR_LIBRARY_TARGET_TYPE "HDR_LIBRARY")
# Internal function, used by `add_header_library`.
diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake
index 805da91..6c534df 100644
--- a/libc/cmake/modules/LLVMLibCObjectRules.cmake
+++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake
@@ -1,4 +1,33 @@
set(OBJECT_LIBRARY_TARGET_TYPE "OBJECT_LIBRARY")
+set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
+set(ENTRYPOINT_EXT_TARGET_TYPE "ENTRYPOINT_EXT")
+
+# Rule to check if a list of dependencies contains any entrypoint objects. Returns a list in entrypoint_deps.
+function(check_entrypoint_deps entrypoint_deps)
+ set(PUBLIC_DEPS "")
+ set(fq_deps_list "")
+ list(APPEND fq_deps_list ${ARGN})
+
+ #don't warn for deps that are allowed, such as errno
+ set(ALLOWED_DEPS
+ "libc.src.errno.errno"
+ "libc.src.setjmp.longjmp"
+ )
+ list(REMOVE_ITEM fq_deps_list ${ALLOWED_DEPS})
+
+ foreach(dep IN LISTS fq_deps_list)
+ if(NOT TARGET ${dep})
+ continue()
+ endif()
+
+ get_target_property(target_type ${dep} "TARGET_TYPE")
+ if(${target_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})
+ list(APPEND PUBLIC_DEPS ${dep})
+ endif()
+ endforeach()
+ set(${entrypoint_deps} ${PUBLIC_DEPS} PARENT_SCOPE)
+endfunction()
+
# Rule which is essentially a wrapper over add_library to compile a set of
# sources to object files.
@@ -65,6 +94,18 @@ function(create_object_library fq_target_name)
target_include_directories(${fq_target_name} PRIVATE ${LIBC_SOURCE_DIR})
target_compile_options(${fq_target_name} PRIVATE ${compile_options})
+ #loop through the deps, check if any have the TARGET_TYPE of ENTRYPOINT_OBJ_TARGET_TYPE, and print a warning if they do.
+ if(LIBC_CMAKE_VERBOSE_LOGGING)
+ set(entrypoint_deps "")
+ if(NOT "${fq_deps_list}" STREQUAL "")
+ check_entrypoint_deps(entrypoint_deps ${fq_deps_list})
+ endif()
+ if(NOT "${entrypoint_deps}" STREQUAL "")
+ message(WARNING "Object ${fq_target_name} depends on public entrypoint(s) ${entrypoint_deps}.
+ Depending on public entrypoints is not allowed in internal code.")
+ endif()
+ endif()
+
if(SHOW_INTERMEDIATE_OBJECTS)
message(STATUS "Adding object library ${fq_target_name}")
if(${SHOW_INTERMEDIATE_OBJECTS} STREQUAL "DEPS")
@@ -110,7 +151,6 @@ function(add_object_library target_name)
${ARGN})
endfunction(add_object_library)
-set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
# A rule for entrypoint object targets.
# Usage:
@@ -179,7 +219,6 @@ function(create_entrypoint_object fq_target_name)
get_target_property(obj_type ${fq_dep_name} "TARGET_TYPE")
if((NOT obj_type) OR (NOT ${obj_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}))
-
message(FATAL_ERROR "The aliasee of an entrypoint alias should be an entrypoint.")
endif()
@@ -230,6 +269,19 @@ function(create_entrypoint_object fq_target_name)
_get_common_compile_options(common_compile_options "${ADD_ENTRYPOINT_OBJ_FLAGS}")
list(APPEND common_compile_options ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS})
get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS})
+
+ #loop through the deps, check if any have the TARGET_TYPE of entrypoint_target_type, and print a warning if they do.
+ if(LIBC_CMAKE_VERBOSE_LOGGING)
+ set(entrypoint_deps "")
+ if(NOT "${fq_deps_list}" STREQUAL "")
+ check_entrypoint_deps(entrypoint_deps ${fq_deps_list})
+ endif()
+ if(NOT "${entrypoint_deps}" STREQUAL "")
+ message(WARNING "Entrypoint ${fq_target_name} depends on public entrypoint(s) ${entrypoint_deps}.
+ Depending on public entrypoints is not allowed in internal code.")
+ endif()
+ endif()
+
set(full_deps_list ${fq_deps_list} libc.src.__support.common)
if(SHOW_INTERMEDIATE_OBJECTS)
@@ -390,8 +442,6 @@ function(add_entrypoint_object target_name)
)
endfunction(add_entrypoint_object)
-set(ENTRYPOINT_EXT_TARGET_TYPE "ENTRYPOINT_EXT")
-
# A rule for external entrypoint targets.
# Usage:
# add_entrypoint_external(
@@ -420,31 +470,6 @@ function(add_entrypoint_external target_name)
endfunction(add_entrypoint_external)
-# Rule build a redirector object file.
-function(add_redirector_object target_name)
- cmake_parse_arguments(
- "REDIRECTOR_OBJECT"
- "" # No optional arguments
- "SRC" # The cpp file in which the redirector is defined.
- "" # No multivalue arguments
- ${ARGN}
- )
- if(NOT REDIRECTOR_OBJECT_SRC)
- message(FATAL_ERROR "'add_redirector_object' rule requires SRC option listing one source file.")
- endif()
-
- add_library(
- ${target_name}
- EXCLUDE_FROM_ALL
- OBJECT
- ${REDIRECTOR_OBJECT_SRC}
- )
- target_compile_options(
- ${target_name}
- BEFORE PRIVATE -fPIC ${LIBC_COMPILE_OPTIONS_DEFAULT}
- )
-endfunction(add_redirector_object)
-
# Helper to define a function with multiple implementations
# - Computes flags to satisfy required/rejected features and arch,
# - Declares an entry point,
diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
index 267c32e..d92fdb2 100644
--- a/libc/cmake/modules/LLVMLibCTestRules.cmake
+++ b/libc/cmake/modules/LLVMLibCTestRules.cmake
@@ -1,6 +1,7 @@
function(_get_common_test_compile_options output_var c_test flags)
_get_compile_options_from_flags(compile_flags ${flags})
_get_compile_options_from_config(config_flags)
+ _get_compile_options_from_arch(arch_flags)
# Remove -fno-math-errno if it was added.
if(LIBC_ADD_FNO_MATH_ERRNO)
@@ -16,7 +17,8 @@ function(_get_common_test_compile_options output_var c_test flags)
${LIBC_COMPILE_OPTIONS_DEFAULT}
${LIBC_TEST_COMPILE_OPTIONS_DEFAULT}
${compile_flags}
- ${config_flags})
+ ${config_flags}
+ ${arch_flags})
if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE)
list(APPEND compile_options "-fpie")
@@ -836,7 +838,7 @@ function(add_libc_hermetic test_name)
${fq_deps_list})
# TODO: currently the dependency chain is broken such that getauxval cannot properly
# propagate to hermetic tests. This is a temporary workaround.
- if (LIBC_TARGET_ARCHITECTURE_IS_AARCH64)
+ if (LIBC_TARGET_ARCHITECTURE_IS_AARCH64 AND NOT(LIBC_TARGET_OS_IS_BAREMETAL))
target_link_libraries(
${fq_build_target_name}
PRIVATE
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index e24e2b9..782769e 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -757,9 +757,86 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
+if(LIBC_TYPES_HAS_FLOAT128)
+ list(APPEND TARGET_LIBM_ENTRYPOINTS
+ # math.h C++23 mixed bfloat16 and _Float128 entrypoints
+ libc.src.math.bf16addf128
+ libc.src.math.bf16divf128
+ libc.src.math.bf16fmaf128
+ libc.src.math.bf16mulf128
+ libc.src.math.bf16subf128
+ )
+endif()
+
if(LIBC_COMPILER_HAS_FIXED_POINT)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# stdfix.h _Fract and _Accum entrypoints
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 44e9c3e..f112c2b 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -760,9 +760,86 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
+if(LIBC_TYPES_HAS_FLOAT128)
+ list(APPEND TARGET_LIBM_ENTRYPOINTS
+ # math.h C++23 mixed bfloat16 and _Float128 entrypoints
+ libc.src.math.bf16addf128
+ libc.src.math.bf16divf128
+ libc.src.math.bf16fmaf128
+ libc.src.math.bf16mulf128
+ libc.src.math.bf16subf128
+ )
+endif()
+
if(LIBC_COMPILER_HAS_FIXED_POINT)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# stdfix.h _Fract and _Accum entrypoints
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 29cf322a..53e5914 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -760,9 +760,86 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
+if(LIBC_TYPES_HAS_FLOAT128)
+ list(APPEND TARGET_LIBM_ENTRYPOINTS
+ # math.h C++23 mixed bfloat16 and _Float128 entrypoints
+ libc.src.math.bf16addf128
+ libc.src.math.bf16divf128
+ libc.src.math.bf16fmaf128
+ libc.src.math.bf16mulf128
+ libc.src.math.bf16subf128
+ )
+endif()
+
if(LIBC_COMPILER_HAS_FIXED_POINT)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# stdfix.h _Fract and _Accum entrypoints
diff --git a/libc/config/config.json b/libc/config/config.json
index 1b05469..cfbe9a43 100644
--- a/libc/config/config.json
+++ b/libc/config/config.json
@@ -2,7 +2,7 @@
"errno": {
"LIBC_CONF_ERRNO_MODE": {
"value": "LIBC_ERRNO_MODE_DEFAULT",
- "doc": "The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, LIBC_ERRNO_MODE_SYSTEM, and LIBC_ERRNO_MODE_SYSTEM_INLINE."
+ "doc": "The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, and LIBC_ERRNO_MODE_SYSTEM_INLINE."
}
},
"threads": {
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 03e00a3..b4e210a 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -590,9 +590,84 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
+if(LIBC_TYPES_HAS_FLOAT128)
+ list(APPEND TARGET_LIBM_ENTRYPOINTS
+ # math.h C++23 mixed bfloat16 and _Float128 entrypoints
+ libc.src.math.bf16addf128
+ libc.src.math.bf16mulf128
+ libc.src.math.bf16subf128
+ )
+endif()
+
if(LIBC_COMPILER_HAS_FIXED_POINT)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# stdfix.h _Fract and _Accum entrypoints
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 00cedab..95392f7 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -233,7 +233,73 @@ set(TARGET_LIBM_ENTRYPOINTS
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
set(TARGET_LLVMLIBC_ENTRYPOINTS
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 291a2d0..737d1bb 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -282,6 +282,7 @@ set(TARGET_LIBM_ENTRYPOINTS
# math.h entrypoints
libc.src.math.acos
libc.src.math.acosf
+ libc.src.math.acoshf
libc.src.math.asin
libc.src.math.asinf
libc.src.math.asinhf
@@ -615,7 +616,73 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
set(TARGET_LLVMLIBC_ENTRYPOINTS
diff --git a/libc/config/gpu/amdgpu/config.json b/libc/config/gpu/config.json
index fa179b8..434ee042 100644
--- a/libc/config/gpu/amdgpu/config.json
+++ b/libc/config/gpu/config.json
@@ -39,7 +39,7 @@
},
"math": {
"LIBC_CONF_MATH_OPTIMIZATIONS": {
- "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)"
+ "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)"
}
}
}
diff --git a/libc/config/gpu/nvptx/config.json b/libc/config/gpu/nvptx/config.json
deleted file mode 100644
index fa179b8..0000000
--- a/libc/config/gpu/nvptx/config.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "errno": {
- "LIBC_CONF_ERRNO_MODE": {
- "value": "LIBC_ERRNO_MODE_SHARED"
- }
- },
- "threads": {
- "LIBC_CONF_THREAD_MODE": {
- "value": "LIBC_THREAD_MODE_SINGLE"
- }
- },
- "printf": {
- "LIBC_CONF_PRINTF_DISABLE_FLOAT": {
- "value": true
- },
- "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": {
- "value": true
- },
- "LIBC_CONF_PRINTF_DISABLE_WRITE_INT": {
- "value": true
- },
- "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
- "value": false
- },
- "LIBC_CONF_PRINTF_DISABLE_STRERROR": {
- "value": true
- },
- "LIBC_CONF_PRINTF_RUNTIME_DISPATCH": {
- "value": false
- }
- },
- "scanf": {
- "LIBC_CONF_SCANF_DISABLE_FLOAT": {
- "value": true
- },
- "LIBC_CONF_SCANF_DISABLE_INDEX_MODE": {
- "value": true
- }
- },
- "math": {
- "LIBC_CONF_MATH_OPTIMIZATIONS": {
- "value": "(LIBC_MATH_SKIP_ACCURATE_PASS | LIBC_MATH_SMALL_TABLES | LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)"
- }
- }
-}
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 55b27e6..c06d6357 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -280,6 +280,7 @@ set(TARGET_LIBC_ENTRYPOINTS
set(TARGET_LIBM_ENTRYPOINTS
# math.h entrypoints
+ libc.src.math.acos
libc.src.math.acosf
libc.src.math.acoshf
libc.src.math.asin
@@ -617,7 +618,73 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
set(TARGET_LLVMLIBC_ENTRYPOINTS
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index d76cdc2..9aeb6a7 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -660,6 +660,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# math.h C23 _Float16 entrypoints
# libc.src.math.acoshf16
+ libc.src.math.asinpif16
libc.src.math.canonicalizef16
libc.src.math.ceilf16
libc.src.math.copysignf16
@@ -844,9 +845,86 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
+if(LIBC_TYPES_HAS_FLOAT128)
+ list(APPEND TARGET_LIBM_ENTRYPOINTS
+ # math.h C++23 mixed bfloat16 and _Float128 entrypoints
+ libc.src.math.bf16addf128
+ libc.src.math.bf16divf128
+ libc.src.math.bf16fmaf128
+ libc.src.math.bf16mulf128
+ libc.src.math.bf16subf128
+ )
+endif()
+
if(LLVM_LIBC_FULL_BUILD)
list(APPEND TARGET_LIBC_ENTRYPOINTS
# assert.h entrypoints
diff --git a/libc/config/linux/arm/config.json b/libc/config/linux/arm/config.json
new file mode 100644
index 0000000..e7ad454
--- /dev/null
+++ b/libc/config/linux/arm/config.json
@@ -0,0 +1,7 @@
+{
+ "string": {
+ "LIBC_CONF_STRING_UNSAFE_WIDE_READ": {
+ "value": false
+ }
+ }
+}
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 813c34d..591c57d 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -460,7 +460,73 @@ set(TARGET_LIBM_ENTRYPOINTS
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
set(TARGET_LLVMLIBC_ENTRYPOINTS
diff --git a/libc/config/linux/config.json b/libc/config/linux/config.json
new file mode 100644
index 0000000..30e8b2c
--- /dev/null
+++ b/libc/config/linux/config.json
@@ -0,0 +1,7 @@
+{
+ "string": {
+ "LIBC_CONF_STRING_UNSAFE_WIDE_READ": {
+ "value": true
+ }
+ }
+}
diff --git a/libc/config/linux/riscv/config.json b/libc/config/linux/riscv/config.json
new file mode 100644
index 0000000..e7ad454
--- /dev/null
+++ b/libc/config/linux/riscv/config.json
@@ -0,0 +1,7 @@
+{
+ "string": {
+ "LIBC_CONF_STRING_UNSAFE_WIDE_READ": {
+ "value": false
+ }
+ }
+}
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 190aef7..b2cd5115 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -863,9 +863,86 @@ endif()
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
+if(LIBC_TYPES_HAS_FLOAT128)
+ list(APPEND TARGET_LIBM_ENTRYPOINTS
+ # math.h C++23 mixed bfloat16 and _Float128 entrypoints
+ libc.src.math.bf16addf128
+ libc.src.math.bf16divf128
+ libc.src.math.bf16fmaf128
+ libc.src.math.bf16mulf128
+ libc.src.math.bf16subf128
+ )
+endif()
+
if(LIBC_COMPILER_HAS_FIXED_POINT)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# stdfix.h _Fract and _Accum entrypoints
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index ec41069..9a73e18 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -18,6 +18,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.toupper
# dlfcn.h entrypoints
+ libc.src.dlfcn.dladdr
libc.src.dlfcn.dlclose
libc.src.dlfcn.dlerror
libc.src.dlfcn.dlopen
@@ -704,8 +705,10 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.acospif16
libc.src.math.asinf16
libc.src.math.asinhf16
+ libc.src.math.asinpif16
libc.src.math.atanf16
libc.src.math.atanhf16
+ libc.src.math.atanpif16
libc.src.math.canonicalizef16
libc.src.math.ceilf16
libc.src.math.copysignf16
@@ -893,12 +896,88 @@ if(LIBC_TYPES_HAS_FLOAT128)
)
endif()
-
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
+if(LIBC_TYPES_HAS_FLOAT128)
+ list(APPEND TARGET_LIBM_ENTRYPOINTS
+ # math.h C++23 mixed bfloat16 and _Float128 entrypoints
+ libc.src.math.bf16addf128
+ libc.src.math.bf16divf128
+ libc.src.math.bf16fmaf128
+ libc.src.math.bf16mulf128
+ libc.src.math.bf16subf128
+ )
+endif()
+
if(LIBC_COMPILER_HAS_FIXED_POINT)
list(APPEND TARGET_LIBM_ENTRYPOINTS
# stdfix.h _Fract and _Accum entrypoints
diff --git a/libc/config/windows/README.md b/libc/config/windows/README.md
index 3ac058e..ee5d5fb 100644
--- a/libc/config/windows/README.md
+++ b/libc/config/windows/README.md
@@ -59,7 +59,7 @@ libc, and finally, build and test the libc.
by Clang, so ensure Clang is specified as the C and C++ compiler.
```
- cmake -G Ninja ../llvm-project/llvm -DCMAKE_C_COMPILER=C:/src/clang-build/bin/clang-cl.exe -DCMAKE_CXX_COMPILER=C:/src/clang-build/bin/clang-cl.exe -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_FORCE_BUILD_RUNTIME=libc -DLLVM_ENABLE_PROJECTS=libc -DLLVM_NATIVE_ARCH=x86_64 -DLLVM_HOST_TRIPLE=x86_64-window-x86-gnu
+ cmake -G Ninja ../llvm-project/runtimes -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=C:/src/clang-build/bin/clang-cl.exe -DCMAKE_CXX_COMPILER=C:/src/clang-build/bin/clang-cl.exe -DLLVM_ENABLE_RUNTIMES=libc
```
Some LLVM libc math unittests test correctness/accuracy against results from
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 3160d57..2da48c3 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -306,7 +306,73 @@ set(TARGET_LIBM_ENTRYPOINTS
list(APPEND TARGET_LIBM_ENTRYPOINTS
# bfloat16 entrypoints
+ libc.src.math.bf16add
+ libc.src.math.bf16addf
+ libc.src.math.bf16addl
+ libc.src.math.bf16div
+ libc.src.math.bf16divf
+ libc.src.math.bf16divl
+ libc.src.math.bf16fma
+ libc.src.math.bf16fmaf
+ libc.src.math.bf16fmal
+ libc.src.math.bf16mul
+ libc.src.math.bf16mulf
+ libc.src.math.bf16mull
+ libc.src.math.bf16sub
+ libc.src.math.bf16subf
+ libc.src.math.bf16subl
+ libc.src.math.canonicalizebf16
+ libc.src.math.ceilbf16
+ libc.src.math.copysignbf16
libc.src.math.fabsbf16
+ libc.src.math.fdimbf16
+ libc.src.math.floorbf16
+ libc.src.math.fmaxbf16
+ libc.src.math.fmaximumbf16
+ libc.src.math.fmaximum_magbf16
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.math.fmaximum_numbf16
+ libc.src.math.fminbf16
+ libc.src.math.fminimumbf16
+ libc.src.math.fminimum_magbf16
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.math.fminimum_numbf16
+ libc.src.math.fmodbf16
+ libc.src.math.frexpbf16
+ libc.src.math.fromfpbf16
+ libc.src.math.fromfpxbf16
+ libc.src.math.getpayloadbf16
+ libc.src.math.ilogbbf16
+ libc.src.math.iscanonicalbf16
+ libc.src.math.issignalingbf16
+ libc.src.math.ldexpbf16
+ libc.src.math.llogbbf16
+ libc.src.math.llrintbf16
+ libc.src.math.llroundbf16
+ libc.src.math.logbbf16
+ libc.src.math.lrintbf16
+ libc.src.math.lroundbf16
+ libc.src.math.modfbf16
+ libc.src.math.nanbf16
+ libc.src.math.nearbyintbf16
+ libc.src.math.nextafterbf16
+ libc.src.math.nextdownbf16
+ libc.src.math.nexttowardbf16
+ libc.src.math.nextupbf16
+ libc.src.math.remainderbf16
+ libc.src.math.remquobf16
+ libc.src.math.rintbf16
+ libc.src.math.roundbf16
+ libc.src.math.roundevenbf16
+ libc.src.math.scalblnbf16
+ libc.src.math.scalbnbf16
+ libc.src.math.setpayloadbf16
+ libc.src.math.setpayloadsigbf16
+ libc.src.math.truncbf16
+ libc.src.math.totalorderbf16
+ libc.src.math.totalordermagbf16
+ libc.src.math.ufromfpbf16
+ libc.src.math.ufromfpxbf16
)
set(TARGET_LLVMLIBC_ENTRYPOINTS
diff --git a/libc/docs/configure.rst b/libc/docs/configure.rst
index 95c51b8..e23fc82 100644
--- a/libc/docs/configure.rst
+++ b/libc/docs/configure.rst
@@ -29,7 +29,7 @@ to learn about the defaults for your platform and target.
- ``LIBC_CONF_ENABLE_STRONG_STACK_PROTECTOR``: Enable -fstack-protector-strong to defend against stack smashing attack.
- ``LIBC_CONF_KEEP_FRAME_POINTER``: Keep frame pointer in functions for better debugging experience.
* **"errno" options**
- - ``LIBC_CONF_ERRNO_MODE``: The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, LIBC_ERRNO_MODE_SYSTEM, and LIBC_ERRNO_MODE_SYSTEM_INLINE.
+ - ``LIBC_CONF_ERRNO_MODE``: The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, and LIBC_ERRNO_MODE_SYSTEM_INLINE.
* **"general" options**
- ``LIBC_ADD_NULL_CHECKS``: Add nullptr checks in the library's implementations to some functions for which passing nullptr is undefined behavior.
* **"math" options**
diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst
index 9679c4a..b42216d 100644
--- a/libc/docs/headers/math/index.rst
+++ b/libc/docs/headers/math/index.rst
@@ -104,144 +104,153 @@ Implementation Status
Basic Operations
================
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| <Func> | <Func_f> (float) | <Func> (double) | <Func_l> (long double) | <Func_f16> (float16) | <Func_f128> (float128) | C23 Definition Section | C23 Error Handling Section |
-+==================+==================+=================+========================+======================+========================+========================+============================+
-| ceil | |check| | |check| | |check| | |check| | |check| | 7.12.9.1 | F.10.6.1 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| canonicalize | |check| | |check| | |check| | |check| | |check| | 7.12.11.7 | F.10.8.7 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| copysign | |check| | |check| | |check| | |check| | |check| | 7.12.11.1 | F.10.8.1 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| dadd | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.1 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| ddiv | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.4 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| dfma | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.5 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| dmul | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.3 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| dsub | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.2 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| f16add | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.1 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| f16div | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.4 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| f16fma | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.5 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| f16mul | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.5 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| f16sub | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.2 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fabs | |check| | |check| | |check| | |check| | |check| | 7.12.7.3 | F.10.4.3 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fadd | N/A | |check| | |check| | N/A | |check| | 7.12.14.1 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fdim | |check| | |check| | |check| | |check| | |check| | 7.12.12.1 | F.10.9.1 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fdiv | N/A | |check| | |check| | N/A | |check|\* | 7.12.14.4 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| ffma | N/A | |check| | |check| | N/A | |check|\* | 7.12.14.5 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| floor | |check| | |check| | |check| | |check| | |check| | 7.12.9.2 | F.10.6.2 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fmax | |check| | |check| | |check| | |check| | |check| | 7.12.12.2 | F.10.9.2 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fmaximum | |check| | |check| | |check| | |check| | |check| | 7.12.12.4 | F.10.9.4 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fmaximum_mag | |check| | |check| | |check| | |check| | |check| | 7.12.12.6 | F.10.9.4 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fmaximum_mag_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.10 | F.10.9.5 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fmaximum_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.8 | F.10.9.5 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fmin | |check| | |check| | |check| | |check| | |check| | 7.12.12.3 | F.10.9.3 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fminimum | |check| | |check| | |check| | |check| | |check| | 7.12.12.5 | F.10.9.4 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fminimum_mag | |check| | |check| | |check| | |check| | |check| | 7.12.12.7 | F.10.9.4 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fminimum_mag_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.11 | F.10.9.5 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fminimum_num | |check| | |check| | |check| | |check| | |check| | 7.12.12.9 | F.10.9.5 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fmod | |check| | |check| | |check| | |check| | |check| | 7.12.10.1 | F.10.7.1 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fmul | N/A | |check| | |check| | N/A | |check|\* | 7.12.14.3 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| frexp | |check| | |check| | |check| | |check| | |check| | 7.12.6.7 | F.10.3.7 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fromfp | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fromfpx | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| fsub | N/A | |check| | |check| | N/A | |check|\* | 7.12.14.2 | F.10.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| getpayload | |check| | |check| | |check| | |check| | |check| | F.10.13.1 | N/A |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| ilogb | |check| | |check| | |check| | |check| | |check| | 7.12.6.8 | F.10.3.8 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| iscanonical | |check| | |check| | |check| | |check| | |check| | 7.12.3.2 | N/A |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| issignaling | |check| | |check| | |check| | |check| | |check| | 7.12.3.8 | N/A |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| ldexp | |check| | |check| | |check| | |check| | |check| | 7.12.6.9 | F.10.3.9 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| llogb | |check| | |check| | |check| | |check| | |check| | 7.12.6.10 | F.10.3.10 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| llrint | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| llround | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| logb | |check| | |check| | |check| | |check| | |check| | 7.12.6.17 | F.10.3.17 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| lrint | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| lround | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| modf | |check| | |check| | |check| | |check| | |check| | 7.12.6.18 | F.10.3.18 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| nan | |check| | |check| | |check| | |check| | |check| | 7.12.11.2 | F.10.8.2 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| nearbyint | |check| | |check| | |check| | |check| | |check| | 7.12.9.3 | F.10.6.3 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| nextafter | |check| | |check| | |check| | |check| | |check| | 7.12.11.3 | F.10.8.3 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| nextdown | |check| | |check| | |check| | |check| | |check| | 7.12.11.6 | F.10.8.6 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| nexttoward | |check| | |check| | |check| | |check| | N/A | 7.12.11.4 | F.10.8.4 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| nextup | |check| | |check| | |check| | |check| | |check| | 7.12.11.5 | F.10.8.5 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| remainder | |check| | |check| | |check| | |check| | |check| | 7.12.10.2 | F.10.7.2 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| remquo | |check| | |check| | |check| | |check| | |check| | 7.12.10.3 | F.10.7.3 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| rint | |check| | |check| | |check| | |check| | |check| | 7.12.9.4 | F.10.6.4 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| round | |check| | |check| | |check| | |check| | |check| | 7.12.9.6 | F.10.6.6 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| roundeven | |check| | |check| | |check| | |check| | |check| | 7.12.9.8 | F.10.6.8 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| scalbln | |check| | |check| | |check| | |check| | |check| | 7.12.6.19 | F.10.3.19 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| scalbn | |check| | |check| | |check| | |check| | |check| | 7.12.6.19 | F.10.3.19 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| setpayload | |check| | |check| | |check| | |check| | |check| | F.10.13.2 | N/A |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| setpayloadsig | |check| | |check| | |check| | |check| | |check| | F.10.13.3 | N/A |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| totalorder | |check| | |check| | |check| | |check| | |check| | F.10.12.1 | N/A |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| totalordermag | |check| | |check| | |check| | |check| | |check| | F.10.12.2 | N/A |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| trunc | |check| | |check| | |check| | |check| | |check| | 7.12.9.9 | F.10.6.9 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| ufromfp | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| ufromfpx | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 |
-+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| <Func> | <Func_f> (float) | <Func> (double) | <Func_l> (long double) | <Func_f16> (float16) | <Func_f128> (float128) | <Func_bf16> (bfloat16) | C23 Definition Section | C23 Error Handling Section |
++==================+==================+=================+========================+======================+========================+========================+========================+============================+
+| ceil | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.1 | F.10.6.1 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| canonicalize | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.7 | F.10.8.7 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| copysign | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.1 | F.10.8.1 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| dadd | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.1 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| ddiv | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.4 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| dfma | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.5 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| dmul | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.3 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| dsub | N/A | N/A | |check| | N/A | |check|\* | N/A | 7.12.14.2 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| f16add | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.1 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| f16div | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.4 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| f16fma | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.5 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| f16mul | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.3 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| f16sub | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.2 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| bf16add | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.1 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| bf16div | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.4 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| bf16fma | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.5 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| bf16mul | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.3 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| bf16sub | |check|\* | |check|\* | |check|\* | N/A | |check| | N/A | 7.12.14.2 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fabs | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.7.3 | F.10.4.3 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fadd | N/A | |check| | |check| | N/A | |check| | N/A | 7.12.14.1 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fdim | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.1 | F.10.9.1 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fdiv | N/A | |check| | |check| | N/A | |check|\* | N/A | 7.12.14.4 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| ffma | N/A | |check| | |check| | N/A | |check|\* | N/A | 7.12.14.5 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| floor | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.2 | F.10.6.2 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fmax | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.2 | F.10.9.2 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fmaximum | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.4 | F.10.9.4 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fmaximum_mag | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.6 | F.10.9.4 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fmaximum_mag_num | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.10 | F.10.9.5 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fmaximum_num | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.8 | F.10.9.5 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fmin | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.3 | F.10.9.3 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fminimum | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.5 | F.10.9.4 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fminimum_mag | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.7 | F.10.9.4 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fminimum_mag_num | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.11 | F.10.9.5 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fminimum_num | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.12.9 | F.10.9.5 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fmod | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.10.1 | F.10.7.1 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fmul | N/A | |check| | |check| | N/A | |check|\* | N/A | 7.12.14.3 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| frexp | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.7 | F.10.3.7 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fromfp | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fromfpx | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| fsub | N/A | |check| | |check| | N/A | |check|\* | N/A | 7.12.14.2 | F.10.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| getpayload | |check| | |check| | |check| | |check| | |check| | |check| | F.10.13.1 | N/A |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| ilogb | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.8 | F.10.3.8 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| iscanonical | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.3.2 | N/A |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| issignaling | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.3.8 | N/A |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| ldexp | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.9 | F.10.3.9 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| llogb | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.10 | F.10.3.10 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| llrint | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| llround | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| logb | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.17 | F.10.3.17 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| lrint | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.5 | F.10.6.5 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| lround | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.7 | F.10.6.7 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| modf | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.18 | F.10.3.18 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| nan | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.2 | F.10.8.2 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| nearbyint | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.3 | F.10.6.3 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| nextafter | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.3 | F.10.8.3 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| nextdown | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.6 | F.10.8.6 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| nexttoward | |check| | |check| | |check| | |check| | N/A | |check| | 7.12.11.4 | F.10.8.4 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| nextup | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.11.5 | F.10.8.5 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| remainder | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.10.2 | F.10.7.2 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| remquo | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.10.3 | F.10.7.3 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| rint | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.4 | F.10.6.4 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| round | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.6 | F.10.6.6 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| roundeven | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.8 | F.10.6.8 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| scalbln | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.19 | F.10.3.19 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| scalbn | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.6.19 | F.10.3.19 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| setpayload | |check| | |check| | |check| | |check| | |check| | |check| | F.10.13.2 | N/A |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| setpayloadsig | |check| | |check| | |check| | |check| | |check| | |check| | F.10.13.3 | N/A |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| totalorder | |check| | |check| | |check| | |check| | |check| | |check| | F.10.12.1 | N/A |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| totalordermag | |check| | |check| | |check| | |check| | |check| | |check| | F.10.12.2 | N/A |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| trunc | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.9 | F.10.6.9 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| ufromfp | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.10 | F.10.6.10 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
+| ufromfpx | |check| | |check| | |check| | |check| | |check| | |check| | 7.12.9.11 | F.10.6.11 |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
Higher Math Functions
=====================
@@ -259,7 +268,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| asinh | |check| | | | |check| | | 7.12.5.2 | F.10.2.2 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| asinpi | | | | | | 7.12.4.9 | F.10.1.9 |
+| asinpi | | | | |check| | | 7.12.4.9 | F.10.1.9 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| atan | |check| | 1 ULP | | |check| | | 7.12.4.3 | F.10.1.3 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
@@ -269,7 +278,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| atanh | |check| | | | |check| | | 7.12.5.3 | F.10.2.3 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| atanpi | | | | | | 7.12.4.10 | F.10.1.10 |
+| atanpi | | | | |check| | | 7.12.4.10 | F.10.1.10 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| cbrt | |check| | |check| | | | | 7.12.7.1 | F.10.4.1 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
@@ -456,3 +465,5 @@ References
* `The CORE-MATH Project <https://core-math.gitlabpages.inria.fr/>`_.
* `The GNU C Library (glibc) <https://www.gnu.org/software/libc/>`_.
* `The GNU MPFR Library <https://www.mpfr.org/>`_.
+* `C++23 Standard <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4950.pdf>`_.
+* `BFloat16 <https://en.wikipedia.org/wiki/Bfloat16_floating-point_format>`_. \ No newline at end of file
diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index 02fe1ad..21971a4 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -461,3 +461,12 @@ add_proxy_header_library(
libc.include.llvm-libc-types.struct_sched_param
libc.include.sched
)
+
+add_proxy_header_library(
+ dl_info
+ HDRS
+ dl_info.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.dl_info
+ libc.include.dlfcn
+)
diff --git a/libc/hdr/types/dl_info.h b/libc/hdr/types/dl_info.h
new file mode 100644
index 0000000..c742831
--- /dev/null
+++ b/libc/hdr/types/dl_info.h
@@ -0,0 +1,21 @@
+//===-- Proxy for struct timespec ----------------------------------------===//
+//
+// 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_TYPES_DLINFO_H
+#define LLVM_LIBC_HDR_TYPES_DLINFO_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/Dl_info.h"
+
+#else
+
+#include <dlfcn.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_TIMESPEC_H
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 74fcea0..8fd37b0 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -70,6 +70,7 @@ add_header_macro(
dlfcn.h
DEPENDS
.llvm_libc_common_h
+ .llvm-libc-types.dl_info
)
add_header_macro(
diff --git a/libc/include/__llvm-libc-common.h b/libc/include/__llvm-libc-common.h
index c6fd33a..1fe3f4d 100644
--- a/libc/include/__llvm-libc-common.h
+++ b/libc/include/__llvm-libc-common.h
@@ -47,6 +47,13 @@
#define __NOEXCEPT throw()
#endif
+#undef _Returns_twice
+#if __cplusplus >= 201103L
+#define _Returns_twice [[gnu::returns_twice]]
+#else
+#define _Returns_twice __attribute__((returns_twice))
+#endif
+
// This macro serves as a generic cast implementation for use in both C and C++,
// similar to `__BIONIC_CAST` in Android.
#undef __LLVM_LIBC_CAST
diff --git a/libc/include/dlfcn.yaml b/libc/include/dlfcn.yaml
index 28be34d..bf17a11 100644
--- a/libc/include/dlfcn.yaml
+++ b/libc/include/dlfcn.yaml
@@ -29,6 +29,65 @@ macros:
standards:
- gnu
macro_value: "0x01000"
+ - macro_name: RTLD_NEXT
+ standards:
+ - gnu
+ macro_value: "((void *) -1l)"
+ - macro_name: RTLD_DEFAULT
+ standards:
+ - gnu
+ macro_value: "((void *) 0)"
+enums:
+ - name: RTLD_DI_LMID
+ standards:
+ - gnu
+ value: 1
+ - name: RTLD_DI_LINKMAP
+ standards:
+ - gnu
+ value: 2
+ - name: RTLD_DI_CONFIGADDR
+ standards:
+ - gnu
+ value: 3
+ - name: RTLD_DI_SERINFO
+ standards:
+ - gnu
+ value: 4
+ - name: RTLD_DI_SERINFOSIZE
+ standards:
+ - gnu
+ value: 5
+ - name: RTLD_DI_ORIGIN
+ standards:
+ - gnu
+ value: 6
+ - name: RTLD_DI_PROFILENAME
+ standards:
+ - gnu
+ value: 7
+ - name: RTLD_DI_PROFILEOUT
+ standards:
+ - gnu
+ value: 8
+ - name: RTLD_DI_TLS_MODID
+ standards:
+ - gnu
+ value: 9
+ - name: RTLD_DI_TLS_DATA
+ standards:
+ - gnu
+ value: 10
+ - name: RTLD_DI_PHDR
+ standards:
+ - gnu
+ value: 11
+ - name: RTLD_DI_MAX
+ standards:
+ - gnu
+ value: 11
+types:
+ - type_name: Dl_info
functions:
- name: dlclose
standards:
@@ -55,3 +114,18 @@ functions:
arguments:
- type: void *__restrict
- type: const char *__restrict
+ - name: dlinfo
+ standards:
+ - gnu
+ return_type: int
+ arguments:
+ - type: void *__restrict
+ - type: int
+ - type: void *__restrict
+ - name: dladdr
+ standards:
+ - POSIX
+ return_type: int
+ arguments:
+ - type: const void *__restrict
+ - type: Dl_info *__restrict
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 451beae..fe9e4e3 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -72,6 +72,7 @@ add_header(stack_t HDR stack_t.h DEPENDS .size_t)
add_header(suseconds_t HDR suseconds_t.h)
add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t)
add_header(struct_dl_phdr_info HDR struct_dl_phdr_info.h DEPENDS .size_t libc.include.llvm-libc-macros.link_macros)
+add_header(dl_info HDR Dl_info.h)
add_header(struct_f_owner_ex HDR struct_f_owner_ex.h DEPENDS .pid_t)
add_header(struct_flock HDR struct_flock.h DEPENDS .off_t .pid_t)
add_header(struct_flock64 HDR struct_flock64.h DEPENDS .off64_t .pid_t)
diff --git a/libc/include/llvm-libc-types/Dl_info.h b/libc/include/llvm-libc-types/Dl_info.h
new file mode 100644
index 0000000..b082e30
--- /dev/null
+++ b/libc/include/llvm-libc-types/Dl_info.h
@@ -0,0 +1,19 @@
+//===-- Definition of Dl_info type ----------------------------------------===//
+//
+// 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_DL_INFO_H
+#define LLVM_LIBC_TYPES_DL_INFO_H
+
+typedef struct {
+ const char *dli_fname;
+ void *dli_fbase;
+ const char *dli_sname;
+ void *dli_saddr;
+} Dl_info;
+
+#endif // LLVM_LIBC_TYPES_DL_INFO_H
diff --git a/libc/include/math.yaml b/libc/include/math.yaml
index e8ac7ee..17f26fc 100644
--- a/libc/include/math.yaml
+++ b/libc/include/math.yaml
@@ -79,6 +79,13 @@ functions:
arguments:
- type: _Float16
guard: LIBC_TYPES_HAS_FLOAT16
+ - name: asinpif16
+ standards:
+ - stdc
+ return_type: _Float16
+ arguments:
+ - type: _Float16
+ guard: LIBC_TYPES_HAS_FLOAT16
- name: atan
standards:
- stdc
@@ -134,6 +141,13 @@ functions:
arguments:
- type: float
- name: atanhf16
+ standatds:
+ - stdc
+ return_type: _Float16
+ arguments:
+ - type: _Float16
+ guard: LIBC_TYPES_HAS_FLOAT16
+ - name: atanpif16
standards:
- stdc
return_type: _Float16
@@ -303,10 +317,33 @@ functions:
arguments:
- type: _Float16
guard: LIBC_TYPES_HAS_FLOAT16
+ - name: daddf128
+ standards:
+ - llvm_libc_ext
+ return_type: double
+ arguments:
+ - type: float128
+ - type: float128
+ guard: LIBC_TYPES_HAS_FLOAT128
+ - name: daddl
+ standards:
+ - stdc
+ return_type: double
+ arguments:
+ - type: long double
+ - type: long double
+ - name: ddivf128
+ standards:
+ - llvm_libc_ext
+ return_type: double
+ arguments:
+ - type: float128
+ - type: float128
+ guard: LIBC_TYPES_HAS_FLOAT128
- name: ddivl
standards:
- stdc
- return_type: long double
+ return_type: double
arguments:
- type: long double
- type: long double
@@ -325,13 +362,20 @@ functions:
arguments:
- type: long double
- type: long double
+ - name: dsqrtf128
+ standards:
+ - llvm_libc_ext
+ return_type: double
+ arguments:
+ - type: float128
+ guard: LIBC_TYPES_HAS_FLOAT128
- name: dsqrtl
standards:
- stdc
return_type: double
arguments:
- type: long double
- - name: dsqrtf128
+ - name: dsubf128
standards:
- llvm_libc_ext
return_type: double
@@ -339,6 +383,13 @@ functions:
- type: float128
- type: float128
guard: LIBC_TYPES_HAS_FLOAT128
+ - name: dsubl
+ standards:
+ - stdc
+ return_type: double
+ arguments:
+ - type: long double
+ - type: long double
- name: erff
standards:
- stdc
@@ -363,6 +414,13 @@ functions:
return_type: float
arguments:
- type: float
+ - name: exp10f16
+ standards:
+ - stdc
+ return_type: _Float16
+ arguments:
+ - type: _Float16
+ guard: LIBC_TYPES_HAS_FLOAT16
- name: exp10m1f
standards:
- stdc
@@ -388,6 +446,13 @@ functions:
return_type: float
arguments:
- type: float
+ - name: exp2f16
+ standards:
+ - stdc
+ return_type: _Float16
+ arguments:
+ - type: _Float16
+ guard: LIBC_TYPES_HAS_FLOAT16
- name: exp2m1f
standards:
- stdc
@@ -407,6 +472,13 @@ functions:
return_type: float
arguments:
- type: float
+ - name: expf16
+ standards:
+ - stdc
+ return_type: _Float16
+ arguments:
+ - type: _Float16
+ guard: LIBC_TYPES_HAS_FLOAT16
- name: expm1
standards:
- stdc
@@ -419,6 +491,13 @@ functions:
return_type: float
arguments:
- type: float
+ - name: expm1f16
+ standards:
+ - stdc
+ return_type: _Float16
+ arguments:
+ - type: _Float16
+ guard: LIBC_TYPES_HAS_FLOAT16
- name: f16add
standards:
- llvm_libc_ext
@@ -1132,6 +1211,13 @@ functions:
- type: _Float16
- type: _Float16
guard: LIBC_TYPES_HAS_FLOAT16
+ - name: fminimum_numl
+ standards:
+ - stdc
+ return_type: long double
+ arguments:
+ - type: long double
+ - type: long double
- name: fminimumf
standards:
- stdc
@@ -2425,14 +2511,6 @@ functions:
return_type: double
arguments:
- type: double
- - name: sincosf
- standards:
- - gnu
- return_type: void
- arguments:
- - type: float
- - type: float *
- - type: float *
- name: sinf
standards:
- stdc
@@ -2446,6 +2524,22 @@ functions:
arguments:
- type: _Float16
guard: LIBC_TYPES_HAS_FLOAT16
+ - name: sincos
+ standards:
+ - gnu
+ return_type: void
+ arguments:
+ - type: double
+ - type: double *
+ - type: double *
+ - name: sincosf
+ standards:
+ - gnu
+ return_type: void
+ arguments:
+ - type: float
+ - type: float *
+ - type: float *
- name: sinhf
standards:
- stdc
diff --git a/libc/include/sched.yaml b/libc/include/sched.yaml
index f14799d..8014aa7 100644
--- a/libc/include/sched.yaml
+++ b/libc/include/sched.yaml
@@ -20,7 +20,7 @@ functions:
- type: const cpu_set_t *
- name: getcpu
standards:
- - POSIX
+ - Linux
return_type: int
arguments:
- type: unsigned int *
diff --git a/libc/include/sys/ioctl.yaml b/libc/include/sys/ioctl.yaml
index 5f7b7f3..7eb66b6 100644
--- a/libc/include/sys/ioctl.yaml
+++ b/libc/include/sys/ioctl.yaml
@@ -5,4 +5,12 @@ macros: []
types: []
enums: []
objects: []
-functions: []
+functions:
+ - name: ioctl
+ standards:
+ - Linux
+ return_type: int
+ arguments:
+ - type: int
+ - type: unsigned long
+ - type: '...'
diff --git a/libc/shared/math.h b/libc/shared/math.h
index 3714f38..69d785b 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -31,6 +31,14 @@
#include "math/atanhf.h"
#include "math/atanhf16.h"
#include "math/cbrt.h"
+#include "math/cbrtf.h"
+#include "math/cos.h"
+#include "math/cosf.h"
+#include "math/cosf16.h"
+#include "math/coshf.h"
+#include "math/coshf16.h"
+#include "math/cospif.h"
+#include "math/cospif16.h"
#include "math/erff.h"
#include "math/exp.h"
#include "math/exp10.h"
diff --git a/libc/shared/math/cbrtf.h b/libc/shared/math/cbrtf.h
new file mode 100644
index 0000000..09b86be
--- /dev/null
+++ b/libc/shared/math/cbrtf.h
@@ -0,0 +1,23 @@
+//===-- Shared cbrtf 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 LIBC_SHARED_MATH_CBRTF_H
+#define LIBC_SHARED_MATH_CBRTF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/cbrtf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::cbrtf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_SHARED_MATH_CBRTF_H
diff --git a/libc/shared/math/cos.h b/libc/shared/math/cos.h
new file mode 100644
index 0000000..c498550
--- /dev/null
+++ b/libc/shared/math/cos.h
@@ -0,0 +1,23 @@
+//===-- Shared cos 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_COS_H
+#define LLVM_LIBC_SHARED_MATH_COS_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/cos.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::cos;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_COS_H
diff --git a/libc/shared/math/cosf.h b/libc/shared/math/cosf.h
new file mode 100644
index 0000000..0618220
--- /dev/null
+++ b/libc/shared/math/cosf.h
@@ -0,0 +1,23 @@
+//===-- Shared cosf 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_COSF_H
+#define LLVM_LIBC_SHARED_MATH_COSF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/cosf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::cosf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_COSF_H
diff --git a/libc/shared/math/cosf16.h b/libc/shared/math/cosf16.h
new file mode 100644
index 0000000..8a19285
--- /dev/null
+++ b/libc/shared/math/cosf16.h
@@ -0,0 +1,28 @@
+//===-- Shared cosf16 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_COSF16_H
+#define LLVM_LIBC_SHARED_MATH_COSF16_H
+
+#include "shared/libc_common.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "src/__support/math/cosf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::cosf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_MATH_COSF16_H
diff --git a/libc/shared/math/coshf.h b/libc/shared/math/coshf.h
new file mode 100644
index 0000000..33c2580
--- /dev/null
+++ b/libc/shared/math/coshf.h
@@ -0,0 +1,23 @@
+//===-- Shared coshf 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_COSHF_H
+#define LLVM_LIBC_SHARED_MATH_COSHF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/coshf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::coshf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_COSHF_H
diff --git a/libc/shared/math/coshf16.h b/libc/shared/math/coshf16.h
new file mode 100644
index 0000000..66e8d14
--- /dev/null
+++ b/libc/shared/math/coshf16.h
@@ -0,0 +1,28 @@
+//===-- Shared coshf16 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_COSHF16_H
+#define LLVM_LIBC_SHARED_MATH_COSHF16_H
+
+#include "shared/libc_common.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "src/__support/math/coshf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::coshf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_MATH_COSHF16_H
diff --git a/libc/shared/math/cospif.h b/libc/shared/math/cospif.h
new file mode 100644
index 0000000..ce664e9
--- /dev/null
+++ b/libc/shared/math/cospif.h
@@ -0,0 +1,23 @@
+//===-- Shared cospif 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_COSPIF_H
+#define LLVM_LIBC_SHARED_MATH_COSPIF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/cospif.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::cospif;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_COSPIF_H
diff --git a/libc/shared/math/cospif16.h b/libc/shared/math/cospif16.h
new file mode 100644
index 0000000..a1680b0
--- /dev/null
+++ b/libc/shared/math/cospif16.h
@@ -0,0 +1,28 @@
+//===-- Shared cospif16 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_COSPIF16_H
+#define LLVM_LIBC_SHARED_MATH_COSPIF16_H
+
+#include "shared/libc_common.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "src/__support/math/cospif16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::cospif16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_MATH_COSPIF_H
diff --git a/libc/shared/rpc.h b/libc/shared/rpc.h
index 7295efd..dac2a79 100644
--- a/libc/shared/rpc.h
+++ b/libc/shared/rpc.h
@@ -551,6 +551,9 @@ template <uint32_t opcode> RPC_ATTRS Client::Port Client::open() {
/// port if it has a pending receive operation
RPC_ATTRS rpc::optional<typename Server::Port>
Server::try_open(uint32_t lane_size, uint32_t start) {
+ if (rpc::get_lane_id() >= lane_size)
+ return rpc::nullopt;
+
// Perform a naive linear scan for a port that has a pending request.
for (uint32_t index = start; index < process.port_count; ++index) {
uint64_t lane_mask = rpc::get_lane_mask();
diff --git a/libc/src/__support/CPP/CMakeLists.txt b/libc/src/__support/CPP/CMakeLists.txt
index 8b65a8839..a389a6d 100644
--- a/libc/src/__support/CPP/CMakeLists.txt
+++ b/libc/src/__support/CPP/CMakeLists.txt
@@ -210,3 +210,9 @@ add_object_library(
libc.src.__support.common
libc.src.__support.macros.properties.os
)
+
+add_header_library(
+ simd
+ HDRS
+ simd.h
+)
diff --git a/libc/src/__support/CPP/algorithm.h b/libc/src/__support/CPP/algorithm.h
index 7704b3f..de0c473 100644
--- a/libc/src/__support/CPP/algorithm.h
+++ b/libc/src/__support/CPP/algorithm.h
@@ -18,6 +18,12 @@
namespace LIBC_NAMESPACE_DECL {
namespace cpp {
+template <class T = void> struct plus {};
+template <class T = void> struct multiplies {};
+template <class T = void> struct bit_and {};
+template <class T = void> struct bit_or {};
+template <class T = void> struct bit_xor {};
+
template <class T> LIBC_INLINE constexpr const T &max(const T &a, const T &b) {
return (a < b) ? b : a;
}
diff --git a/libc/src/__support/CPP/simd.h b/libc/src/__support/CPP/simd.h
new file mode 100644
index 0000000..449455c
--- /dev/null
+++ b/libc/src/__support/CPP/simd.h
@@ -0,0 +1,276 @@
+//===-- Portable SIMD library similar to stdx::simd -------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a generic interface into fixed-size SIMD instructions
+// using the clang vector type. The API shares some similarities with the
+// stdx::simd proposal, but instead chooses to use vectors as primitive types
+// with several extra helper functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/algorithm.h"
+#include "src/__support/CPP/limits.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+#include <stddef.h>
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_SIMD_H
+#define LLVM_LIBC_SRC___SUPPORT_CPP_SIMD_H
+
+#if LIBC_HAS_VECTOR_TYPE
+
+namespace LIBC_NAMESPACE_DECL {
+namespace cpp {
+
+namespace internal {
+
+template <typename T>
+using get_as_integer_type_t = unsigned _BitInt(sizeof(T) * CHAR_BIT);
+
+#if defined(LIBC_TARGET_CPU_HAS_AVX512F)
+template <typename T>
+inline constexpr size_t native_vector_size = 64 / sizeof(T);
+#elif defined(LIBC_TARGET_CPU_HAS_AVX2)
+template <typename T>
+inline constexpr size_t native_vector_size = 32 / sizeof(T);
+#elif defined(LIBC_TARGET_CPU_HAS_SSE2) || defined(LIBC_TARGET_CPU_HAS_ARM_NEON)
+template <typename T>
+inline constexpr size_t native_vector_size = 16 / sizeof(T);
+#else
+template <typename T> inline constexpr size_t native_vector_size = 1;
+#endif
+
+template <typename T> LIBC_INLINE constexpr T poison() {
+ return __builtin_nondeterministic_value(T());
+}
+} // namespace internal
+
+// Type aliases.
+template <typename T, size_t N>
+using fixed_size_simd = T [[clang::ext_vector_type(N)]];
+template <typename T, size_t N = internal::native_vector_size<T>>
+using simd = T [[clang::ext_vector_type(N)]];
+template <typename T>
+using simd_mask = simd<bool, internal::native_vector_size<T>>;
+
+// Type trait helpers.
+template <typename T>
+struct simd_size : cpp::integral_constant<size_t, __builtin_vectorelements(T)> {
+};
+template <class T> constexpr size_t simd_size_v = simd_size<T>::value;
+
+template <typename T> struct is_simd : cpp::integral_constant<bool, false> {};
+template <typename T, unsigned N>
+struct is_simd<simd<T, N>> : cpp::integral_constant<bool, true> {};
+template <class T> constexpr bool is_simd_v = is_simd<T>::value;
+
+template <typename T>
+struct is_simd_mask : cpp::integral_constant<bool, false> {};
+template <unsigned N>
+struct is_simd_mask<simd<bool, N>> : cpp::integral_constant<bool, true> {};
+template <class T> constexpr bool is_simd_mask_v = is_simd_mask<T>::value;
+
+template <typename T> struct simd_element_type;
+template <typename T, size_t N> struct simd_element_type<simd<T, N>> {
+ using type = T;
+};
+template <typename T>
+using simd_element_type_t = typename simd_element_type<T>::type;
+
+template <typename T>
+using enable_if_simd_t = cpp::enable_if_t<is_simd_v<T>, T>;
+
+// Casting.
+template <typename To, typename From, size_t N>
+LIBC_INLINE constexpr simd<To, N> simd_cast(simd<From, N> v) {
+ return __builtin_convertvector(v, simd<To, N>);
+}
+
+// SIMD mask operations.
+template <size_t N> LIBC_INLINE constexpr bool all_of(simd<bool, N> m) {
+ return __builtin_reduce_and(m);
+}
+template <size_t N> LIBC_INLINE constexpr bool any_of(simd<bool, N> m) {
+ return __builtin_reduce_or(m);
+}
+template <size_t N> LIBC_INLINE constexpr bool none_of(simd<bool, N> m) {
+ return !any_of(m);
+}
+template <size_t N> LIBC_INLINE constexpr bool some_of(simd<bool, N> m) {
+ return any_of(m) && !all_of(m);
+}
+template <size_t N> LIBC_INLINE constexpr int popcount(simd<bool, N> m) {
+ return __builtin_popcountg(m);
+}
+template <size_t N> LIBC_INLINE constexpr int find_first_set(simd<bool, N> m) {
+ return __builtin_ctzg(m);
+}
+template <size_t N> LIBC_INLINE constexpr int find_last_set(simd<bool, N> m) {
+ constexpr size_t size = simd_size_v<simd<bool, N>>;
+ return size - __builtin_clzg(m);
+}
+
+// Elementwise operations.
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> min(simd<T, N> x, simd<T, N> y) {
+ return __builtin_elementwise_min(x, y);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> max(simd<T, N> x, simd<T, N> y) {
+ return __builtin_elementwise_max(x, y);
+}
+
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> abs(simd<T, N> x) {
+ return __builtin_elementwise_abs(x);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> fma(simd<T, N> x, simd<T, N> y, simd<T, N> z) {
+ return __builtin_elementwise_fma(x, y, z);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> ceil(simd<T, N> x) {
+ return __builtin_elementwise_ceil(x);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> floor(simd<T, N> x) {
+ return __builtin_elementwise_floor(x);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> roundeven(simd<T, N> x) {
+ return __builtin_elementwise_roundeven(x);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> round(simd<T, N> x) {
+ return __builtin_elementwise_round(x);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> trunc(simd<T, N> x) {
+ return __builtin_elementwise_trunc(x);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> nearbyint(simd<T, N> x) {
+ return __builtin_elementwise_nearbyint(x);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> rint(simd<T, N> x) {
+ return __builtin_elementwise_rint(x);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> canonicalize(simd<T, N> x) {
+ return __builtin_elementwise_canonicalize(x);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> copysign(simd<T, N> x, simd<T, N> y) {
+ return __builtin_elementwise_copysign(x, y);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> fmod(simd<T, N> x, simd<T, N> y) {
+ return __builtin_elementwise_fmod(x, y);
+}
+
+// Reduction operations.
+template <typename T, size_t N, typename Op = cpp::plus<>>
+LIBC_INLINE constexpr T reduce(simd<T, N> v, Op op = {}) {
+ return reduce(v, op);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::plus<>) {
+ return __builtin_reduce_add(v);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::multiplies<>) {
+ return __builtin_reduce_mul(v);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::bit_and<>) {
+ return __builtin_reduce_and(v);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::bit_or<>) {
+ return __builtin_reduce_or(v);
+}
+template <typename T, size_t N>
+LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::bit_xor<>) {
+ return __builtin_reduce_xor(v);
+}
+template <typename T, size_t N> LIBC_INLINE constexpr T hmin(simd<T, N> v) {
+ return __builtin_reduce_min(v);
+}
+template <typename T, size_t N> LIBC_INLINE constexpr T hmax(simd<T, N> v) {
+ return __builtin_reduce_max(v);
+}
+
+// Accessor helpers.
+template <typename T>
+LIBC_INLINE enable_if_simd_t<T> load_unaligned(const void *ptr) {
+ T tmp;
+ __builtin_memcpy(&tmp, ptr, sizeof(T));
+ return tmp;
+}
+template <typename T>
+LIBC_INLINE enable_if_simd_t<T> load_aligned(const void *ptr) {
+ return load_unaligned<T>(__builtin_assume_aligned(ptr, alignof(T)));
+}
+template <typename T>
+LIBC_INLINE enable_if_simd_t<T> store_unaligned(T v, void *ptr) {
+ __builtin_memcpy(ptr, &v, sizeof(T));
+}
+template <typename T>
+LIBC_INLINE enable_if_simd_t<T> store_aligned(T v, void *ptr) {
+ store_unaligned<T>(v, __builtin_assume_aligned(ptr, alignof(T)));
+}
+template <typename T>
+LIBC_INLINE enable_if_simd_t<T>
+masked_load(simd<bool, simd_size_v<T>> m, void *ptr,
+ T passthru = internal::poison<simd_element_type<T>>()) {
+ return __builtin_masked_load(m, ptr, passthru);
+}
+template <typename T>
+LIBC_INLINE enable_if_simd_t<T> masked_store(simd<bool, simd_size_v<T>> m, T v,
+ void *ptr) {
+ __builtin_masked_store(
+ m, v, static_cast<T *>(__builtin_assume_aligned(ptr, alignof(T))));
+}
+
+// Construction helpers.
+template <typename T, size_t N> LIBC_INLINE constexpr simd<T, N> splat(T v) {
+ return simd<T, N>(v);
+}
+template <typename T> LIBC_INLINE constexpr simd<T> splat(T v) {
+ return splat<T, simd_size_v<simd<T>>>(v);
+}
+template <typename T, unsigned N>
+LIBC_INLINE constexpr simd<T, N> iota(T base = T(0), T step = T(1)) {
+ simd<T, N> v{};
+ for (unsigned i = 0; i < N; ++i)
+ v[i] = base + T(i) * step;
+ return v;
+}
+template <typename T>
+LIBC_INLINE constexpr simd<T> iota(T base = T(0), T step = T(1)) {
+ return iota<T, simd_size_v<simd<T>>>(base, step);
+}
+
+// Conditional helpers.
+template <typename T, size_t N>
+LIBC_INLINE constexpr simd<T, N> select(simd<bool, N> m, simd<T, N> x,
+ simd<T, N> y) {
+ return m ? x : y;
+}
+
+// TODO: where expressions, scalar overloads, ABI types.
+
+} // namespace cpp
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_HAS_VECTOR_TYPE
+#endif
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 2357b05..ca7be66 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -244,7 +244,7 @@ LIBC_INLINE T fdim(T x, T y) {
return y;
}
- return (x > y ? x - y : 0);
+ return (x > y ? x - y : T(0));
}
// Avoid reusing `issignaling` macro.
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 6e447fc..e8fc539 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -231,6 +231,7 @@ add_header_library(
Hypot.h
DEPENDS
.basic_operations
+ .cast
.fenv_impl
.fp_bits
.rounding_mode
@@ -285,6 +286,9 @@ add_header_library(
libc.hdr.stdint_proxy
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.FPUtil.generic.div
+ libc.src.__support.FPUtil.generic.mul
libc.src.__support.macros.config
libc.src.__support.macros.properties.types
)
diff --git a/libc/src/__support/FPUtil/Hypot.h b/libc/src/__support/FPUtil/Hypot.h
index 94da259c..e23f8b5 100644
--- a/libc/src/__support/FPUtil/Hypot.h
+++ b/libc/src/__support/FPUtil/Hypot.h
@@ -12,6 +12,7 @@
#include "BasicOperations.h"
#include "FEnvImpl.h"
#include "FPBits.h"
+#include "cast.h"
#include "rounding_mode.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
@@ -133,8 +134,18 @@ LIBC_INLINE T hypot(T x, T y) {
uint16_t a_exp = a_bits.get_biased_exponent();
uint16_t b_exp = b_bits.get_biased_exponent();
- if ((a_exp - b_exp >= FPBits_t::FRACTION_LEN + 2) || (x == 0) || (y == 0))
- return x_abs.get_val() + y_abs.get_val();
+ if ((a_exp - b_exp >= FPBits_t::FRACTION_LEN + 2) || (x == 0) || (y == 0)) {
+#ifdef LIBC_TYPES_HAS_FLOAT16
+ if constexpr (cpp::is_same_v<T, float16>) {
+ // Compiler runtime for basic operations of float16 might not be correctly
+ // rounded for all rounding modes.
+ float af = fputil::cast<float>(x_abs.get_val());
+ float bf = fputil::cast<float>(y_abs.get_val());
+ return fputil::cast<float16>(af + bf);
+ } else
+#endif // LIBC_TYPES_HAS_FLOAT16
+ return x_abs.get_val() + y_abs.get_val();
+ }
uint64_t out_exp = a_exp;
StorageType a_mant = a_bits.get_mantissa();
diff --git a/libc/src/__support/FPUtil/bfloat16.h b/libc/src/__support/FPUtil/bfloat16.h
index fa45d73..13e1512 100644
--- a/libc/src/__support/FPUtil/bfloat16.h
+++ b/libc/src/__support/FPUtil/bfloat16.h
@@ -15,6 +15,9 @@
#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/comparison_operations.h"
#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/FPUtil/generic/div.h"
+#include "src/__support/FPUtil/generic/mul.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/types.h"
@@ -26,9 +29,9 @@ struct BFloat16 {
LIBC_INLINE BFloat16() = default;
- LIBC_INLINE constexpr explicit BFloat16(uint16_t bits) : bits(bits) {}
-
- template <typename T> LIBC_INLINE constexpr explicit BFloat16(T value) {
+ template <typename T>
+ LIBC_INLINE constexpr explicit BFloat16(T value)
+ : bits(static_cast<uint16_t>(0U)) {
if constexpr (cpp::is_floating_point_v<T>) {
bits = fputil::cast<bfloat16>(value).bits;
} else if constexpr (cpp::is_integral_v<T>) {
@@ -45,6 +48,8 @@ struct BFloat16 {
xd(sign, 0, value);
bits = xd.template as<bfloat16, /*ShouldSignalExceptions=*/true>().bits;
+ } else if constexpr (cpp::is_convertible_v<T, BFloat16>) {
+ bits = value.operator BFloat16().bits;
} else {
bits = fputil::cast<bfloat16>(static_cast<float>(value)).bits;
}
@@ -58,6 +63,11 @@ struct BFloat16 {
return cpp::bit_cast<float>(x_bits);
}
+ template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
+ LIBC_INLINE constexpr explicit operator T() const {
+ return static_cast<T>(static_cast<float>(*this));
+ }
+
LIBC_INLINE bool operator==(BFloat16 other) const {
return fputil::equals(*this, other);
}
@@ -81,6 +91,28 @@ struct BFloat16 {
LIBC_INLINE bool operator>=(BFloat16 other) const {
return fputil::greater_than_or_equals(*this, other);
}
+
+ LIBC_INLINE constexpr BFloat16 operator-() const {
+ fputil::FPBits<bfloat16> result(*this);
+ result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS);
+ return result.get_val();
+ }
+
+ LIBC_INLINE BFloat16 operator+(BFloat16 other) const {
+ return fputil::generic::add<BFloat16>(*this, other);
+ }
+
+ LIBC_INLINE BFloat16 operator-(BFloat16 other) const {
+ return fputil::generic::sub<BFloat16>(*this, other);
+ }
+
+ LIBC_INLINE BFloat16 operator*(BFloat16 other) const {
+ return fputil::generic::mul<bfloat16>(*this, other);
+ }
+
+ LIBC_INLINE BFloat16 operator/(BFloat16 other) const {
+ return fputil::generic::div<bfloat16>(*this, other);
+ }
}; // struct BFloat16
} // namespace fputil
diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
index e999ece..54c80e8 100644
--- a/libc/src/__support/FPUtil/cast.h
+++ b/libc/src/__support/FPUtil/cast.h
@@ -27,47 +27,47 @@ LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
OutType>
cast(InType x) {
// Casting to the same type is a no-op.
- if constexpr (cpp::is_same_v<InType, OutType>)
+ if constexpr (cpp::is_same_v<InType, OutType>) {
return x;
-
- // bfloat16 is always defined (for now)
- if constexpr (cpp::is_same_v<OutType, bfloat16> ||
- cpp::is_same_v<InType, bfloat16>
+ } else {
+ if constexpr (cpp::is_same_v<OutType, bfloat16> ||
+ cpp::is_same_v<InType, bfloat16>
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
- || cpp::is_same_v<OutType, float16> ||
- cpp::is_same_v<InType, float16>
+ || cpp::is_same_v<OutType, float16> ||
+ cpp::is_same_v<InType, float16>
#endif
- ) {
- using InFPBits = FPBits<InType>;
- using InStorageType = typename InFPBits::StorageType;
- using OutFPBits = FPBits<OutType>;
- using OutStorageType = typename OutFPBits::StorageType;
+ ) {
+ using InFPBits = FPBits<InType>;
+ using InStorageType = typename InFPBits::StorageType;
+ using OutFPBits = FPBits<OutType>;
+ using OutStorageType = typename OutFPBits::StorageType;
- InFPBits x_bits(x);
+ InFPBits x_bits(x);
- if (x_bits.is_nan()) {
- if (x_bits.is_signaling_nan()) {
- raise_except_if_required(FE_INVALID);
- return OutFPBits::quiet_nan().get_val();
- }
+ if (x_bits.is_nan()) {
+ if (x_bits.is_signaling_nan()) {
+ raise_except_if_required(FE_INVALID);
+ return OutFPBits::quiet_nan().get_val();
+ }
- InStorageType x_mant = x_bits.get_mantissa();
- if (InFPBits::FRACTION_LEN > OutFPBits::FRACTION_LEN)
- x_mant >>= InFPBits::FRACTION_LEN - OutFPBits::FRACTION_LEN;
- return OutFPBits::quiet_nan(x_bits.sign(),
- static_cast<OutStorageType>(x_mant))
- .get_val();
- }
+ InStorageType x_mant = x_bits.get_mantissa();
+ if (InFPBits::FRACTION_LEN > OutFPBits::FRACTION_LEN)
+ x_mant >>= InFPBits::FRACTION_LEN - OutFPBits::FRACTION_LEN;
+ return OutFPBits::quiet_nan(x_bits.sign(),
+ static_cast<OutStorageType>(x_mant))
+ .get_val();
+ }
- if (x_bits.is_inf())
- return OutFPBits::inf(x_bits.sign()).get_val();
+ if (x_bits.is_inf())
+ return OutFPBits::inf(x_bits.sign()).get_val();
- constexpr size_t MAX_FRACTION_LEN =
- cpp::max(OutFPBits::FRACTION_LEN, InFPBits::FRACTION_LEN);
- DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x);
- return xd.template as<OutType, /*ShouldSignalExceptions=*/true>();
- } else {
- return static_cast<OutType>(x);
+ constexpr size_t MAX_FRACTION_LEN =
+ cpp::max(OutFPBits::FRACTION_LEN, InFPBits::FRACTION_LEN);
+ DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x);
+ return xd.template as<OutType, /*ShouldSignalExceptions=*/true>();
+ } else {
+ return static_cast<OutType>(x);
+ }
}
}
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 3464e4a..cc0710f 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -576,7 +576,7 @@ LIBC_INLINE constexpr DyadicFloat<Bits> quick_mul(const DyadicFloat<Bits> &a,
// Check the leading bit directly, should be faster than using clz in
// normalize().
if (result.mantissa.val[DyadicFloat<Bits>::MantissaType::WORD_COUNT - 1] >>
- 63 ==
+ (DyadicFloat<Bits>::MantissaType::WORD_SIZE - 1) ==
0)
result.shift_left(1);
} else {
diff --git a/libc/src/__support/FPUtil/generic/CMakeLists.txt b/libc/src/__support/FPUtil/generic/CMakeLists.txt
index 117213f..b75efc8 100644
--- a/libc/src/__support/FPUtil/generic/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/generic/CMakeLists.txt
@@ -68,6 +68,7 @@ add_header_library(
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.attributes
libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.types
)
add_header_library(
@@ -77,6 +78,7 @@ add_header_library(
DEPENDS
libc.hdr.errno_macros
libc.hdr.fenv_macros
+ libc.src.__support.CPP.algorithm
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
libc.src.__support.FPUtil.basic_operations
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 7205d8d..b2e9d81 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -87,8 +87,12 @@ add_or_sub(InType x, InType y) {
return OutFPBits::inf(x_bits.sign()).get_val();
}
- if (y_bits.is_inf())
- return OutFPBits::inf(y_bits.sign()).get_val();
+ if (y_bits.is_inf()) {
+ if constexpr (IsSub)
+ return OutFPBits::inf(y_bits.sign().negate()).get_val();
+ else
+ return OutFPBits::inf(y_bits.sign()).get_val();
+ }
if (x_bits.is_zero()) {
if (y_bits.is_zero()) {
@@ -100,13 +104,22 @@ add_or_sub(InType x, InType y) {
}
}
- // volatile prevents Clang from converting tmp to OutType and then
- // immediately back to InType before negating it, resulting in double
- // rounding.
- volatile InType tmp = y;
- if constexpr (IsSub)
- tmp = -tmp;
- return cast<OutType>(tmp);
+ if constexpr (cpp::is_same_v<InType, bfloat16> &&
+ cpp::is_same_v<OutType, bfloat16>) {
+ OutFPBits y_bits(y);
+ if constexpr (IsSub)
+ y_bits.set_sign(y_bits.sign().negate());
+ return y_bits.get_val();
+ } else {
+
+ // volatile prevents Clang from converting tmp to OutType and then
+ // immediately back to InType before negating it, resulting in double
+ // rounding.
+ volatile InType tmp = y;
+ if constexpr (IsSub)
+ tmp = -tmp;
+ return cast<OutType>(tmp);
+ }
}
if (y_bits.is_zero())
@@ -161,8 +174,8 @@ add_or_sub(InType x, InType y) {
int alignment = (max_bits.get_biased_exponent() - max_bits.is_normal()) -
(min_bits.get_biased_exponent() - min_bits.is_normal());
- InStorageType aligned_min_mant =
- min_mant >> cpp::min(alignment, RESULT_MANTISSA_LEN);
+ InStorageType aligned_min_mant = static_cast<InStorageType>(
+ min_mant >> cpp::min(alignment, RESULT_MANTISSA_LEN));
bool aligned_min_mant_sticky;
if (alignment <= GUARD_BITS_LEN)
diff --git a/libc/src/__support/FPUtil/generic/div.h b/libc/src/__support/FPUtil/generic/div.h
index f0e4057..bf7d0b7 100644
--- a/libc/src/__support/FPUtil/generic/div.h
+++ b/libc/src/__support/FPUtil/generic/div.h
@@ -11,6 +11,7 @@
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/BasicOperations.h"
@@ -34,8 +35,9 @@ div(InType x, InType y) {
using OutStorageType = typename OutFPBits::StorageType;
using InFPBits = FPBits<InType>;
using InStorageType = typename InFPBits::StorageType;
- using DyadicFloat =
- DyadicFloat<cpp::bit_ceil(static_cast<size_t>(InFPBits::SIG_LEN + 1))>;
+ using DyadicFloat = DyadicFloat<cpp::max(
+ static_cast<size_t>(16),
+ cpp::bit_ceil(static_cast<size_t>(InFPBits::SIG_LEN + 1)))>;
InFPBits x_bits(x);
InFPBits y_bits(y);
@@ -78,7 +80,7 @@ div(InType x, InType y) {
}
if (y_bits.is_inf())
- return OutFPBits::inf(result_sign).get_val();
+ return OutFPBits::zero(result_sign).get_val();
if (y_bits.is_zero()) {
if (x_bits.is_zero()) {
diff --git a/libc/src/__support/FPUtil/rounding_mode.h b/libc/src/__support/FPUtil/rounding_mode.h
index 4ee0a0b..fdc8498 100644
--- a/libc/src/__support/FPUtil/rounding_mode.h
+++ b/libc/src/__support/FPUtil/rounding_mode.h
@@ -17,30 +17,24 @@
namespace LIBC_NAMESPACE_DECL {
namespace fputil {
+namespace generic {
+
// Quick free-standing test whether fegetround() == FE_UPWARD.
// Using the following observation:
// 1.0f + 2^-25 = 1.0f for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO
// = 0x1.000002f for FE_UPWARD.
-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);
- }
+LIBC_INLINE bool fenv_is_round_up() {
+ static 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 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);
- }
+LIBC_INLINE bool fenv_is_round_down() {
+ static volatile float x = 0x1.0p-25f;
+ return (-1.0f - x != -1.0f);
}
// Quick free-standing test whether fegetround() == FE_TONEAREST.
@@ -49,14 +43,10 @@ LIBC_INLINE static constexpr 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 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);
- }
+LIBC_INLINE bool fenv_is_round_to_nearest() {
+ static volatile float x = 0x1.0p-24f;
+ float y = 1.5f + x;
+ return (y == 1.5f - x);
}
// Quick free-standing test whether fegetround() == FE_TOWARDZERO.
@@ -69,13 +59,56 @@ LIBC_INLINE static constexpr 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);
+}
+
+// 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);
+
+ 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;
+}
+
+} // namespace generic
+
+LIBC_INLINE static constexpr bool fenv_is_round_up() {
+ if (cpp::is_constant_evaluated()) {
+ return false;
+ } else {
+ return generic::fenv_is_round_up();
+ }
+}
+
+LIBC_INLINE static constexpr bool fenv_is_round_down() {
+ if (cpp::is_constant_evaluated()) {
+ return false;
+ } else {
+ return generic::fenv_is_round_down();
+ }
+}
+
+LIBC_INLINE static constexpr bool fenv_is_round_to_nearest() {
+ if (cpp::is_constant_evaluated()) {
+ return true;
+ } else {
+ return generic::fenv_is_round_to_nearest();
+ }
+}
+
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);
+ return generic::fenv_is_round_to_zero();
}
}
@@ -84,15 +117,7 @@ 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 + x == 2.0f) ? FE_TONEAREST : FE_UPWARD;
+ return generic::quick_get_round();
}
}
diff --git a/libc/src/__support/File/file.cpp b/libc/src/__support/File/file.cpp
index 303852d..4217e73 100644
--- a/libc/src/__support/File/file.cpp
+++ b/libc/src/__support/File/file.cpp
@@ -123,7 +123,7 @@ FileIOResult File::write_unlocked_fbf(const uint8_t *data, size_t len) {
FileIOResult result =
platform_write(this, remainder.data(), remainder.size());
- size_t bytes_written = buf_result.value;
+ size_t bytes_written = result.value;
// If less bytes were written than expected, then an error occurred. Return
// the number of bytes that have been written from |data|.
diff --git a/libc/src/__support/GPU/CMakeLists.txt b/libc/src/__support/GPU/CMakeLists.txt
index f8fdfeb..72a7879 100644
--- a/libc/src/__support/GPU/CMakeLists.txt
+++ b/libc/src/__support/GPU/CMakeLists.txt
@@ -9,6 +9,12 @@ add_header_library(
utils.h
)
+add_header_library(
+ fixedstack
+ HDRS
+ fixedstack.h
+)
+
add_object_library(
allocator
SRCS
@@ -23,4 +29,5 @@ add_object_library(
libc.src.__support.CPP.bit
libc.src.__support.CPP.new
.utils
+ .fixedstack
)
diff --git a/libc/src/__support/GPU/allocator.cpp b/libc/src/__support/GPU/allocator.cpp
index 250bebd..3da339c 100644
--- a/libc/src/__support/GPU/allocator.cpp
+++ b/libc/src/__support/GPU/allocator.cpp
@@ -20,6 +20,7 @@
#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/new.h"
+#include "src/__support/GPU/fixedstack.h"
#include "src/__support/GPU/utils.h"
#include "src/__support/RPC/rpc_client.h"
#include "src/__support/threads/sleep.h"
@@ -39,6 +40,9 @@ constexpr static uint32_t MIN_ALIGNMENT = MIN_SIZE - 1;
// The number of times to attempt claiming an in-progress slab allocation.
constexpr static uint32_t MAX_TRIES = 1024;
+// The number of previously allocated slabs we will keep in memory.
+constexpr static uint32_t CACHED_SLABS = 8;
+
static_assert(!(ARRAY_SIZE & (ARRAY_SIZE - 1)), "Must be a power of two");
namespace impl {
@@ -162,7 +166,11 @@ static inline uint32_t get_leader_id(uint64_t ballot, uint32_t id) {
// 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();
+ if constexpr (cpp::is_pointer_v<T>)
+ return reinterpret_cast<uintptr_t>(x) ==
+ cpp::numeric_limits<uintptr_t>::max();
+ else
+ return x == cpp::numeric_limits<T>::max();
}
} // namespace impl
@@ -185,20 +193,35 @@ struct Slab {
struct alignas(MIN_SIZE) Header {
uint32_t chunk_size;
uint32_t global_index;
+ uint32_t cached_chunk_size;
};
// Initialize the slab with its chunk size and index in the global table for
// use when freeing.
Slab(uint32_t chunk_size, uint32_t global_index) {
Header *header = reinterpret_cast<Header *>(memory);
+ header->cached_chunk_size = cpp::numeric_limits<uint32_t>::max();
+ header->chunk_size = chunk_size;
+ header->global_index = global_index;
+ }
+
+ // Reset the memory with a new index and chunk size, not thread safe.
+ Slab *reset(uint32_t chunk_size, uint32_t global_index) {
+ Header *header = reinterpret_cast<Header *>(memory);
+ header->cached_chunk_size = header->chunk_size;
header->chunk_size = chunk_size;
header->global_index = global_index;
+ return this;
}
// Set the necessary bitfield bytes to zero in parallel using many lanes. This
// must be called before the bitfield can be accessed safely, memory is not
// guaranteed to be zero initialized in the current implementation.
void initialize(uint64_t uniform) {
+ // If this is a re-used slab the memory is already set to zero.
+ if (get_cached_chunk_size() <= get_chunk_size())
+ return;
+
uint32_t size = (bitfield_bytes(get_chunk_size()) + sizeof(uint32_t) - 1) /
sizeof(uint32_t);
impl::uniform_memset(get_bitfield(), 0, size, uniform);
@@ -236,6 +259,11 @@ struct Slab {
return reinterpret_cast<const Header *>(memory)->chunk_size;
}
+ // Get the chunk size that was previously used.
+ uint32_t get_cached_chunk_size() const {
+ return reinterpret_cast<const Header *>(memory)->cached_chunk_size;
+ }
+
// Get the location in the memory where we will store the global index.
uint32_t get_global_index() const {
return reinterpret_cast<const Header *>(memory)->global_index;
@@ -337,6 +365,9 @@ struct Slab {
uint8_t memory[SLAB_SIZE];
};
+// A global cache of previously allocated slabs for efficient reuse.
+static FixedStack<Slab *, CACHED_SLABS> slab_cache;
+
/// A wait-free guard around a pointer resource to be created dynamically if
/// space is available and freed once there are no more users.
struct GuardPtr {
@@ -408,13 +439,24 @@ private:
reinterpret_cast<Slab *>(cpp::numeric_limits<uintptr_t>::max()),
cpp::MemoryOrder::RELAXED, cpp::MemoryOrder::RELAXED)) {
count = cpp::numeric_limits<uint32_t>::max();
+
+ Slab *cached = nullptr;
+ if (slab_cache.pop(cached))
+ return cached->reset(cpp::forward<Args>(args)...);
+
void *raw = impl::rpc_allocate(sizeof(Slab));
if (!raw)
return nullptr;
return new (raw) Slab(cpp::forward<Args>(args)...);
}
- if (!expected || impl::is_sentinel(reinterpret_cast<uintptr_t>(expected)))
+ // If there is a slab allocation in progress we retry a few times.
+ for (uint32_t t = 0; impl::is_sentinel(expected) && t < MAX_TRIES; ++t) {
+ sleep_briefly();
+ expected = ptr.load(cpp::MemoryOrder::RELAXED);
+ }
+
+ if (!expected || impl::is_sentinel(expected))
return nullptr;
if (!ref.acquire(n, count))
@@ -475,8 +517,10 @@ public:
if (gpu::get_lane_id() == uint32_t(cpp::countr_zero(mask)) &&
ref.release(cpp::popcount(mask))) {
Slab *p = ptr.load(cpp::MemoryOrder::RELAXED);
- p->~Slab();
- impl::rpc_free(p);
+ if (!slab_cache.push(p)) {
+ p->~Slab();
+ impl::rpc_free(p);
+ }
cpp::atomic_thread_fence(cpp::MemoryOrder::RELEASE);
ptr.store(nullptr, cpp::MemoryOrder::RELAXED);
}
@@ -523,16 +567,6 @@ static Slab *find_slab(uint32_t chunk_size, uint64_t &uniform,
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();
- }
-
// 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 receive a sentinel value and return a failure.
diff --git a/libc/src/__support/GPU/fixedstack.h b/libc/src/__support/GPU/fixedstack.h
new file mode 100644
index 0000000..6ceaa2f
--- /dev/null
+++ b/libc/src/__support/GPU/fixedstack.h
@@ -0,0 +1,111 @@
+//===-- A lock-free data structure for a fixed capacity stack ---*- 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_GPU_FIXEDSTACK_H
+#define LLVM_LIBC_SRC___SUPPORT_GPU_FIXEDSTACK_H
+
+#include "src/__support/CPP/atomic.h"
+#include "src/__support/threads/sleep.h"
+
+#include <stdint.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+// A lock-free fixed size stack backed by an underlying array of data. It
+// supports push and pop operations in a completely lock-free manner.
+template <typename T, uint32_t CAPACITY> struct alignas(16) FixedStack {
+ // The index is stored as a 20-bit value and cannot index into any more.
+ static_assert(CAPACITY < 1024 * 1024, "Invalid buffer size");
+
+ // The head of the free and used stacks. Represents as a 20-bit index combined
+ // with a 44-bit ABA tag that is updated in a single atomic operation.
+ uint64_t free;
+ uint64_t used;
+
+ // The stack is a linked list of indices into the underlying data
+ uint32_t next[CAPACITY];
+ T data[CAPACITY];
+
+ // Get the 20-bit index into the underlying array from the head.
+ LIBC_INLINE static constexpr uint32_t get_node(uint64_t head) {
+ return static_cast<uint32_t>(head & 0xfffff);
+ }
+
+ // Increment the old ABA tag and merge it into the new index.
+ LIBC_INLINE static constexpr uint64_t make_head(uint64_t orig,
+ uint32_t node) {
+ return static_cast<uint64_t>(node) | (((orig >> 20ul) + 1ul) << 20ul);
+ }
+
+ // Attempts to pop data from the given stack by making it point to the next
+ // node. We repeatedly attempt to write to the head using compare-and-swap,
+ // expecting that it has not been changed by any other thread.
+ LIBC_INLINE uint32_t pop_impl(cpp::AtomicRef<uint64_t> head) {
+ uint64_t orig = head.load(cpp::MemoryOrder::RELAXED);
+
+ for (;;) {
+ if (get_node(orig) == CAPACITY)
+ return CAPACITY;
+
+ uint32_t node =
+ cpp::AtomicRef(next[get_node(orig)]).load(cpp::MemoryOrder::RELAXED);
+ if (head.compare_exchange_strong(orig, make_head(orig, node),
+ cpp::MemoryOrder::ACQUIRE,
+ cpp::MemoryOrder::RELAXED))
+ break;
+ }
+ return get_node(orig);
+ }
+
+ // Attempts to push data to the given stack by making it point to the new
+ // node. We repeatedly attempt to write to the head using compare-and-swap,
+ // expecting that it has not been changed by any other thread.
+ LIBC_INLINE uint32_t push_impl(cpp::AtomicRef<uint64_t> head, uint32_t node) {
+ uint64_t orig = head.load(cpp::MemoryOrder::RELAXED);
+ for (;;) {
+ next[node] = get_node(orig);
+ if (head.compare_exchange_strong(orig, make_head(orig, node),
+ cpp::MemoryOrder::RELEASE,
+ cpp::MemoryOrder::RELAXED))
+ break;
+ }
+ return get_node(head.load(cpp::MemoryOrder::RELAXED));
+ }
+
+public:
+ // Initialize the free stack to be full and the used stack to be empty. We use
+ // the capacity of the stack as a sentinel value.
+ LIBC_INLINE constexpr FixedStack() : free(0), used(CAPACITY), data{} {
+ for (uint32_t i = 0; i < CAPACITY; ++i)
+ next[i] = i + 1;
+ }
+
+ LIBC_INLINE bool push(const T &val) {
+ uint32_t node = pop_impl(cpp::AtomicRef(free));
+ if (node == CAPACITY)
+ return false;
+
+ data[node] = val;
+ push_impl(cpp::AtomicRef(used), node);
+ return true;
+ }
+
+ LIBC_INLINE bool pop(T &val) {
+ uint32_t node = pop_impl(cpp::AtomicRef(used));
+ if (node == CAPACITY)
+ return false;
+
+ val = data[node];
+ push_impl(cpp::AtomicRef(free), node);
+ return true;
+ }
+};
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_GPU_FIXEDSTACK_H
diff --git a/libc/src/__support/OSUtil/linux/aarch64/vdso.h b/libc/src/__support/OSUtil/linux/aarch64/vdso.h
index 3c4c620..ee5777a 100644
--- a/libc/src/__support/OSUtil/linux/aarch64/vdso.h
+++ b/libc/src/__support/OSUtil/linux/aarch64/vdso.h
@@ -23,6 +23,8 @@ LIBC_INLINE constexpr cpp::string_view symbol_name(VDSOSym sym) {
return "__kernel_clock_gettime";
case VDSOSym::ClockGetRes:
return "__kernel_clock_getres";
+ case VDSOSym::GetRandom:
+ return "__kernel_getrandom";
default:
return "";
}
diff --git a/libc/src/__support/OSUtil/linux/vdso_sym.h b/libc/src/__support/OSUtil/linux/vdso_sym.h
index 968e153..01f0b72 100644
--- a/libc/src/__support/OSUtil/linux/vdso_sym.h
+++ b/libc/src/__support/OSUtil/linux/vdso_sym.h
@@ -35,7 +35,8 @@ enum class VDSOSym {
RTSigReturn,
FlushICache,
RiscvHwProbe,
- VDSOSymCount
+ GetRandom,
+ VDSOSymCount,
};
template <VDSOSym sym> LIBC_INLINE constexpr auto dispatcher() {
@@ -60,6 +61,9 @@ template <VDSOSym sym> LIBC_INLINE constexpr auto dispatcher() {
else if constexpr (sym == VDSOSym::RiscvHwProbe)
return static_cast<int (*)(riscv_hwprobe *, size_t, size_t, cpu_set_t *,
unsigned)>(nullptr);
+ else if constexpr (sym == VDSOSym::GetRandom)
+ return static_cast<int (*)(void *, size_t, unsigned int, void *, size_t)>(
+ nullptr);
else
return static_cast<void *>(nullptr);
}
diff --git a/libc/src/__support/OSUtil/linux/x86_64/vdso.h b/libc/src/__support/OSUtil/linux/x86_64/vdso.h
index abe7c33..f46fcb0 100644
--- a/libc/src/__support/OSUtil/linux/x86_64/vdso.h
+++ b/libc/src/__support/OSUtil/linux/x86_64/vdso.h
@@ -29,6 +29,8 @@ LIBC_INLINE constexpr cpp::string_view symbol_name(VDSOSym sym) {
return "__vdso_time";
case VDSOSym::ClockGetRes:
return "__vdso_clock_getres";
+ case VDSOSym::GetRandom:
+ return "__vdso_getrandom";
default:
return "";
}
diff --git a/libc/src/__support/libc_errno.h b/libc/src/__support/libc_errno.h
index ab5f6a9..3720cde 100644
--- a/libc/src/__support/libc_errno.h
+++ b/libc/src/__support/libc_errno.h
@@ -37,18 +37,11 @@
// libc doesn't maintain any internal state, instead the embedder must define
// `int *__llvm_libc_errno(void);` C function.
#define LIBC_ERRNO_MODE_EXTERNAL 4
-// libc uses system `<errno.h>` `errno` macro directly in the overlay mode; in
-// fullbuild mode, effectively the same as `LIBC_ERRNO_MODE_EXTERNAL`.
-// In this mode, the public C++ symbol `LIBC_NAMESPACE::libc_errno ` is still
-// exported and get redirected to the system `errno` inside its implementation.
-
-// TODO: Investigate deprecating LIBC_ERRNO_MODE_SYSTEM in favor of
-// LIBC_ERRNO_MODE_SYSTEM_INLINE.
-// https://github.com/llvm/llvm-project/issues/143454
-#define LIBC_ERRNO_MODE_SYSTEM 5
+// DEPRECATED: #define LIBC_ERRNO_MODE_SYSTEM 5
// In this mode, the libc_errno is simply a macro resolved to `errno` from the
// system header <errno.h>. There is no need to link against the
-// `libc.src.errno.errno` object.
+// `libc.src.errno.errno` object, and public C++ symbol
+// `LIBC_NAMESPACE::libc_errno` doesn't exist.
#define LIBC_ERRNO_MODE_SYSTEM_INLINE 6
#if !defined(LIBC_ERRNO_MODE) || LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_DEFAULT
@@ -56,7 +49,7 @@
#if defined(LIBC_FULL_BUILD) || !defined(LIBC_COPT_PUBLIC_PACKAGING)
#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_THREAD_LOCAL
#else
-#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM
+#define LIBC_ERRNO_MODE LIBC_ERRNO_MODE_SYSTEM_INLINE
#endif
#endif // LIBC_ERRNO_MODE
@@ -65,7 +58,6 @@
LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_THREAD_LOCAL && \
LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SHARED && \
LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_EXTERNAL && \
- LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM && \
LIBC_ERRNO_MODE != LIBC_ERRNO_MODE_SYSTEM_INLINE
#error LIBC_ERRNO_MODE must be one of the following values: \
LIBC_ERRNO_MODE_DEFAULT, \
@@ -73,7 +65,6 @@ LIBC_ERRNO_MODE_UNDEFINED, \
LIBC_ERRNO_MODE_THREAD_LOCAL, \
LIBC_ERRNO_MODE_SHARED, \
LIBC_ERRNO_MODE_EXTERNAL, \
-LIBC_ERRNO_MODE_SYSTEM, \
LIBC_ERRNO_MODE_SYSTEM_INLINE.
#endif
diff --git a/libc/src/__support/macros/attributes.h b/libc/src/__support/macros/attributes.h
index c647467..145aa3b 100644
--- a/libc/src/__support/macros/attributes.h
+++ b/libc/src/__support/macros/attributes.h
@@ -17,6 +17,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H
#define LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H
+#include "config.h"
#include "properties/architectures.h"
#ifndef __has_attribute
@@ -28,7 +29,32 @@
#define LIBC_INLINE_ASM __asm__ __volatile__
#define LIBC_UNUSED __attribute__((unused))
-#ifdef LIBC_TARGET_ARCH_IS_GPU
+// Uses the platform specific specialization
+#define LIBC_THREAD_MODE_PLATFORM 0
+
+// Mutex guards nothing, used in single-threaded implementations
+#define LIBC_THREAD_MODE_SINGLE 1
+
+// Vendor provides implementation
+#define LIBC_THREAD_MODE_EXTERNAL 2
+
+// libcxx doesn't define LIBC_THREAD_MODE, unless that is passed in the command
+// line in the CMake invocation. This defaults to the original implementation
+// (before changes in https://github.com/llvm/llvm-project/pull/145358)
+#ifndef LIBC_THREAD_MODE
+#define LIBC_THREAD_MODE LIBC_THREAD_MODE_PLATFORM
+#endif // LIBC_THREAD_MODE
+
+#if LIBC_THREAD_MODE != LIBC_THREAD_MODE_PLATFORM && \
+ LIBC_THREAD_MODE != LIBC_THREAD_MODE_SINGLE && \
+ LIBC_THREAD_MODE != LIBC_THREAD_MODE_EXTERNAL
+#error LIBC_THREAD_MODE must be one of the following values: \
+LIBC_THREAD_MODE_PLATFORM, \
+LIBC_THREAD_MODE_SINGLE, \
+LIBC_THREAD_MODE_EXTERNAL.
+#endif
+
+#if LIBC_THREAD_MODE == LIBC_THREAD_MODE_SINGLE
#define LIBC_THREAD_LOCAL
#else
#define LIBC_THREAD_LOCAL thread_local
@@ -48,4 +74,11 @@
#define LIBC_PREFERED_TYPE(TYPE)
#endif
+#if __has_attribute(ext_vector_type) && \
+ LIBC_HAS_FEATURE(ext_vector_type_boolean)
+#define LIBC_HAS_VECTOR_TYPE 1
+#else
+#define LIBC_HAS_VECTOR_TYPE 0
+#endif
+
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H
diff --git a/libc/src/__support/macros/properties/cpu_features.h b/libc/src/__support/macros/properties/cpu_features.h
index fde30ea..fc6099c 100644
--- a/libc/src/__support/macros/properties/cpu_features.h
+++ b/libc/src/__support/macros/properties/cpu_features.h
@@ -59,6 +59,10 @@
#endif // LIBC_TARGET_CPU_HAS_ARM_FPU_DOUBLE
#endif // __ARM_FP
+#if defined(__ARM_NEON)
+#define LIBC_TARGET_CPU_HAS_ARM_NEON
+#endif
+
#if defined(__riscv_flen)
// https://github.com/riscv-non-isa/riscv-c-api-doc/blob/main/src/c-api.adoc
#if defined(__riscv_zfhmin)
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index e1076ed..39dc0e5 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -347,6 +347,117 @@ add_header_library(
)
add_header_library(
+ cbrtf
+ HDRS
+ cbrtf.h
+ DEPENDS
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ cos
+ HDRS
+ cos.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.src.errno.errno
+ libc.src.__support.FPUtil.double_double
+ libc.src.__support.FPUtil.dyadic_float
+ libc.src.__support.FPUtil.except_value_utils
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.math.range_reduction_double
+ libc.src.__support.math.sincos_eval
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ cosf
+ HDRS
+ cosf.h
+ DEPENDS
+ .sincosf_utils
+ libc.src.errno.errno
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.except_value_utils
+ libc.src.__support.FPUtil.fma
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ cosf16
+ HDRS
+ cosf16.h
+ DEPENDS
+ .sincosf16_utils
+ 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.except_value_utils
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+ coshf
+ HDRS
+ coshf.h
+ DEPENDS
+ .sinhfcoshf_utils
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ coshf16
+ HDRS
+ coshf16.h
+ DEPENDS
+ .expxf16_utils
+ libc.src.__support.FPUtil.except_value_utils
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.rounding_mode
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ cospif
+ HDRS
+ cospif.h
+ DEPENDS
+ .sincosf_utils
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.macros.optimization
+)
+
+add_header_library(
+ cospif16
+ HDRS
+ cospif16.h
+ DEPENDS
+ .sincosf16_utils
+ 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.macros.optimization
+)
+
+add_header_library(
erff
HDRS
erff.h
@@ -417,6 +528,21 @@ add_header_library(
)
add_header_library(
+ expxf16_utils
+ HDRS
+ expxf16_utils.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.macros.attributes
+ libc.src.__support.math.expf16_utils
+ libc.src.__support.math.exp10_float16_constants
+)
+
+add_header_library(
frexpf128
HDRS
frexpf128.h
@@ -602,3 +728,75 @@ add_header_library(
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
)
+
+add_header_library(
+ range_reduction_double
+ HDRS
+ range_reduction_double_common.h
+ range_reduction_double_fma.h
+ range_reduction_double_nofma.h
+ DEPENDS
+ libc.src.__support.FPUtil.double_double
+ libc.src.__support.FPUtil.dyadic_float
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.fma
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.common
+ libc.src.__support.integer_literals
+)
+
+add_header_library(
+ range_reduction
+ HDRS
+ range_reduction.h
+ range_reduction_fma.h
+ DEPENDS
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.fma
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.common
+)
+
+add_header_library(
+ sincos_eval
+ HDRS
+ sincos_eval.h
+ DEPENDS
+ libc.src.__support.FPUtil.double_double
+ libc.src.__support.FPUtil.dyadic_float
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.integer_literals
+)
+
+add_header_library(
+ sincosf_utils
+ HDRS
+ sincosf_utils.h
+ DEPENDS
+ .range_reduction
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.common
+)
+
+add_header_library(
+ sincosf16_utils
+ HDRS
+ sincosf16_utils.h
+ DEPENDS
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.common
+)
+
+add_header_library(
+ sinhfcoshf_utils
+ HDRS
+ sinhfcoshf_utils.h
+ DEPENDS
+ .exp10f_utils
+ libc.src.__support.FPUtil.multiply_add
+)
diff --git a/libc/src/__support/math/cbrtf.h b/libc/src/__support/math/cbrtf.h
new file mode 100644
index 0000000..f82892b
--- /dev/null
+++ b/libc/src/__support/math/cbrtf.h
@@ -0,0 +1,161 @@
+//===-- Implementation header for cbrtf -------------------------*- 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 LIBC_SRC___SUPPORT_MATH_CBRTF_H
+#define LIBC_SRC___SUPPORT_MATH_CBRTF_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.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 cbrtf(float x) {
+ // Look up table for 2^(i/3) for i = 0, 1, 2.
+ constexpr double CBRT2[3] = {1.0, 0x1.428a2f98d728bp0, 0x1.965fea53d6e3dp0};
+
+ // Degree-7 polynomials approximation of ((1 + x)^(1/3) - 1)/x for 0 <= x <= 1
+ // generated by Sollya with:
+ // > for i from 0 to 15 do {
+ // P = fpminimax(((1 + x)^(1/3) - 1)/x, 6, [|D...|], [i/16, (i + 1)/16]);
+ // print("{", coeff(P, 0), ",", coeff(P, 1), ",", coeff(P, 2), ",",
+ // coeff(P, 3), ",", coeff(P, 4), ",", coeff(P, 5), ",",
+ // coeff(P, 6), "},");
+ // };
+ // Then (1 + x)^(1/3) ~ 1 + x * P(x).
+ constexpr double COEFFS[16][7] = {
+ {0x1.55555555554ebp-2, -0x1.c71c71c678c0cp-4, 0x1.f9add2776de81p-5,
+ -0x1.511e10aa964a7p-5, 0x1.ee44165937fa2p-6, -0x1.7c5c9e059345dp-6,
+ 0x1.047f75e0aff14p-6},
+ {0x1.5555554d1149ap-2, -0x1.c71c676fcb5bp-4, 0x1.f9ab127dc57ebp-5,
+ -0x1.50ea8fd1d4c15p-5, 0x1.e9d68f28ced43p-6, -0x1.60e0e1e661311p-6,
+ 0x1.716eca1d6e3bcp-7},
+ {0x1.5555546377d45p-2, -0x1.c71bc1c6d49d2p-4, 0x1.f9924cc0ed24dp-5,
+ -0x1.4fea3beb53b3bp-5, 0x1.de028a9a07b1bp-6, -0x1.3b090d2233524p-6,
+ 0x1.0aeca34893785p-7},
+ {0x1.55554dce9f649p-2, -0x1.c7188b34b98f8p-4, 0x1.f93e1af34af49p-5,
+ -0x1.4d9a06be75c63p-5, 0x1.cb943f4f68992p-6, -0x1.139a685a5e3c4p-6,
+ 0x1.88410674c6a5dp-8},
+ {0x1.5555347d211c3p-2, -0x1.c70f2a4b1a5fap-4, 0x1.f88420e8602c3p-5,
+ -0x1.49becfa4ed3ep-5, 0x1.b475cd9013162p-6, -0x1.dcfee1dd2f8efp-7,
+ 0x1.249bb51a1c498p-8},
+ {0x1.5554f01b33dbap-2, -0x1.c6facb929dbf1p-4, 0x1.f73fb7861252ep-5,
+ -0x1.4459a4a0071fap-5, 0x1.9a8df2b504fc2p-6, -0x1.9a7ce3006d06ep-7,
+ 0x1.ba9230918fa2ep-9},
+ {0x1.55545c695db5fp-2, -0x1.c6d6089f20275p-4, 0x1.f556e0ea80efp-5,
+ -0x1.3d91372d083f4p-5, 0x1.7f66cff331f4p-6, -0x1.606a562491737p-7,
+ 0x1.52e3e17c71069p-9},
+ {0x1.55534a879232ap-2, -0x1.c69b836998b84p-4, 0x1.f2bb26dac0e4cp-5,
+ -0x1.359eed43716d7p-5, 0x1.64218cd824fbcp-6, -0x1.2e703e2e091e8p-7,
+ 0x1.0677d9af6aad4p-9},
+ {0x1.5551836bb5494p-2, -0x1.c64658c15353bp-4, 0x1.ef68517451a6ep-5,
+ -0x1.2cc20a980dceep-5, 0x1.49843e0fad93ap-6, -0x1.03c59ccb68e54p-7,
+ 0x1.9ad325dc7adcbp-10},
+ {0x1.554ecacb0d035p-2, -0x1.c5d2664026ffcp-4, 0x1.eb624796ba809p-5,
+ -0x1.233803d19a535p-5, 0x1.300decb1c3c28p-6, -0x1.befe18031ec3dp-8,
+ 0x1.449f5ee175c69p-10},
+ {0x1.554ae1f5ae815p-2, -0x1.c53c6b14ff6b2p-4, 0x1.e6b2d5127bb5bp-5,
+ -0x1.19387336788a3p-5, 0x1.180955a6ab255p-6, -0x1.81696703ba369p-8,
+ 0x1.02cb36389bd79p-10},
+ {0x1.55458a59f356ep-2, -0x1.c4820dd631ae9p-4, 0x1.e167af818bd15p-5,
+ -0x1.0ef35f6f72e52p-5, 0x1.019c33b65e4ebp-6, -0x1.4d25bdd52d3a5p-8,
+ 0x1.a008ae91f5936p-11},
+ {0x1.553e878eafee1p-2, -0x1.c3a1d0b2a3db2p-4, 0x1.db90d8ed9f89bp-5,
+ -0x1.0490e20f1ae91p-5, 0x1.d9a5d1fc42fe3p-7, -0x1.20bf8227c2abfp-8,
+ 0x1.50f8174cdb6e9p-11},
+ {0x1.5535a0dedf1b1p-2, -0x1.c29afb8bd01a1p-4, 0x1.d53f6371c1e27p-5,
+ -0x1.f463209b433e2p-6, 0x1.b35222a17e44p-7, -0x1.f5efbf505e133p-9,
+ 0x1.12e0e94e8586dp-11},
+ {0x1.552aa25e57bfdp-2, -0x1.c16d811e4acadp-4, 0x1.ce8489b47aa51p-5,
+ -0x1.dfde7ff758ea8p-6, 0x1.901f43aac38c8p-7, -0x1.b581d07df5ad5p-9,
+ 0x1.c3726535f1fc6p-12},
+ {0x1.551d5d9b204d3p-2, -0x1.c019e328f8db1p-4, 0x1.c7710f44fc3cep-5,
+ -0x1.cbbbe25ea8ba4p-6, 0x1.6fe270088623dp-7, -0x1.7e6fc79733761p-9,
+ 0x1.75077abf18d84p-12},
+ };
+
+ using FloatBits = typename fputil::FPBits<float>;
+ using DoubleBits = typename fputil::FPBits<double>;
+
+ FloatBits x_bits(x);
+
+ uint32_t x_abs = x_bits.uintval() & 0x7fff'ffff;
+ uint32_t sign_bit = (x_bits.uintval() >> 31) << DoubleBits::EXP_LEN;
+
+ if (LIBC_UNLIKELY(x == 0.0f || x_abs >= 0x7f80'0000)) {
+ // x is 0, Inf, or NaN.
+ // Make sure it works for FTZ/DAZ modes.
+ return x + x;
+ }
+
+ double xd = static_cast<double>(x);
+ DoubleBits xd_bits(xd);
+
+ // When using biased exponent of x in double precision,
+ // x_e = real_exponent_of_x + 1023
+ // Then:
+ // x_e / 3 = real_exponent_of_x / 3 + 1023/3
+ // = real_exponent_of_x / 3 + 341
+ // So to make it the correct biased exponent of x^(1/3), we add
+ // 1023 - 341 = 682
+ // to the quotient x_e / 3.
+ unsigned x_e = static_cast<unsigned>(xd_bits.get_biased_exponent());
+ unsigned out_e = (x_e / 3 + 682) | sign_bit;
+ unsigned shift_e = x_e % 3;
+
+ // Set x_m = 2^(x_e % 3) * (1.mantissa)
+ uint64_t x_m = xd_bits.get_mantissa();
+ // Use the leading 4 bits for look up table
+ unsigned idx = static_cast<unsigned>(x_m >> (DoubleBits::FRACTION_LEN - 4));
+
+ x_m |= static_cast<uint64_t>(DoubleBits::EXP_BIAS)
+ << DoubleBits::FRACTION_LEN;
+
+ double x_reduced = DoubleBits(x_m).get_val();
+ double dx = x_reduced - 1.0;
+
+ double dx_sq = dx * dx;
+ double c0 = fputil::multiply_add(dx, COEFFS[idx][0], 1.0);
+ double c1 = fputil::multiply_add(dx, COEFFS[idx][2], COEFFS[idx][1]);
+ double c2 = fputil::multiply_add(dx, COEFFS[idx][4], COEFFS[idx][3]);
+ double c3 = fputil::multiply_add(dx, COEFFS[idx][6], COEFFS[idx][5]);
+
+ double dx_4 = dx_sq * dx_sq;
+ double p0 = fputil::multiply_add(dx_sq, c1, c0);
+ double p1 = fputil::multiply_add(dx_sq, c3, c2);
+
+ double r = fputil::multiply_add(dx_4, p1, p0) * CBRT2[shift_e];
+
+ uint64_t r_m = DoubleBits(r).get_mantissa();
+ // Check if the output is exact. To be exact, the smallest 1-bit of the
+ // output has to be at least 2^-7 or higher. So we check the lowest 44 bits
+ // to see if they are within 2^(-52 + 3) errors from all zeros, then the
+ // result cube root is exact.
+ if (LIBC_UNLIKELY(((r_m + 8) & 0xfffffffffff) <= 16)) {
+ if ((r_m & 0xfffffffffff) <= 8)
+ r_m &= 0xffff'ffff'ffff'ffe0;
+ else
+ r_m = (r_m & 0xffff'ffff'ffff'ffe0) + 0x20;
+ fputil::clear_except_if_required(FE_INEXACT);
+ }
+ // Adjust exponent and sign.
+ uint64_t r_bits =
+ r_m | (static_cast<uint64_t>(out_e) << DoubleBits::FRACTION_LEN);
+
+ return static_cast<float>(DoubleBits(r_bits).get_val());
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_SRC___SUPPORT_MATH_CBRTF_H
diff --git a/libc/src/__support/math/cos.h b/libc/src/__support/math/cos.h
new file mode 100644
index 0000000..0802f9e
--- /dev/null
+++ b/libc/src/__support/math/cos.h
@@ -0,0 +1,173 @@
+//===-- Implementation header for cos ---------------------------*- 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 LIBC_SRC___SUPPORT_MATH_COS_H
+#define LIBC_SRC___SUPPORT_MATH_COS_H
+
+#include "range_reduction_double_common.h"
+#include "sincos_eval.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/except_value_utils.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
+
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+#include "range_reduction_double_fma.h"
+#else
+#include "range_reduction_double_nofma.h"
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr double cos(double x) {
+ using namespace range_reduction_double_internal;
+ using DoubleDouble = fputil::DoubleDouble;
+ using FPBits = typename fputil::FPBits<double>;
+ FPBits xbits(x);
+
+ uint16_t x_e = xbits.get_biased_exponent();
+
+ DoubleDouble y;
+ unsigned k = 0;
+ LargeRangeReduction range_reduction_large;
+
+ // |x| < 2^16.
+ if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) {
+ // |x| < 2^-7
+ if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 7)) {
+ // |x| < 2^-27
+ if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 27)) {
+ // Signed zeros.
+ if (LIBC_UNLIKELY(x == 0.0))
+ return 1.0;
+
+ // For |x| < 2^-27, |cos(x) - 1| < |x|^2/2 < 2^-54 = ulp(1 - 2^-53)/2.
+ return fputil::round_result_slightly_down(1.0);
+ }
+ // No range reduction needed.
+ k = 0;
+ y.lo = 0.0;
+ y.hi = x;
+ } else {
+ // Small range reduction.
+ k = range_reduction_small(x, y);
+ }
+ } else {
+ // Inf or NaN
+ if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ // cos(+-Inf) = NaN
+ if (xbits.get_mantissa() == 0) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ }
+ return x + FPBits::quiet_nan().get_val();
+ }
+
+ // Large range reduction.
+ k = range_reduction_large.fast(x, y);
+ }
+
+ DoubleDouble sin_y, cos_y;
+
+ [[maybe_unused]] double err =
+ math::sincos_eval_internal::sincos_eval(y, sin_y, cos_y);
+
+ // Look up sin(k * pi/128) and cos(k * pi/128)
+#ifdef LIBC_MATH_HAS_SMALL_TABLES
+ // Memory saving versions. Use 65-entry table.
+ auto get_idx_dd = [](unsigned kk) -> DoubleDouble {
+ unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63);
+ DoubleDouble ans = SIN_K_PI_OVER_128[idx];
+ if (kk & 128) {
+ ans.hi = -ans.hi;
+ ans.lo = -ans.lo;
+ }
+ return ans;
+ };
+ DoubleDouble msin_k = get_idx_dd(k + 128);
+ DoubleDouble cos_k = get_idx_dd(k + 64);
+#else
+ // Fast look up version, but needs 256-entry table.
+ // -sin(k * pi/128) = sin((k + 128) * pi/128)
+ // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128).
+ DoubleDouble msin_k = SIN_K_PI_OVER_128[(k + 128) & 255];
+ DoubleDouble cos_k = SIN_K_PI_OVER_128[(k + 64) & 255];
+#endif // LIBC_MATH_HAS_SMALL_TABLES
+
+ // After range reduction, k = round(x * 128 / pi) and y = x - k * (pi / 128).
+ // So k is an integer and -pi / 256 <= y <= pi / 256.
+ // Then cos(x) = cos((k * pi/128 + y)
+ // = cos(y) * cos(k*pi/128) - sin(y) * sin(k*pi/128)
+ DoubleDouble cos_k_cos_y = fputil::quick_mult(cos_y, cos_k);
+ DoubleDouble msin_k_sin_y = fputil::quick_mult(sin_y, msin_k);
+
+ DoubleDouble rr = fputil::exact_add<false>(cos_k_cos_y.hi, msin_k_sin_y.hi);
+ rr.lo += msin_k_sin_y.lo + cos_k_cos_y.lo;
+
+#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ return rr.hi + rr.lo;
+#else
+ using Float128 = typename fputil::DyadicFloat<128>;
+ double rlp = rr.lo + err;
+ double rlm = rr.lo - err;
+
+ double r_upper = rr.hi + rlp; // (rr.lo + ERR);
+ double r_lower = rr.hi + rlm; // (rr.lo - ERR);
+
+ // Ziv's rounding test.
+ if (LIBC_LIKELY(r_upper == r_lower))
+ return r_upper;
+
+ Float128 u_f128, sin_u, cos_u;
+ if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT))
+ u_f128 = range_reduction_small_f128(x);
+ else
+ u_f128 = range_reduction_large.accurate();
+
+ math::sincos_eval_internal::sincos_eval(u_f128, sin_u, cos_u);
+
+ auto get_sin_k = [](unsigned kk) -> Float128 {
+ unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63);
+ Float128 ans = SIN_K_PI_OVER_128_F128[idx];
+ if (kk & 128)
+ ans.sign = Sign::NEG;
+ return ans;
+ };
+
+ // -sin(k * pi/128) = sin((k + 128) * pi/128)
+ // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128).
+ Float128 msin_k_f128 = get_sin_k(k + 128);
+ Float128 cos_k_f128 = get_sin_k(k + 64);
+
+ // cos(x) = cos((k * pi/128 + u)
+ // = cos(u) * cos(k*pi/128) - sin(u) * sin(k*pi/128)
+ Float128 r = fputil::quick_add(fputil::quick_mul(cos_k_f128, cos_u),
+ fputil::quick_mul(msin_k_f128, sin_u));
+
+ // TODO: Add assertion if Ziv's accuracy tests fail in debug mode.
+ // https://github.com/llvm/llvm-project/issues/96452.
+
+ return static_cast<double>(r);
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_SRC___SUPPORT_MATH_COS_H
diff --git a/libc/src/__support/math/cosf.h b/libc/src/__support/math/cosf.h
new file mode 100644
index 0000000..074be0b
--- /dev/null
+++ b/libc/src/__support/math/cosf.h
@@ -0,0 +1,152 @@
+//===-- Implementation header for cosf --------------------------*- 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 LIBC_SRC___SUPPORT_MATH_COSF_H
+#define LIBC_SRC___SUPPORT_MATH_COSF_H
+
+#include "sincosf_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/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 cosf(float x) {
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Exceptional cases for cosf.
+ constexpr size_t N_EXCEPTS = 6;
+
+ constexpr fputil::ExceptValues<float, N_EXCEPTS> COSF_EXCEPTS{{
+ // (inputs, RZ output, RU offset, RD offset, RN offset)
+ // x = 0x1.64a032p43, cos(x) = 0x1.9d4ba4p-1 (RZ)
+ {0x55325019, 0x3f4ea5d2, 1, 0, 0},
+ // x = 0x1.4555p51, cos(x) = 0x1.115d7cp-1 (RZ)
+ {0x5922aa80, 0x3f08aebe, 1, 0, 1},
+ // x = 0x1.48a858p54, cos(x) = 0x1.f48148p-2 (RZ)
+ {0x5aa4542c, 0x3efa40a4, 1, 0, 0},
+ // x = 0x1.3170fp63, cos(x) = 0x1.fe2976p-1 (RZ)
+ {0x5f18b878, 0x3f7f14bb, 1, 0, 0},
+ // x = 0x1.2b9622p67, cos(x) = 0x1.f0285cp-1 (RZ)
+ {0x6115cb11, 0x3f78142e, 1, 0, 1},
+ // x = 0x1.ddebdep120, cos(x) = 0x1.114438p-1 (RZ)
+ {0x7beef5ef, 0x3f08a21c, 1, 0, 0},
+ }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ using FPBits = typename fputil::FPBits<float>;
+
+ FPBits xbits(x);
+ xbits.set_sign(Sign::POS);
+
+ uint32_t x_abs = xbits.uintval();
+ double xd = static_cast<double>(xbits.get_val());
+
+ // Range reduction:
+ // For |x| > pi/16, we perform range reduction as follows:
+ // Find k and y such that:
+ // x = (k + y) * pi/32
+ // k is an integer
+ // |y| < 0.5
+ // For small range (|x| < 2^45 when FMA instructions are available, 2^22
+ // otherwise), this is done by performing:
+ // k = round(x * 32/pi)
+ // y = x * 32/pi - k
+ // For large range, we will omit all the higher parts of 16/pi such that the
+ // least significant bits of their full products with x are larger than 63,
+ // since cos((k + y + 64*i) * pi/32) = cos(x + i * 2pi) = cos(x).
+ //
+ // When FMA instructions are not available, we store the digits of 32/pi in
+ // chunks of 28-bit precision. This will make sure that the products:
+ // x * THIRTYTWO_OVER_PI_28[i] are all exact.
+ // When FMA instructions are available, we simply store the digits of 32/pi in
+ // chunks of doubles (53-bit of precision).
+ // So when multiplying by the largest values of single precision, the
+ // resulting output should be correct up to 2^(-208 + 128) ~ 2^-80. By the
+ // worst-case analysis of range reduction, |y| >= 2^-38, so this should give
+ // us more than 40 bits of accuracy. For the worst-case estimation of range
+ // reduction, see for instances:
+ // Elementary Functions by J-M. Muller, Chapter 11,
+ // Handbook of Floating-Point Arithmetic by J-M. Muller et. al.,
+ // Chapter 10.2.
+ //
+ // Once k and y are computed, we then deduce the answer by the cosine of sum
+ // formula:
+ // cos(x) = cos((k + y)*pi/32)
+ // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
+ // The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed
+ // and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are
+ // computed using degree-7 and degree-6 minimax polynomials generated by
+ // Sollya respectively.
+
+ // |x| < 0x1.0p-12f
+ if (LIBC_UNLIKELY(x_abs < 0x3980'0000U)) {
+ // When |x| < 2^-12, the relative error of the approximation cos(x) ~ 1
+ // is:
+ // |cos(x) - 1| < |x^2 / 2| = 2^-25 < epsilon(1)/2.
+ // So the correctly rounded values of cos(x) are:
+ // = 1 - eps(x) if rounding mode = FE_TOWARDZERO or FE_DOWWARD,
+ // = 1 otherwise.
+ // To simplify the rounding decision and make it more efficient and to
+ // prevent compiler to perform constant folding, we use
+ // fma(x, -2^-25, 1) instead.
+ // Note: to use the formula 1 - 2^-25*x to decide the correct rounding, we
+ // do need fma(x, -2^-25, 1) 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(xbits.get_val(), -0x1.0p-25f, 1.0f);
+#else
+ return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0));
+#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
+ }
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ if (auto r = COSF_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // x is inf or nan.
+ 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();
+ }
+
+ 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();
+ }
+
+ // Combine the results with the sine of sum formula:
+ // cos(x) = cos((k + y)*pi/32)
+ // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
+ // = cosm1_y * cos_k + sin_y * sin_k
+ // = (cosm1_y * cos_k + cos_k) + sin_y * sin_k
+ double sin_k = 0, cos_k = 0, sin_y = 0, cosm1_y = 0;
+
+ sincosf_eval(xd, x_abs, sin_k, cos_k, sin_y, cosm1_y);
+
+ return static_cast<float>(fputil::multiply_add(
+ sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k)));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_SRC___SUPPORT_MATH_COSF_H
diff --git a/libc/src/__support/math/cosf16.h b/libc/src/__support/math/cosf16.h
new file mode 100644
index 0000000..50c9a8f
--- /dev/null
+++ b/libc/src/__support/math/cosf16.h
@@ -0,0 +1,106 @@
+//===-- Implementation header for cosf16 ------------------------*- 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_COSF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_COSF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "sincosf16_utils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.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/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr float16 cosf16(float16 x) {
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ constexpr size_t N_EXCEPTS = 4;
+
+ constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{
+ // (input, RZ output, RU offset, RD offset, RN offset)
+ {0x2b7c, 0x3bfc, 1, 0, 1},
+ {0x4ac1, 0x38b5, 1, 0, 0},
+ {0x5c49, 0xb8c6, 0, 1, 0},
+ {0x7acc, 0xa474, 0, 1, 0},
+ }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ using namespace sincosf16_internal;
+ using FPBits = fputil::FPBits<float16>;
+ FPBits xbits(x);
+
+ uint16_t x_u = xbits.uintval();
+ uint16_t x_abs = x_u & 0x7fff;
+ float xf = x;
+
+ // Range reduction:
+ // For |x| > pi/32, we perform range reduction as follows:
+ // Find k and y such that:
+ // x = (k + y) * pi/32
+ // k is an integer, |y| < 0.5
+ //
+ // This is done by performing:
+ // k = round(x * 32/pi)
+ // y = x * 32/pi - k
+ //
+ // Once k and y are computed, we then deduce the answer by the cosine of sum
+ // formula:
+ // cos(x) = cos((k + y) * pi/32)
+ // = cos(k * pi/32) * cos(y * pi/32) -
+ // sin(k * pi/32) * sin(y * pi/32)
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ // Handle exceptional values
+ if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ // cos(+/-0) = 1
+ if (LIBC_UNLIKELY(x_abs == 0U))
+ return fputil::cast<float16>(1.0f);
+
+ // cos(+/-inf) = NaN, and cos(NaN) = NaN
+ if (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_inf()) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ }
+
+ return x + FPBits::quiet_nan().get_val();
+ }
+
+ float sin_k = 0.0f, cos_k = 0.0f, sin_y = 0.0f, cosm1_y = 0.0f;
+ sincosf16_eval(xf, sin_k, cos_k, sin_y, cosm1_y);
+ // Since, cosm1_y = cos_y - 1, therefore:
+ // cos(x) = cos_k * cos_y - sin_k * sin_y
+ // = cos_k * (cos_y - 1 + 1) - sin_k * sin_y
+ // = cos_k * cosm1_y - sin_k * sin_y + cos_k
+ return fputil::cast<float16>(fputil::multiply_add(
+ cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k)));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSF16_H
diff --git a/libc/src/__support/math/coshf.h b/libc/src/__support/math/coshf.h
new file mode 100644
index 0000000..0f233b8
--- /dev/null
+++ b/libc/src/__support/math/coshf.h
@@ -0,0 +1,65 @@
+//===-- Implementation header for coshf -------------------------*- 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_COSHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_COSHF_H
+
+#include "sinhfcoshf_utils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/rounding_mode.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 coshf(float x) {
+ using namespace sinhfcoshf_internal;
+ using FPBits = typename fputil::FPBits<float>;
+
+ FPBits xbits(x);
+ xbits.set_sign(Sign::POS);
+ x = xbits.get_val();
+
+ uint32_t x_u = xbits.uintval();
+
+ // When |x| >= 90, or x is inf or nan
+ if (LIBC_UNLIKELY(x_u >= 0x42b4'0000U || x_u <= 0x3280'0000U)) {
+ // |x| <= 2^-26
+ if (x_u <= 0x3280'0000U) {
+ return 1.0f + x;
+ }
+
+ if (xbits.is_inf_or_nan())
+ return x + FPBits::inf().get_val();
+
+ int rounding = fputil::quick_get_round();
+ if (LIBC_UNLIKELY(rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO))
+ return FPBits::max_normal().get_val();
+
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW);
+
+ return x + FPBits::inf().get_val();
+ }
+
+ // TODO: We should be able to reduce the latency and reciprocal throughput
+ // further by using a low degree (maybe 3-7 ?) minimax polynomial for small
+ // but not too small inputs, such as |x| < 2^-2, or |x| < 2^-3.
+
+ // cosh(x) = (e^x + e^(-x)) / 2.
+ return static_cast<float>(exp_pm_eval</*is_sinh*/ false>(x));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF_H
diff --git a/libc/src/__support/math/coshf16.h b/libc/src/__support/math/coshf16.h
new file mode 100644
index 0000000..4c96a78
--- /dev/null
+++ b/libc/src/__support/math/coshf16.h
@@ -0,0 +1,124 @@
+//===-- Implementation header for coshf16 -----------------------*- 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_COSHF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "expxf16_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/rounding_mode.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr float16 coshf16(float16 x) {
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ constexpr fputil::ExceptValues<float16, 9> COSHF16_EXCEPTS_POS = {{
+ // x = 0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
+ {0x29a8U, 0x3c00U, 1U, 0U, 1U},
+ // x = 0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)
+ {0x3e31U, 0x40eaU, 1U, 0U, 0U},
+ // x = 0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)
+ {0x3e65U, 0x4126U, 1U, 0U, 0U},
+ // x = 0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)
+ {0x3ed8U, 0x41b6U, 1U, 0U, 1U},
+ // x = 0x1.aap+1, coshf16(x) = 0x1.be8p+3 (RZ)
+ {0x42a8U, 0x4afaU, 1U, 0U, 1U},
+ // x = 0x1.cc4p+1, coshf16(x) = 0x1.23cp+4 (RZ)
+ {0x4331U, 0x4c8fU, 1U, 0U, 0U},
+ // x = 0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)
+ {0x44a2U, 0x526dU, 1U, 0U, 0U},
+ // x = 0x1.958p+2, coshf16(x) = 0x1.1a4p+8 (RZ)
+ {0x4656U, 0x5c69U, 1U, 0U, 0U},
+ // x = 0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
+ {0x497cU, 0x7715U, 1U, 0U, 1U},
+ }};
+
+ constexpr fputil::ExceptValues<float16, 6> COSHF16_EXCEPTS_NEG = {{
+ // x = -0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
+ {0xa9a8U, 0x3c00U, 1U, 0U, 1U},
+ // x = -0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)
+ {0xbed8U, 0x41b6U, 1U, 0U, 1U},
+ // x = -0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)
+ {0xc4a2U, 0x526dU, 1U, 0U, 0U},
+ // x = -0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
+ {0xc97cU, 0x7715U, 1U, 0U, 1U},
+ // x = -0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)
+ {0xbe31U, 0x40eaU, 1U, 0U, 0U},
+ // x = -0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)
+ {0xbe65U, 0x4126U, 1U, 0U, 0U},
+ }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ using namespace expxf16_internal;
+ using FPBits = fputil::FPBits<float16>;
+ FPBits x_bits(x);
+
+ uint16_t x_u = x_bits.uintval();
+ uint16_t x_abs = x_u & 0x7fffU;
+
+ // When |x| >= acosh(2^16), or x is NaN.
+ if (LIBC_UNLIKELY(x_abs >= 0x49e5U)) {
+ // cosh(NaN) = NaN
+ if (x_bits.is_nan()) {
+ if (x_bits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ return x;
+ }
+
+ // When |x| >= acosh(2^16).
+ if (x_abs >= 0x49e5U) {
+ // cosh(+/-inf) = +inf
+ if (x_bits.is_inf())
+ return FPBits::inf().get_val();
+
+ switch (fputil::quick_get_round()) {
+ case FE_TONEAREST:
+ case FE_UPWARD:
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
+ return FPBits::inf().get_val();
+ default:
+ return FPBits::max_normal().get_val();
+ }
+ }
+ }
+
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ if (x_bits.is_pos()) {
+ if (auto r = COSHF16_EXCEPTS_POS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ } else {
+ if (auto r = COSHF16_EXCEPTS_NEG.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+ return eval_sinh_or_cosh</*IsSinh=*/false>(x);
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H
diff --git a/libc/src/__support/math/cospif.h b/libc/src/__support/math/cospif.h
new file mode 100644
index 0000000..e921090
--- /dev/null
+++ b/libc/src/__support/math/cospif.h
@@ -0,0 +1,109 @@
+//===-- Implementation header for cospif ------------------------*- 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_COSPIF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_COSPIF_H
+
+#include "sincosf_utils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.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/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr float cospif(float x) {
+ using FPBits = typename fputil::FPBits<float>;
+
+ FPBits xbits(x);
+ xbits.set_sign(Sign::POS);
+
+ uint32_t x_abs = xbits.uintval();
+ double xd = static_cast<double>(xbits.get_val());
+
+ // Range reduction:
+ // For |x| > 1/32, we perform range reduction as follows:
+ // Find k and y such that:
+ // x = (k + y) * 1/32
+ // k is an integer
+ // |y| < 0.5
+ //
+ // This is done by performing:
+ // k = round(x * 32)
+ // y = x * 32 - k
+ //
+ // Once k and y are computed, we then deduce the answer by the cosine of sum
+ // formula:
+ // cospi(x) = cos((k + y)*pi/32)
+ // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
+ // The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed
+ // and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are
+ // computed using degree-7 and degree-6 minimax polynomials generated by
+ // Sollya respectively.
+
+ // The exhautive test passes for smaller values
+ if (LIBC_UNLIKELY(x_abs < 0x38A2'F984U)) {
+
+#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT)
+ return fputil::multiply_add(xbits.get_val(), -0x1.0p-25f, 1.0f);
+#else
+ return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0));
+#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
+ }
+
+ // Numbers greater or equal to 2^23 are always integers or NaN
+ if (LIBC_UNLIKELY(x_abs >= 0x4B00'0000)) {
+
+ if (LIBC_UNLIKELY(x_abs < 0x4B80'0000)) {
+ return (x_abs & 0x1) ? -1.0f : 1.0f;
+ }
+
+ // x is inf or nan.
+ 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();
+ }
+
+ 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();
+ }
+
+ return 1.0f;
+ }
+
+ // Combine the results with the sine of sum formula:
+ // cos(pi * x) = cos((k + y)*pi/32)
+ // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
+ // = (cosm1_y + 1) * cos_k - sin_y * sin_k
+ // = (cosm1_y * cos_k + cos_k) - sin_y * sin_k
+ double sin_k = 0, cos_k = 0, sin_y = 0, cosm1_y = 0;
+
+ sincospif_eval(xd, sin_k, cos_k, sin_y, cosm1_y);
+
+ if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) {
+ return 0.0f;
+ }
+
+ return static_cast<float>(fputil::multiply_add(
+ sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k)));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF_H
diff --git a/libc/src/__support/math/cospif16.h b/libc/src/__support/math/cospif16.h
new file mode 100644
index 0000000..d07236c
--- /dev/null
+++ b/libc/src/__support/math/cospif16.h
@@ -0,0 +1,99 @@
+//===-- Implementation header for cospif16 ----------------------*- 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_COSPIF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_COSPIF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "sincosf16_utils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE static constexpr float16 cospif16(float16 x) {
+
+ using namespace sincosf16_internal;
+ using FPBits = typename fputil::FPBits<float16>;
+ FPBits xbits(x);
+
+ uint16_t x_u = xbits.uintval();
+ uint16_t x_abs = x_u & 0x7fff;
+ float xf = x;
+
+ // Range reduction:
+ // For |x| > 1/32, we perform range reduction as follows:
+ // Find k and y such that:
+ // x = (k + y) * 1/32
+ // k is an integer
+ // |y| < 0.5
+ //
+ // This is done by performing:
+ // k = round(x * 32)
+ // y = x * 32 - k
+ //
+ // Once k and y are computed, we then deduce the answer by the cosine of sum
+ // formula:
+ // cos(x * pi) = cos((k + y) * pi/32)
+ // = cos(k * pi/32) * cos(y * pi/32) +
+ // sin(y * pi/32) * sin(k * pi/32)
+
+ // For signed zeros
+ if (LIBC_UNLIKELY(x_abs == 0U))
+ return fputil::cast<float16>(1.0f);
+
+ // Numbers greater or equal to 2^10 are integers, or infinity, or NaN
+ if (LIBC_UNLIKELY(x_abs >= 0x6400)) {
+ if (LIBC_UNLIKELY(x_abs <= 0x67FF))
+ return fputil::cast<float16>((x_abs & 0x1) ? -1.0f : 1.0f);
+
+ // Check for NaN or infintiy values
+ if (LIBC_UNLIKELY(x_abs >= 0x7c00)) {
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ // If value is equal to infinity
+ if (x_abs == 0x7c00) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ }
+
+ return x + FPBits::quiet_nan().get_val();
+ }
+
+ return fputil::cast<float16>(1.0f);
+ }
+
+ float sin_k = 0, cos_k = 0, sin_y = 0, cosm1_y = 0;
+ sincospif16_eval(xf, sin_k, cos_k, sin_y, cosm1_y);
+
+ if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0))
+ return fputil::cast<float16>(0.0f);
+
+ // Since, cosm1_y = cos_y - 1, therefore:
+ // cos(x * pi) = cos_k(cosm1_y) + cos_k - sin_k * sin_y
+ return fputil::cast<float16>(fputil::multiply_add(
+ cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k)));
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_COSHF16_H
diff --git a/libc/src/math/generic/expxf16.h b/libc/src/__support/math/expxf16_utils.h
index 562a427..5d3bd38 100644
--- a/libc/src/math/generic/expxf16.h
+++ b/libc/src/__support/math/expxf16_utils.h
@@ -21,7 +21,11 @@
namespace LIBC_NAMESPACE_DECL {
-LIBC_INLINE ExpRangeReduction exp2_range_reduction(float16 x) {
+namespace math {
+
+namespace expxf16_internal {
+
+LIBC_INLINE static ExpRangeReduction exp2_range_reduction(float16 x) {
// For -25 < x < 16, to compute 2^x, we perform the following range reduction:
// find hi, mid, lo, such that:
// x = hi + mid + lo, in which
@@ -117,7 +121,8 @@ static constexpr cpp::array<uint32_t, 32> EXP2_MID_5_BITS = {
// The main point of these formulas is that the expensive part of calculating
// the polynomials approximating lower parts of e^x and e^(-x) is shared and
// only done once.
-template <bool IsSinh> LIBC_INLINE float16 eval_sinh_or_cosh(float16 x) {
+template <bool IsSinh>
+LIBC_INLINE static constexpr float16 eval_sinh_or_cosh(float16 x) {
float xf = x;
float kf = fputil::nearest_integer(xf * (LOG2F_E * 0x1.0p+5f));
int x_hi_mid_p = static_cast<int>(kf);
@@ -174,7 +179,7 @@ template <bool IsSinh> LIBC_INLINE float16 eval_sinh_or_cosh(float16 x) {
// Generated by Sollya with the following commands:
// > display = hexadecimal;
// > for i from 0 to 31 do print(round(log(1 + i * 2^-5), SG, RN));
-constexpr cpp::array<float, 32> LOGF_F = {
+static constexpr cpp::array<float, 32> LOGF_F = {
0x0p+0f, 0x1.f829bp-6f, 0x1.f0a30cp-5f, 0x1.6f0d28p-4f,
0x1.e27076p-4f, 0x1.29553p-3f, 0x1.5ff308p-3f, 0x1.9525aap-3f,
0x1.c8ff7cp-3f, 0x1.fb9186p-3f, 0x1.1675cap-2f, 0x1.2e8e2cp-2f,
@@ -188,7 +193,7 @@ constexpr cpp::array<float, 32> LOGF_F = {
// Generated by Sollya with the following commands:
// > display = hexadecimal;
// > for i from 0 to 31 do print(round(log2(1 + i * 2^-5), SG, RN));
-constexpr cpp::array<float, 32> LOG2F_F = {
+static constexpr cpp::array<float, 32> LOG2F_F = {
0x0p+0f, 0x1.6bad38p-5f, 0x1.663f7p-4f, 0x1.08c588p-3f,
0x1.5c01a4p-3f, 0x1.acf5e2p-3f, 0x1.fbc16cp-3f, 0x1.24407ap-2f,
0x1.49a784p-2f, 0x1.6e221cp-2f, 0x1.91bba8p-2f, 0x1.b47ecp-2f,
@@ -202,7 +207,7 @@ constexpr cpp::array<float, 32> LOG2F_F = {
// Generated by Sollya with the following commands:
// > display = hexadecimal;
// > for i from 0 to 31 do print(round(log10(1 + i * 2^-5), SG, RN));
-constexpr cpp::array<float, 32> LOG10F_F = {
+static constexpr cpp::array<float, 32> LOG10F_F = {
0x0p+0f, 0x1.b5e908p-7f, 0x1.af5f92p-6f, 0x1.3ed11ap-5f,
0x1.a30a9ep-5f, 0x1.02428cp-4f, 0x1.31b306p-4f, 0x1.5fe804p-4f,
0x1.8cf184p-4f, 0x1.b8de4ep-4f, 0x1.e3bc1ap-4f, 0x1.06cbd6p-3f,
@@ -216,7 +221,7 @@ constexpr cpp::array<float, 32> LOG10F_F = {
// Generated by Sollya with the following commands:
// > display = hexadecimal;
// > for i from 0 to 31 do print(round(1 / (1 + i * 2^-5), SG, RN));
-constexpr cpp::array<float, 32> ONE_OVER_F_F = {
+static constexpr cpp::array<float, 32> ONE_OVER_F_F = {
0x1p+0f, 0x1.f07c2p-1f, 0x1.e1e1e2p-1f, 0x1.d41d42p-1f,
0x1.c71c72p-1f, 0x1.bacf92p-1f, 0x1.af286cp-1f, 0x1.a41a42p-1f,
0x1.99999ap-1f, 0x1.8f9c18p-1f, 0x1.861862p-1f, 0x1.7d05f4p-1f,
@@ -227,6 +232,10 @@ constexpr cpp::array<float, 32> ONE_OVER_F_F = {
0x1.111112p-1f, 0x1.0c9714p-1f, 0x1.08421p-1f, 0x1.041042p-1f,
};
+} // namespace expxf16_internal
+
+} // namespace math
+
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_MATH_GENERIC_EXPXF16_H
diff --git a/libc/src/math/generic/range_reduction.h b/libc/src/__support/math/range_reduction.h
index 9ea446d..e3f25e4 100644
--- a/libc/src/math/generic/range_reduction.h
+++ b/libc/src/__support/math/range_reduction.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_H
+#ifndef LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_H
+#define LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_H
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/multiply_add.h"
@@ -87,4 +87,4 @@ LIBC_INLINE int64_t large_range_reduction(double x, int x_exp, double &y) {
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_H
+#endif // LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_H
diff --git a/libc/src/math/generic/range_reduction_double_common.h b/libc/src/__support/math/range_reduction_double_common.h
index a93ee25..a12c25d 100644
--- a/libc/src/math/generic/range_reduction_double_common.h
+++ b/libc/src/__support/math/range_reduction_double_common.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_COMMON_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_COMMON_H
#include "src/__support/FPUtil/double_double.h"
#include "src/__support/FPUtil/dyadic_float.h"
@@ -20,6 +20,10 @@
namespace LIBC_NAMESPACE_DECL {
+namespace math {
+
+namespace range_reduction_double_internal {
+
#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
static constexpr unsigned SPLIT = fputil::DefaultSplit<double>::VALUE;
#else
@@ -40,7 +44,7 @@ using Float128 = LIBC_NAMESPACE::fputil::DyadicFloat<128>;
// Error bound:
// |(x - k * pi/128) - (u_hi + u_lo)| <= max(ulp(ulp(u_hi)), 2^-119)
// <= 2^-111.
-LIBC_INLINE unsigned range_reduction_small(double x, DoubleDouble &u) {
+LIBC_INLINE static unsigned range_reduction_small(double x, DoubleDouble &u) {
// Values of -pi/128 used for inputs with absolute value <= 2^16.
// The first 3 parts are generated with (53 - 21 = 32)-bit precision, so that
// the product k * MPI_OVER_128[i] is exact.
@@ -267,13 +271,15 @@ struct LargeRangeReduction {
}
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+ LIBC_INLINE LargeRangeReduction() = default;
+
private:
// Index of x in the look-up table ONE_TWENTY_EIGHT_OVER_PI.
- unsigned idx;
+ unsigned idx = 0;
// x scaled down by 2^(-16 *(idx - 3))).
- double x_reduced;
+ double x_reduced = 0;
// Parts of (x * 128/pi) mod 1.
- double y_hi, y_lo;
+ double y_hi = 0, y_lo = 0;
DoubleDouble y_mid;
};
@@ -369,6 +375,10 @@ static constexpr Float128 SIN_K_PI_OVER_128_F128[65] = {
};
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+} // namespace range_reduction_double_internal
+
+} // namespace math
+
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_COMMON_H
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_COMMON_H
diff --git a/libc/src/math/generic/range_reduction_double_fma.h b/libc/src/__support/math/range_reduction_double_fma.h
index 160fb24..7fa3e40 100644
--- a/libc/src/math/generic/range_reduction_double_fma.h
+++ b/libc/src/__support/math/range_reduction_double_fma.h
@@ -6,20 +6,22 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_FMA_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_FMA_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_FMA_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_FMA_H
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/double_double.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/FPUtil/nearest_integer.h"
-#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h"
-#include "src/math/generic/range_reduction_double_common.h"
+#include "src/__support/math/range_reduction_double_common.h"
namespace LIBC_NAMESPACE_DECL {
+namespace math {
+
+namespace range_reduction_double_internal {
+
using LIBC_NAMESPACE::fputil::DoubleDouble;
LIBC_INLINE unsigned LargeRangeReduction::fast(double x, DoubleDouble &u) {
@@ -341,6 +343,10 @@ LIBC_INLINE constexpr DoubleDouble SIN_K_PI_OVER_128[] = {
#endif // !LIBC_MATH_HAS_SMALL_TABLES
};
+} // namespace range_reduction_double_internal
+
+} // namespace math
+
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_FMA_H
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_FMA_H
diff --git a/libc/src/math/generic/range_reduction_double_nofma.h b/libc/src/__support/math/range_reduction_double_nofma.h
index 9d13d24..3990b9b 100644
--- a/libc/src/math/generic/range_reduction_double_nofma.h
+++ b/libc/src/__support/math/range_reduction_double_nofma.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_NOFMA_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_NOFMA_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_NOFMA_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_NOFMA_H
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/double_double.h"
@@ -16,10 +16,14 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
-#include "src/math/generic/range_reduction_double_common.h"
+#include "src/__support/math/range_reduction_double_common.h"
namespace LIBC_NAMESPACE_DECL {
+namespace math {
+
+namespace range_reduction_double_internal {
+
using fputil::DoubleDouble;
LIBC_INLINE unsigned LargeRangeReduction::fast(double x, DoubleDouble &u) {
@@ -342,6 +346,10 @@ LIBC_INLINE constexpr DoubleDouble SIN_K_PI_OVER_128[] = {
#endif // !LIBC_MATH_HAS_SMALL_TABLES
};
+} // namespace range_reduction_double_internal
+
+} // namespace math
+
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_DOUBLE_NOFMA_H
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_DOUBLE_NOFMA_H
diff --git a/libc/src/math/generic/range_reduction_fma.h b/libc/src/__support/math/range_reduction_fma.h
index 537d572..c06a1d8 100644
--- a/libc/src/math/generic/range_reduction_fma.h
+++ b/libc/src/__support/math/range_reduction_fma.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_FMA_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_FMA_H
+#ifndef LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_FMA_H
+#define LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_FMA_H
#include "src/__support/FPUtil/FMA.h"
#include "src/__support/FPUtil/FPBits.h"
@@ -89,4 +89,4 @@ LIBC_INLINE int64_t large_range_reduction(double x, int x_exp, double &y) {
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_RANGE_REDUCTION_FMA_H
+#endif // LIBC_SRC___SUPPORT_MATH_RANGE_REDUCTION_FMA_H
diff --git a/libc/src/math/generic/sincos_eval.h b/libc/src/__support/math/sincos_eval.h
index 41a4c75..fc741af 100644
--- a/libc/src/math/generic/sincos_eval.h
+++ b/libc/src/__support/math/sincos_eval.h
@@ -18,7 +18,9 @@
namespace LIBC_NAMESPACE_DECL {
-namespace generic {
+namespace math {
+
+namespace sincos_eval_internal {
using fputil::DoubleDouble;
using Float128 = fputil::DyadicFloat<128>;
@@ -131,7 +133,9 @@ LIBC_INLINE void sincos_eval(const Float128 &u, Float128 &sin_u,
COS_COEFFS[6]);
}
-} // namespace generic
+} // namespace sincos_eval_internal
+
+} // namespace math
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/sincosf16_utils.h b/libc/src/__support/math/sincosf16_utils.h
index 05cab09d..74f21fd 100644
--- a/libc/src/math/generic/sincosf16_utils.h
+++ b/libc/src/__support/math/sincosf16_utils.h
@@ -16,6 +16,8 @@
namespace LIBC_NAMESPACE_DECL {
+namespace sincosf16_internal {
+
// Lookup table for sin(k * pi / 32) with k = 0, ..., 63.
// Table is generated with Sollya as follows:
// > display = hexadecimmal;
@@ -66,7 +68,7 @@ LIBC_INLINE int32_t range_reduction_sincosf16(float x, float &y) {
return static_cast<int32_t>(kd);
}
-static LIBC_INLINE void sincosf16_poly_eval(int32_t k, float y, float &sin_k,
+LIBC_INLINE static void sincosf16_poly_eval(int32_t k, float y, float &sin_k,
float &cos_k, float &sin_y,
float &cosm1_y) {
@@ -107,6 +109,8 @@ LIBC_INLINE void sincospif16_eval(float xf, float &sin_k, float &cos_k,
sincosf16_poly_eval(k, y, sin_k, cos_k, sin_y, cosm1_y);
}
+} // namespace sincosf16_internal
+
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC_MATH_GENERIC_SINCOSF16_UTILS_H
diff --git a/libc/src/math/generic/sincosf_utils.h b/libc/src/__support/math/sincosf_utils.h
index 6eaf820..ed9d9f6 100644
--- a/libc/src/math/generic/sincosf_utils.h
+++ b/libc/src/__support/math/sincosf_utils.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GENERIC_SINCOSF_UTILS_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_SINCOSF_UTILS_H
+#ifndef LIBC_SRC___SUPPORT_MATH_SINCOSF_UTILS_H
+#define LIBC_SRC___SUPPORT_MATH_SINCOSF_UTILS_H
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -122,4 +122,4 @@ LIBC_INLINE void sincospif_eval(double xd, double &sin_k, double &cos_k,
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_SINCOSF_UTILS_H
+#endif // LIBC_SRC___SUPPORT_MATH_SINCOSF_UTILS_H
diff --git a/libc/src/math/generic/explogxf.h b/libc/src/__support/math/sinhfcoshf_utils.h
index 72f8da8..5f19b81 100644
--- a/libc/src/math/generic/explogxf.h
+++ b/libc/src/__support/math/sinhfcoshf_utils.h
@@ -1,4 +1,4 @@
-//===-- Single-precision general exp/log functions ------------------------===//
+//===-- Single-precision general sinhf/coshf 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,21 +6,17 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_MATH_GENERIC_EXPLOGXF_H
-#define LLVM_LIBC_SRC_MATH_GENERIC_EXPLOGXF_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_SINHFCOSHF_UTILS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_SINHFCOSHF_UTILS_H
-#include "common_constants.h"
-
-#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"
+#include "exp10f_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
namespace LIBC_NAMESPACE_DECL {
-constexpr int LOG_P1_BITS = 6;
-constexpr int LOG_P1_SIZE = 1 << LOG_P1_BITS;
+namespace math {
+
+namespace sinhfcoshf_internal {
// The function correctly calculates sinh(x) and cosh(x) by calculating exp(x)
// and exp(-x) simultaneously.
@@ -121,6 +117,10 @@ template <bool is_sinh> LIBC_INLINE double exp_pm_eval(float x) {
return r;
}
+} // namespace sinhfcoshf_internal
+
+} // namespace math
+
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC_MATH_GENERIC_EXPLOGXF_H
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_SINHFCOSHF_UTILS_H
diff --git a/libc/src/__support/math_extras.h b/libc/src/__support/math_extras.h
index 47df2a4..954bcb1b 100644
--- a/libc/src/__support/math_extras.h
+++ b/libc/src/__support/math_extras.h
@@ -66,7 +66,7 @@ template <typename T>
#define RETURN_IF(TYPE, BUILTIN) \
if constexpr (cpp::is_same_v<T, TYPE>) \
- return BUILTIN(a, b, carry_in, carry_out);
+ return BUILTIN(a, b, carry_in, &carry_out);
// Returns the result of 'a + b' taking into account 'carry_in'.
// The carry out is stored in 'carry_out' it not 'nullptr', dropped otherwise.
@@ -74,7 +74,7 @@ template <typename T>
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
add_with_carry(T a, T b, T carry_in, T &carry_out) {
- if constexpr (!cpp::is_constant_evaluated()) {
+ if (!cpp::is_constant_evaluated()) {
#if __has_builtin(__builtin_addcb)
RETURN_IF(unsigned char, __builtin_addcb)
#elif __has_builtin(__builtin_addcs)
@@ -100,7 +100,7 @@ add_with_carry(T a, T b, T carry_in, T &carry_out) {
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
sub_with_borrow(T a, T b, T carry_in, T &carry_out) {
- if constexpr (!cpp::is_constant_evaluated()) {
+ if (!cpp::is_constant_evaluated()) {
#if __has_builtin(__builtin_subcb)
RETURN_IF(unsigned char, __builtin_subcb)
#elif __has_builtin(__builtin_subcs)
diff --git a/libc/src/__support/threads/linux/barrier.h b/libc/src/__support/threads/linux/barrier.h
index f0655bf..a632aa4 100644
--- a/libc/src/__support/threads/linux/barrier.h
+++ b/libc/src/__support/threads/linux/barrier.h
@@ -36,14 +36,19 @@ public:
int wait();
};
-static_assert(
- sizeof(Barrier) == sizeof(pthread_barrier_t),
- "The public pthread_barrier_t type cannot accommodate the internal "
- "barrier type.");
-
-static_assert(alignof(Barrier) == alignof(pthread_barrier_t),
- "The public pthread_barrier_t type has a different alignment "
- "than the internal barrier type.");
+static_assert(sizeof(Barrier) <= sizeof(pthread_barrier_t),
+ "The public pthread_barrier_t type cannot accommodate the "
+ "internal barrier type.");
+
+static_assert(alignof(Barrier) <= alignof(pthread_barrier_t),
+ "The public pthread_barrier_t type has insufficient alignment "
+ "for the internal barrier type.");
+
+static_assert(sizeof(CndVar) <= 24,
+ "CndVar size exceeds the size in __barrier_type.h");
+
+static_assert(sizeof(Mutex) <= 24,
+ "Mutex size exceeds the size in __barrier_type.h");
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/threads/mutex.h b/libc/src/__support/threads/mutex.h
index cbef0d0..f64f7e7 100644
--- a/libc/src/__support/threads/mutex.h
+++ b/libc/src/__support/threads/mutex.h
@@ -12,28 +12,6 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
-// Uses the platform specific specialization
-#define LIBC_THREAD_MODE_PLATFORM 0
-
-// Mutex guards nothing, used in single-threaded implementations
-#define LIBC_THREAD_MODE_SINGLE 1
-
-// Vendor provides implementation
-#define LIBC_THREAD_MODE_EXTERNAL 2
-
-#if !defined(LIBC_THREAD_MODE)
-#error LIBC_THREAD_MODE is undefined
-#endif // LIBC_THREAD_MODE
-
-#if LIBC_THREAD_MODE != LIBC_THREAD_MODE_PLATFORM && \
- LIBC_THREAD_MODE != LIBC_THREAD_MODE_SINGLE && \
- LIBC_THREAD_MODE != LIBC_THREAD_MODE_EXTERNAL
-#error LIBC_THREAD_MODE must be one of the following values: \
-LIBC_THREAD_MODE_PLATFORM, \
-LIBC_THREAD_MODE_SINGLE, \
-LIBC_THREAD_MODE_EXTERNAL.
-#endif
-
#if LIBC_THREAD_MODE == LIBC_THREAD_MODE_PLATFORM
// Platform independent code will include this header file which pulls
diff --git a/libc/src/__support/threads/thread.cpp b/libc/src/__support/threads/thread.cpp
index 6f6b75b..9618d78 100644
--- a/libc/src/__support/threads/thread.cpp
+++ b/libc/src/__support/threads/thread.cpp
@@ -163,6 +163,8 @@ void call_atexit_callbacks(ThreadAttributes *attrib) {
}
}
+extern "C" void __cxa_thread_finalize() { call_atexit_callbacks(self.attrib); }
+
} // namespace internal
cpp::optional<unsigned int> new_tss_key(TSSDtor *dtor) {
diff --git a/libc/src/__support/threads/thread.h b/libc/src/__support/threads/thread.h
index 114ab49..6806098 100644
--- a/libc/src/__support/threads/thread.h
+++ b/libc/src/__support/threads/thread.h
@@ -110,7 +110,7 @@ struct alignas(STACK_ALIGNMENT) ThreadAttributes {
ThreadAtExitCallbackMgr *atexit_callback_mgr;
void *platform_data;
- constexpr ThreadAttributes()
+ LIBC_INLINE constexpr ThreadAttributes()
: detach_state(uint32_t(DetachState::DETACHED)), stack(nullptr),
stacksize(0), guardsize(0), tls(0), tls_size(0), owned_stack(false),
tid(-1), style(ThreadStyle::POSIX), retval(),
diff --git a/libc/src/__support/wchar/character_converter.cpp b/libc/src/__support/wchar/character_converter.cpp
index 15d0f47..2667288 100644
--- a/libc/src/__support/wchar/character_converter.cpp
+++ b/libc/src/__support/wchar/character_converter.cpp
@@ -132,12 +132,6 @@ ErrorOr<char32_t> CharacterConverter::pop_utf32() {
return utf32;
}
-size_t CharacterConverter::sizeAsUTF32() {
- return 1; // a single utf-32 value can fit an entire character
-}
-
-size_t CharacterConverter::sizeAsUTF8() { return state->total_bytes; }
-
ErrorOr<char8_t> CharacterConverter::pop_utf8() {
if (isEmpty())
return Error(-1);
@@ -170,5 +164,13 @@ ErrorOr<char8_t> CharacterConverter::pop_utf8() {
return static_cast<char8_t>(output);
}
+template <> ErrorOr<char8_t> CharacterConverter::pop() { return pop_utf8(); }
+template <> ErrorOr<char32_t> CharacterConverter::pop() { return pop_utf32(); }
+
+template <> size_t CharacterConverter::sizeAs<char8_t>() {
+ return state->total_bytes;
+}
+template <> size_t CharacterConverter::sizeAs<char32_t>() { return 1; }
+
} // namespace internal
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/wchar/character_converter.h b/libc/src/__support/wchar/character_converter.h
index b6d918f..2cc28ab 100644
--- a/libc/src/__support/wchar/character_converter.h
+++ b/libc/src/__support/wchar/character_converter.h
@@ -12,6 +12,7 @@
#include "hdr/types/char32_t.h"
#include "hdr/types/char8_t.h"
#include "hdr/types/size_t.h"
+#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/wchar/mbstate.h"
@@ -31,14 +32,14 @@ public:
bool isEmpty();
bool isValidState();
- size_t sizeAsUTF32();
- size_t sizeAsUTF8();
+ template <typename CharType> size_t sizeAs();
int push(char8_t utf8_byte);
int push(char32_t utf32);
ErrorOr<char8_t> pop_utf8();
ErrorOr<char32_t> pop_utf32();
+ template <typename CharType> ErrorOr<CharType> pop();
};
} // namespace internal
diff --git a/libc/src/__support/wchar/mbrtowc.cpp b/libc/src/__support/wchar/mbrtowc.cpp
index 0f730d6..66cc68e 100644
--- a/libc/src/__support/wchar/mbrtowc.cpp
+++ b/libc/src/__support/wchar/mbrtowc.cpp
@@ -8,7 +8,6 @@
#include "src/__support/wchar/mbrtowc.h"
#include "hdr/errno_macros.h"
-#include "hdr/types/mbstate_t.h"
#include "hdr/types/size_t.h"
#include "hdr/types/wchar_t.h"
#include "src/__support/common.h"
diff --git a/libc/src/__support/wchar/mbsnrtowcs.h b/libc/src/__support/wchar/mbsnrtowcs.h
index 54e3152..6abb836 100644
--- a/libc/src/__support/wchar/mbsnrtowcs.h
+++ b/libc/src/__support/wchar/mbsnrtowcs.h
@@ -36,7 +36,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst,
StringConverter<char8_t> str_conv(reinterpret_cast<const char8_t *>(*src), ps,
len, nmc);
size_t dst_idx = 0;
- ErrorOr<char32_t> converted = str_conv.popUTF32();
+ ErrorOr<char32_t> converted = str_conv.pop<char32_t>();
while (converted.has_value()) {
if (dst != nullptr)
dst[dst_idx] = converted.value();
@@ -47,7 +47,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst,
return dst_idx;
}
dst_idx++;
- converted = str_conv.popUTF32();
+ converted = str_conv.pop<char32_t>();
}
if (converted.error() == -1) { // if we hit conversion limit
diff --git a/libc/src/__support/wchar/string_converter.h b/libc/src/__support/wchar/string_converter.h
index 869ebdf..ba628bd 100644
--- a/libc/src/__support/wchar/string_converter.h
+++ b/libc/src/__support/wchar/string_converter.h
@@ -12,6 +12,7 @@
#include "hdr/types/char32_t.h"
#include "hdr/types/char8_t.h"
#include "hdr/types/size_t.h"
+#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/wchar/character_converter.h"
@@ -53,9 +54,7 @@ public:
size_t srclen = SIZE_MAX)
: cr(ps), src(s), src_len(srclen), src_idx(0), num_to_write(dstlen) {}
- // TODO: following functions are almost identical
- // look into templating CharacterConverter pop functions
- ErrorOr<char32_t> popUTF32() {
+ template <typename CharType> ErrorOr<CharType> pop() {
if (num_to_write == 0)
return Error(-1);
@@ -64,7 +63,7 @@ public:
if (!src_elements_read.has_value())
return Error(src_elements_read.error());
- if (cr.sizeAsUTF32() > num_to_write) {
+ if (cr.sizeAs<CharType>() > num_to_write) {
cr.clear();
return Error(-1);
}
@@ -72,34 +71,9 @@ public:
src_idx += src_elements_read.value();
}
- auto out = cr.pop_utf32();
- if (out.has_value() && out.value() == L'\0')
- src_len = src_idx;
-
- num_to_write--;
-
- return out;
- }
-
- ErrorOr<char8_t> popUTF8() {
- if (num_to_write == 0)
- return Error(-1);
-
- if (cr.isEmpty() || src_idx == 0) {
- auto src_elements_read = pushFullCharacter();
- if (!src_elements_read.has_value())
- return Error(src_elements_read.error());
-
- if (cr.sizeAsUTF8() > num_to_write) {
- cr.clear();
- return Error(-1);
- }
-
- src_idx += src_elements_read.value();
- }
-
- auto out = cr.pop_utf8();
- if (out.has_value() && out.value() == '\0')
+ ErrorOr<CharType> out = cr.pop<CharType>();
+ // if out isn't null terminator or an error
+ if (out.has_value() && out.value() == 0)
src_len = src_idx;
num_to_write--;
diff --git a/libc/src/__support/wchar/wcsnrtombs.h b/libc/src/__support/wchar/wcsnrtombs.h
index 433097c..f593a0e 100644
--- a/libc/src/__support/wchar/wcsnrtombs.h
+++ b/libc/src/__support/wchar/wcsnrtombs.h
@@ -39,7 +39,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src,
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();
+ ErrorOr<char8_t> converted = str_conv.pop<char8_t>();
while (converted.has_value()) {
if (dest != nullptr)
dest[dst_idx] = converted.value();
@@ -51,7 +51,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src,
}
dst_idx++;
- converted = str_conv.popUTF8();
+ converted = str_conv.pop<char8_t>();
}
if (dest != nullptr)
diff --git a/libc/src/dlfcn/CMakeLists.txt b/libc/src/dlfcn/CMakeLists.txt
index e3a51ba..876d915 100644
--- a/libc/src/dlfcn/CMakeLists.txt
+++ b/libc/src/dlfcn/CMakeLists.txt
@@ -14,7 +14,6 @@ add_entrypoint_object(
dlerror.h
DEPENDS
libc.include.dlfcn
- libc.src.errno.errno
)
add_entrypoint_object(
@@ -25,7 +24,6 @@ add_entrypoint_object(
dlopen.h
DEPENDS
libc.include.dlfcn
- libc.src.errno.errno
)
add_entrypoint_object(
@@ -36,5 +34,25 @@ add_entrypoint_object(
dlsym.h
DEPENDS
libc.include.dlfcn
- libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ dlinfo
+ SRCS
+ dlinfo.cpp
+ HDRS
+ dlinfo.h
+ DEPENDS
+ libc.include.dlfcn
+)
+
+add_entrypoint_object(
+ dladdr
+ SRCS
+ dladdr.cpp
+ HDRS
+ dladdr.h
+ DEPENDS
+ libc.include.dlfcn
+ libc.hdr.types.dl_info
)
diff --git a/libc/src/dlfcn/dladdr.cpp b/libc/src/dlfcn/dladdr.cpp
new file mode 100644
index 0000000..7e2a154
--- /dev/null
+++ b/libc/src/dlfcn/dladdr.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of dladdr ------------------------------------------===//
+//
+// 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 "dladdr.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// TODO: https:// github.com/llvm/llvm-project/issues/97929
+LLVM_LIBC_FUNCTION(int, dladdr,
+ ([[maybe_unused]] const void *__restrict addr,
+ [[maybe_unused]] Dl_info *__restrict info)) {
+ return -1;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/dlfcn/dladdr.h b/libc/src/dlfcn/dladdr.h
new file mode 100644
index 0000000..1fabe81
--- /dev/null
+++ b/libc/src/dlfcn/dladdr.h
@@ -0,0 +1,22 @@
+//===-- Implementation header of dladdr -------------------------*- 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_DLFCN_DLADDR_H
+#define LLVM_LIBC_SRC_DLFCN_DLADDR_H
+
+#include "src/__support/macros/config.h"
+
+#include "hdr/types/dl_info.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int dladdr(const void *__restrict, Dl_info *__restrict);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_DLFCN_DLADDR_H
diff --git a/libc/src/dlfcn/dlinfo.cpp b/libc/src/dlfcn/dlinfo.cpp
new file mode 100644
index 0000000..e1938d1
--- /dev/null
+++ b/libc/src/dlfcn/dlinfo.cpp
@@ -0,0 +1,24 @@
+
+//===-- Implementation of dlinfo ------------------------------------------===//
+//
+// 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 "dlinfo.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// TODO: https://github.com/llvm/llvm-project/issues/149911
+LLVM_LIBC_FUNCTION(int, dlinfo,
+ (void *__restrict handle, int request,
+ void *__restrict info)) {
+ return -1;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/dlfcn/dlinfo.h b/libc/src/dlfcn/dlinfo.h
new file mode 100644
index 0000000..bc13152
--- /dev/null
+++ b/libc/src/dlfcn/dlinfo.h
@@ -0,0 +1,20 @@
+//===-- Implementation header of dlinfo -------------------------*- 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_DLFCN_DLINFO_H
+#define LLVM_LIBC_SRC_DLFCN_DLINFO_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int dlinfo(void *__restrict, int, void *__restrict);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_DLFCN_DLINFO_H
diff --git a/libc/src/dlfcn/dlsym.cpp b/libc/src/dlfcn/dlsym.cpp
index c075c20..dc0da7d 100644
--- a/libc/src/dlfcn/dlsym.cpp
+++ b/libc/src/dlfcn/dlsym.cpp
@@ -14,6 +14,8 @@
namespace LIBC_NAMESPACE_DECL {
// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97920
-LLVM_LIBC_FUNCTION(void *, dlsym, (void *, const char *)) { return nullptr; }
+LLVM_LIBC_FUNCTION(void *, dlsym, (void *__restrict, const char *__restrict)) {
+ return nullptr;
+}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/dlfcn/dlsym.h b/libc/src/dlfcn/dlsym.h
index 70c6ab3..f879792 100644
--- a/libc/src/dlfcn/dlsym.h
+++ b/libc/src/dlfcn/dlsym.h
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE_DECL {
-void *dlsym(void *, const char *);
+void *dlsym(void *__restrict, const char *__restrict);
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/errno/libc_errno.cpp b/libc/src/errno/libc_errno.cpp
index 8ff1eec..e8960fc 100644
--- a/libc/src/errno/libc_errno.cpp
+++ b/libc/src/errno/libc_errno.cpp
@@ -46,11 +46,6 @@ Errno::operator int() { return shared_errno; }
void Errno::operator=(int a) { *__llvm_libc_errno() = a; }
Errno::operator int() { return *__llvm_libc_errno(); }
-#elif LIBC_ERRNO_MODE == LIBC_ERRNO_MODE_SYSTEM
-
-void Errno::operator=(int a) { errno = a; }
-Errno::operator int() { return errno; }
-
#endif
// Define the global `libc_errno` instance.
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 0522e0e..3e7d9ec 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -58,6 +58,8 @@ add_math_entrypoint_object(asinh)
add_math_entrypoint_object(asinhf)
add_math_entrypoint_object(asinhf16)
+add_math_entrypoint_object(asinpif16)
+
add_math_entrypoint_object(atan)
add_math_entrypoint_object(atanf)
add_math_entrypoint_object(atanf16)
@@ -71,17 +73,21 @@ add_math_entrypoint_object(atanh)
add_math_entrypoint_object(atanhf)
add_math_entrypoint_object(atanhf16)
+add_math_entrypoint_object(atanpif16)
+
add_math_entrypoint_object(canonicalize)
add_math_entrypoint_object(canonicalizef)
add_math_entrypoint_object(canonicalizel)
add_math_entrypoint_object(canonicalizef16)
add_math_entrypoint_object(canonicalizef128)
+add_math_entrypoint_object(canonicalizebf16)
add_math_entrypoint_object(iscanonical)
add_math_entrypoint_object(iscanonicalf)
add_math_entrypoint_object(iscanonicall)
add_math_entrypoint_object(iscanonicalf16)
add_math_entrypoint_object(iscanonicalf128)
+add_math_entrypoint_object(iscanonicalbf16)
add_math_entrypoint_object(cbrt)
add_math_entrypoint_object(cbrtf)
@@ -91,12 +97,14 @@ add_math_entrypoint_object(ceilf)
add_math_entrypoint_object(ceill)
add_math_entrypoint_object(ceilf16)
add_math_entrypoint_object(ceilf128)
+add_math_entrypoint_object(ceilbf16)
add_math_entrypoint_object(copysign)
add_math_entrypoint_object(copysignf)
add_math_entrypoint_object(copysignl)
add_math_entrypoint_object(copysignf16)
add_math_entrypoint_object(copysignf128)
+add_math_entrypoint_object(copysignbf16)
add_math_entrypoint_object(cos)
add_math_entrypoint_object(cosf)
@@ -200,6 +208,7 @@ add_math_entrypoint_object(fdimf)
add_math_entrypoint_object(fdiml)
add_math_entrypoint_object(fdimf16)
add_math_entrypoint_object(fdimf128)
+add_math_entrypoint_object(fdimbf16)
add_math_entrypoint_object(fdiv)
add_math_entrypoint_object(fdivl)
@@ -214,6 +223,7 @@ add_math_entrypoint_object(floorf)
add_math_entrypoint_object(floorl)
add_math_entrypoint_object(floorf16)
add_math_entrypoint_object(floorf128)
+add_math_entrypoint_object(floorbf16)
add_math_entrypoint_object(fma)
add_math_entrypoint_object(fmaf)
@@ -224,60 +234,70 @@ add_math_entrypoint_object(fmaxf)
add_math_entrypoint_object(fmaxl)
add_math_entrypoint_object(fmaxf128)
add_math_entrypoint_object(fmaxf16)
+add_math_entrypoint_object(fmaxbf16)
add_math_entrypoint_object(fmin)
add_math_entrypoint_object(fminf)
add_math_entrypoint_object(fminl)
add_math_entrypoint_object(fminf128)
add_math_entrypoint_object(fminf16)
+add_math_entrypoint_object(fminbf16)
add_math_entrypoint_object(fmaximum)
add_math_entrypoint_object(fmaximumf)
add_math_entrypoint_object(fmaximuml)
add_math_entrypoint_object(fmaximumf16)
add_math_entrypoint_object(fmaximumf128)
+add_math_entrypoint_object(fmaximumbf16)
add_math_entrypoint_object(fmaximum_num)
add_math_entrypoint_object(fmaximum_numf)
add_math_entrypoint_object(fmaximum_numl)
add_math_entrypoint_object(fmaximum_numf16)
add_math_entrypoint_object(fmaximum_numf128)
+add_math_entrypoint_object(fmaximum_numbf16)
add_math_entrypoint_object(fmaximum_mag)
add_math_entrypoint_object(fmaximum_magf)
add_math_entrypoint_object(fmaximum_magl)
add_math_entrypoint_object(fmaximum_magf16)
add_math_entrypoint_object(fmaximum_magf128)
+add_math_entrypoint_object(fmaximum_magbf16)
add_math_entrypoint_object(fmaximum_mag_num)
add_math_entrypoint_object(fmaximum_mag_numf)
add_math_entrypoint_object(fmaximum_mag_numl)
add_math_entrypoint_object(fmaximum_mag_numf16)
add_math_entrypoint_object(fmaximum_mag_numf128)
+add_math_entrypoint_object(fmaximum_mag_numbf16)
add_math_entrypoint_object(fminimum)
add_math_entrypoint_object(fminimumf)
add_math_entrypoint_object(fminimuml)
add_math_entrypoint_object(fminimumf16)
add_math_entrypoint_object(fminimumf128)
+add_math_entrypoint_object(fminimumbf16)
add_math_entrypoint_object(fminimum_num)
add_math_entrypoint_object(fminimum_numf)
add_math_entrypoint_object(fminimum_numl)
add_math_entrypoint_object(fminimum_numf16)
add_math_entrypoint_object(fminimum_numf128)
+add_math_entrypoint_object(fminimum_numbf16)
add_math_entrypoint_object(fminimum_mag)
add_math_entrypoint_object(fminimum_magf)
add_math_entrypoint_object(fminimum_magl)
add_math_entrypoint_object(fminimum_magf16)
add_math_entrypoint_object(fminimum_magf128)
+add_math_entrypoint_object(fminimum_magbf16)
add_math_entrypoint_object(fminimum_mag_num)
add_math_entrypoint_object(fminimum_mag_numf)
add_math_entrypoint_object(fminimum_mag_numl)
add_math_entrypoint_object(fminimum_mag_numf16)
add_math_entrypoint_object(fminimum_mag_numf128)
+add_math_entrypoint_object(fminimum_mag_numbf16)
add_math_entrypoint_object(fmul)
add_math_entrypoint_object(fmull)
@@ -288,24 +308,28 @@ add_math_entrypoint_object(fmodf)
add_math_entrypoint_object(fmodl)
add_math_entrypoint_object(fmodf16)
add_math_entrypoint_object(fmodf128)
+add_math_entrypoint_object(fmodbf16)
add_math_entrypoint_object(frexp)
add_math_entrypoint_object(frexpf)
add_math_entrypoint_object(frexpl)
add_math_entrypoint_object(frexpf16)
add_math_entrypoint_object(frexpf128)
+add_math_entrypoint_object(frexpbf16)
add_math_entrypoint_object(fromfp)
add_math_entrypoint_object(fromfpf)
add_math_entrypoint_object(fromfpl)
add_math_entrypoint_object(fromfpf16)
add_math_entrypoint_object(fromfpf128)
+add_math_entrypoint_object(fromfpbf16)
add_math_entrypoint_object(fromfpx)
add_math_entrypoint_object(fromfpxf)
add_math_entrypoint_object(fromfpxl)
add_math_entrypoint_object(fromfpxf16)
add_math_entrypoint_object(fromfpxf128)
+add_math_entrypoint_object(fromfpxbf16)
add_math_entrypoint_object(fsub)
add_math_entrypoint_object(fsubl)
@@ -316,6 +340,7 @@ add_math_entrypoint_object(getpayloadf)
add_math_entrypoint_object(getpayloadl)
add_math_entrypoint_object(getpayloadf16)
add_math_entrypoint_object(getpayloadf128)
+add_math_entrypoint_object(getpayloadbf16)
add_math_entrypoint_object(hypot)
add_math_entrypoint_object(hypotf)
@@ -326,6 +351,7 @@ add_math_entrypoint_object(ilogbf)
add_math_entrypoint_object(ilogbl)
add_math_entrypoint_object(ilogbf16)
add_math_entrypoint_object(ilogbf128)
+add_math_entrypoint_object(ilogbbf16)
add_math_entrypoint_object(isnan)
add_math_entrypoint_object(isnanf)
@@ -336,18 +362,21 @@ add_math_entrypoint_object(issignalingf)
add_math_entrypoint_object(issignalingl)
add_math_entrypoint_object(issignalingf16)
add_math_entrypoint_object(issignalingf128)
+add_math_entrypoint_object(issignalingbf16)
add_math_entrypoint_object(llogb)
add_math_entrypoint_object(llogbf)
add_math_entrypoint_object(llogbl)
add_math_entrypoint_object(llogbf16)
add_math_entrypoint_object(llogbf128)
+add_math_entrypoint_object(llogbbf16)
add_math_entrypoint_object(ldexp)
add_math_entrypoint_object(ldexpf)
add_math_entrypoint_object(ldexpl)
add_math_entrypoint_object(ldexpf16)
add_math_entrypoint_object(ldexpf128)
+add_math_entrypoint_object(ldexpbf16)
add_math_entrypoint_object(log10)
add_math_entrypoint_object(log10f)
@@ -369,71 +398,83 @@ add_math_entrypoint_object(logbf)
add_math_entrypoint_object(logbl)
add_math_entrypoint_object(logbf16)
add_math_entrypoint_object(logbf128)
+add_math_entrypoint_object(logbbf16)
add_math_entrypoint_object(llrint)
add_math_entrypoint_object(llrintf)
add_math_entrypoint_object(llrintl)
add_math_entrypoint_object(llrintf16)
add_math_entrypoint_object(llrintf128)
+add_math_entrypoint_object(llrintbf16)
add_math_entrypoint_object(llround)
add_math_entrypoint_object(llroundf)
add_math_entrypoint_object(llroundl)
add_math_entrypoint_object(llroundf16)
add_math_entrypoint_object(llroundf128)
+add_math_entrypoint_object(llroundbf16)
add_math_entrypoint_object(lrint)
add_math_entrypoint_object(lrintf)
add_math_entrypoint_object(lrintl)
add_math_entrypoint_object(lrintf16)
add_math_entrypoint_object(lrintf128)
+add_math_entrypoint_object(lrintbf16)
add_math_entrypoint_object(lround)
add_math_entrypoint_object(lroundf)
add_math_entrypoint_object(lroundl)
add_math_entrypoint_object(lroundf16)
add_math_entrypoint_object(lroundf128)
+add_math_entrypoint_object(lroundbf16)
add_math_entrypoint_object(modf)
add_math_entrypoint_object(modff)
add_math_entrypoint_object(modfl)
add_math_entrypoint_object(modff16)
add_math_entrypoint_object(modff128)
+add_math_entrypoint_object(modfbf16)
add_math_entrypoint_object(nan)
add_math_entrypoint_object(nanf)
add_math_entrypoint_object(nanl)
add_math_entrypoint_object(nanf16)
add_math_entrypoint_object(nanf128)
+add_math_entrypoint_object(nanbf16)
add_math_entrypoint_object(nearbyint)
add_math_entrypoint_object(nearbyintf)
add_math_entrypoint_object(nearbyintl)
add_math_entrypoint_object(nearbyintf16)
add_math_entrypoint_object(nearbyintf128)
+add_math_entrypoint_object(nearbyintbf16)
add_math_entrypoint_object(nextafter)
add_math_entrypoint_object(nextafterf)
add_math_entrypoint_object(nextafterl)
add_math_entrypoint_object(nextafterf16)
add_math_entrypoint_object(nextafterf128)
+add_math_entrypoint_object(nextafterbf16)
add_math_entrypoint_object(nexttoward)
add_math_entrypoint_object(nexttowardf)
add_math_entrypoint_object(nexttowardl)
add_math_entrypoint_object(nexttowardf16)
+add_math_entrypoint_object(nexttowardbf16)
add_math_entrypoint_object(nextdown)
add_math_entrypoint_object(nextdownf)
add_math_entrypoint_object(nextdownl)
add_math_entrypoint_object(nextdownf16)
add_math_entrypoint_object(nextdownf128)
+add_math_entrypoint_object(nextdownbf16)
add_math_entrypoint_object(nextup)
add_math_entrypoint_object(nextupf)
add_math_entrypoint_object(nextupl)
add_math_entrypoint_object(nextupf16)
add_math_entrypoint_object(nextupf128)
+add_math_entrypoint_object(nextupbf16)
add_math_entrypoint_object(pow)
add_math_entrypoint_object(powf)
@@ -445,54 +486,63 @@ add_math_entrypoint_object(remainderf)
add_math_entrypoint_object(remainderl)
add_math_entrypoint_object(remainderf16)
add_math_entrypoint_object(remainderf128)
+add_math_entrypoint_object(remainderbf16)
add_math_entrypoint_object(remquo)
add_math_entrypoint_object(remquof)
-add_math_entrypoint_object(remquof128)
add_math_entrypoint_object(remquol)
add_math_entrypoint_object(remquof16)
+add_math_entrypoint_object(remquof128)
+add_math_entrypoint_object(remquobf16)
add_math_entrypoint_object(rint)
add_math_entrypoint_object(rintf)
add_math_entrypoint_object(rintl)
add_math_entrypoint_object(rintf16)
add_math_entrypoint_object(rintf128)
+add_math_entrypoint_object(rintbf16)
add_math_entrypoint_object(round)
add_math_entrypoint_object(roundf)
add_math_entrypoint_object(roundl)
add_math_entrypoint_object(roundf16)
add_math_entrypoint_object(roundf128)
+add_math_entrypoint_object(roundbf16)
add_math_entrypoint_object(roundeven)
add_math_entrypoint_object(roundevenf)
add_math_entrypoint_object(roundevenl)
add_math_entrypoint_object(roundevenf16)
add_math_entrypoint_object(roundevenf128)
+add_math_entrypoint_object(roundevenbf16)
add_math_entrypoint_object(scalbln)
add_math_entrypoint_object(scalblnf)
add_math_entrypoint_object(scalblnl)
add_math_entrypoint_object(scalblnf16)
add_math_entrypoint_object(scalblnf128)
+add_math_entrypoint_object(scalblnbf16)
add_math_entrypoint_object(scalbn)
add_math_entrypoint_object(scalbnf)
add_math_entrypoint_object(scalbnl)
add_math_entrypoint_object(scalbnf16)
add_math_entrypoint_object(scalbnf128)
+add_math_entrypoint_object(scalbnbf16)
add_math_entrypoint_object(setpayload)
add_math_entrypoint_object(setpayloadf)
add_math_entrypoint_object(setpayloadl)
add_math_entrypoint_object(setpayloadf16)
add_math_entrypoint_object(setpayloadf128)
+add_math_entrypoint_object(setpayloadbf16)
add_math_entrypoint_object(setpayloadsig)
add_math_entrypoint_object(setpayloadsigf)
add_math_entrypoint_object(setpayloadsigl)
add_math_entrypoint_object(setpayloadsigf16)
add_math_entrypoint_object(setpayloadsigf128)
+add_math_entrypoint_object(setpayloadsigbf16)
add_math_entrypoint_object(sincos)
add_math_entrypoint_object(sincosf)
@@ -534,27 +584,57 @@ add_math_entrypoint_object(totalorderf)
add_math_entrypoint_object(totalorderl)
add_math_entrypoint_object(totalorderf16)
add_math_entrypoint_object(totalorderf128)
+add_math_entrypoint_object(totalorderbf16)
add_math_entrypoint_object(totalordermag)
add_math_entrypoint_object(totalordermagf)
add_math_entrypoint_object(totalordermagl)
add_math_entrypoint_object(totalordermagf16)
add_math_entrypoint_object(totalordermagf128)
+add_math_entrypoint_object(totalordermagbf16)
add_math_entrypoint_object(trunc)
add_math_entrypoint_object(truncf)
add_math_entrypoint_object(truncl)
add_math_entrypoint_object(truncf16)
add_math_entrypoint_object(truncf128)
+add_math_entrypoint_object(truncbf16)
add_math_entrypoint_object(ufromfp)
add_math_entrypoint_object(ufromfpf)
add_math_entrypoint_object(ufromfpl)
add_math_entrypoint_object(ufromfpf16)
add_math_entrypoint_object(ufromfpf128)
+add_math_entrypoint_object(ufromfpbf16)
add_math_entrypoint_object(ufromfpx)
add_math_entrypoint_object(ufromfpxf)
add_math_entrypoint_object(ufromfpxl)
add_math_entrypoint_object(ufromfpxf16)
add_math_entrypoint_object(ufromfpxf128)
+add_math_entrypoint_object(ufromfpxbf16)
+
+add_math_entrypoint_object(bf16add)
+add_math_entrypoint_object(bf16addf)
+add_math_entrypoint_object(bf16addl)
+add_math_entrypoint_object(bf16addf128)
+
+add_math_entrypoint_object(bf16div)
+add_math_entrypoint_object(bf16divf)
+add_math_entrypoint_object(bf16divl)
+add_math_entrypoint_object(bf16divf128)
+
+add_math_entrypoint_object(bf16fma)
+add_math_entrypoint_object(bf16fmaf)
+add_math_entrypoint_object(bf16fmal)
+add_math_entrypoint_object(bf16fmaf128)
+
+add_math_entrypoint_object(bf16mul)
+add_math_entrypoint_object(bf16mulf)
+add_math_entrypoint_object(bf16mull)
+add_math_entrypoint_object(bf16mulf128)
+
+add_math_entrypoint_object(bf16sub)
+add_math_entrypoint_object(bf16subf)
+add_math_entrypoint_object(bf16subl)
+add_math_entrypoint_object(bf16subf128)
diff --git a/libc/src/math/asinpif16.h b/libc/src/math/asinpif16.h
new file mode 100644
index 0000000..b97166a
--- /dev/null
+++ b/libc/src/math/asinpif16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for asinpif16 ---------------------*- 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_MATH_ASINPIF16_H
+#define LLVM_LIBC_SRC_MATH_ASINPIF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 asinpif16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ASINPIF16_H
diff --git a/libc/src/math/atanpif16.h b/libc/src/math/atanpif16.h
new file mode 100644
index 0000000..8f2391a
--- /dev/null
+++ b/libc/src/math/atanpif16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for atanpif16 ---------------------*- 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_MATH_ATANPIF16_H
+#define LLVM_LIBC_SRC_MATH_ATANPIF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 atanpif16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ASINF16_H
diff --git a/libc/src/math/bf16add.h b/libc/src/math/bf16add.h
new file mode 100644
index 0000000..a29970e
--- /dev/null
+++ b/libc/src/math/bf16add.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16add -----------------------*- 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_MATH_BF16ADD_H
+#define LLVM_LIBC_SRC_MATH_BF16ADD_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16add(double x, double y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16ADD_H
diff --git a/libc/src/math/bf16addf.h b/libc/src/math/bf16addf.h
new file mode 100644
index 0000000..80a5e2a
--- /dev/null
+++ b/libc/src/math/bf16addf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16addf ----------------------*- 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_MATH_BF16ADDF_H
+#define LLVM_LIBC_SRC_MATH_BF16ADDF_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16addf(float x, float y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16ADDF_H
diff --git a/libc/src/math/bf16addf128.h b/libc/src/math/bf16addf128.h
new file mode 100644
index 0000000..3c2f3a1
--- /dev/null
+++ b/libc/src/math/bf16addf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16addf128 -------------------*- 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_MATH_BF16ADDF128_H
+#define LLVM_LIBC_SRC_MATH_BF16ADDF128_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16addf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16ADDF128_H
diff --git a/libc/src/math/bf16addl.h b/libc/src/math/bf16addl.h
new file mode 100644
index 0000000..a9e7d68
--- /dev/null
+++ b/libc/src/math/bf16addl.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16addl ----------------------*- 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_MATH_BF16ADDL_H
+#define LLVM_LIBC_SRC_MATH_BF16ADDL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16addl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16ADDL_H
diff --git a/libc/src/math/bf16div.h b/libc/src/math/bf16div.h
new file mode 100644
index 0000000..ade9c06
--- /dev/null
+++ b/libc/src/math/bf16div.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16div -----------------------*- 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_MATH_BF16DIV_H
+#define LLVM_LIBC_SRC_MATH_BF16DIV_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16div(double x, double y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16DIV_H
diff --git a/libc/src/math/bf16divf.h b/libc/src/math/bf16divf.h
new file mode 100644
index 0000000..481b176
--- /dev/null
+++ b/libc/src/math/bf16divf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16divf ----------------------*- 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_MATH_BF16DIVF_H
+#define LLVM_LIBC_SRC_MATH_BF16DIVF_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16divf(float x, float y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16DIVF_H
diff --git a/libc/src/math/bf16divf128.h b/libc/src/math/bf16divf128.h
new file mode 100644
index 0000000..d990066
--- /dev/null
+++ b/libc/src/math/bf16divf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16divf128 -------------------*- 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_MATH_BF16DIVF128_H
+#define LLVM_LIBC_SRC_MATH_BF16DIVF128_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16divf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16DIVF128_H
diff --git a/libc/src/math/bf16divl.h b/libc/src/math/bf16divl.h
new file mode 100644
index 0000000..b19ac873
--- /dev/null
+++ b/libc/src/math/bf16divl.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16divl ----------------------*- 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_MATH_BF16DIVL_H
+#define LLVM_LIBC_SRC_MATH_BF16DIVL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16divl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16DIVL_H
diff --git a/libc/src/math/bf16fma.h b/libc/src/math/bf16fma.h
new file mode 100644
index 0000000..aa54956
--- /dev/null
+++ b/libc/src/math/bf16fma.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fma -----------------------*- 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_MATH_BF16FMA_H
+#define LLVM_LIBC_SRC_MATH_BF16FMA_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fma(double x, double y, double z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMA_H
diff --git a/libc/src/math/bf16fmaf.h b/libc/src/math/bf16fmaf.h
new file mode 100644
index 0000000..e8582bd
--- /dev/null
+++ b/libc/src/math/bf16fmaf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fmaf ----------------------*- 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_MATH_BF16FMAF_H
+#define LLVM_LIBC_SRC_MATH_BF16FMAF_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fmaf(float x, float y, float z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMAF_H
diff --git a/libc/src/math/bf16fmaf128.h b/libc/src/math/bf16fmaf128.h
new file mode 100644
index 0000000..4215e54
--- /dev/null
+++ b/libc/src/math/bf16fmaf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fmaf128 -------------------*- 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_MATH_BF16FMAF128_H
+#define LLVM_LIBC_SRC_MATH_BF16FMAF128_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fmaf128(float128 x, float128 y, float128 z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMAF128_H
diff --git a/libc/src/math/bf16fmal.h b/libc/src/math/bf16fmal.h
new file mode 100644
index 0000000..b92f17b
--- /dev/null
+++ b/libc/src/math/bf16fmal.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16fmal ----------------------*- 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_MATH_BF16FMAL_H
+#define LLVM_LIBC_SRC_MATH_BF16FMAL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16fmal(long double x, long double y, long double z);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16FMAL_H
diff --git a/libc/src/math/bf16mul.h b/libc/src/math/bf16mul.h
new file mode 100644
index 0000000..14e8a30
--- /dev/null
+++ b/libc/src/math/bf16mul.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16mul -----------------------*- 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_MATH_BF16MUL_H
+#define LLVM_LIBC_SRC_MATH_BF16MUL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16mul(double x, double y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16MUL_H
diff --git a/libc/src/math/bf16mulf.h b/libc/src/math/bf16mulf.h
new file mode 100644
index 0000000..1d02c8e
--- /dev/null
+++ b/libc/src/math/bf16mulf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16mulf ----------------------*- 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_MATH_BF16MULF_H
+#define LLVM_LIBC_SRC_MATH_BF16MULF_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16mulf(float x, float y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16MULF_H
diff --git a/libc/src/math/bf16mulf128.h b/libc/src/math/bf16mulf128.h
new file mode 100644
index 0000000..6ba7cef
--- /dev/null
+++ b/libc/src/math/bf16mulf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16mulf128 -------------------*- 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_MATH_BF16MULF128_H
+#define LLVM_LIBC_SRC_MATH_BF16MULF128_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16mulf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16MULF128_H
diff --git a/libc/src/math/bf16mull.h b/libc/src/math/bf16mull.h
new file mode 100644
index 0000000..dad6523
--- /dev/null
+++ b/libc/src/math/bf16mull.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16mull ----------------------*- 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_MATH_BF16MULL_H
+#define LLVM_LIBC_SRC_MATH_BF16MULL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16mull(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16MULL_H
diff --git a/libc/src/math/bf16sub.h b/libc/src/math/bf16sub.h
new file mode 100644
index 0000000..8108e914
--- /dev/null
+++ b/libc/src/math/bf16sub.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16sub -----------------------*- 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_MATH_BF16SUB_H
+#define LLVM_LIBC_SRC_MATH_BF16SUB_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16sub(double x, double y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16SUB_H
diff --git a/libc/src/math/bf16subf.h b/libc/src/math/bf16subf.h
new file mode 100644
index 0000000..1bd79bf
--- /dev/null
+++ b/libc/src/math/bf16subf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16subf ----------------------*- 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_MATH_BF16SUBF_H
+#define LLVM_LIBC_SRC_MATH_BF16SUBF_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16subf(float x, float y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16SUBF_H
diff --git a/libc/src/math/bf16subf128.h b/libc/src/math/bf16subf128.h
new file mode 100644
index 0000000..19590e8
--- /dev/null
+++ b/libc/src/math/bf16subf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16subf128 -------------------*- 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_MATH_BF16SUBF128_H
+#define LLVM_LIBC_SRC_MATH_BF16SUBF128_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16subf128(float128 x, float128 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16SUBF128_H
diff --git a/libc/src/math/bf16subl.h b/libc/src/math/bf16subl.h
new file mode 100644
index 0000000..13b2093
--- /dev/null
+++ b/libc/src/math/bf16subl.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for bf16subl ----------------------*- 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_MATH_BF16SUBL_H
+#define LLVM_LIBC_SRC_MATH_BF16SUBL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 bf16subl(long double x, long double y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_BF16SUBL_H
diff --git a/libc/src/math/canonicalizebf16.h b/libc/src/math/canonicalizebf16.h
new file mode 100644
index 0000000..858fa32
--- /dev/null
+++ b/libc/src/math/canonicalizebf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for canonicalizebf16 --------------*- 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_MATH_CANONICALIZEBF16_H
+#define LLVM_LIBC_SRC_MATH_CANONICALIZEBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int canonicalizebf16(bfloat16 *cx, const bfloat16 *x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_CANONICALIZEBF16_H
diff --git a/libc/src/math/ceilbf16.h b/libc/src/math/ceilbf16.h
new file mode 100644
index 0000000..bf70f25
--- /dev/null
+++ b/libc/src/math/ceilbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for ceilbf16 ----------------------*- 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_MATH_CEILBF16_H
+#define LLVM_LIBC_SRC_MATH_CEILBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 ceilbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_CEILBF16_H
diff --git a/libc/src/math/copysignbf16.h b/libc/src/math/copysignbf16.h
new file mode 100644
index 0000000..6369616
--- /dev/null
+++ b/libc/src/math/copysignbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for copysignbf16 ------------------*- 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_MATH_COPYSIGNBF16_H
+#define LLVM_LIBC_SRC_MATH_COPYSIGNBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 copysignbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_COPYSIGNBF16_H
diff --git a/libc/src/math/fdimbf16.h b/libc/src/math/fdimbf16.h
new file mode 100644
index 0000000..75bec34
--- /dev/null
+++ b/libc/src/math/fdimbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fdimbf16 ----------------------*- 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_MATH_FDIMBF16_H
+#define LLVM_LIBC_SRC_MATH_FDIMBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fdimbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FDIMBF16_H
diff --git a/libc/src/math/floorbf16.h b/libc/src/math/floorbf16.h
new file mode 100644
index 0000000..9b5a30a
--- /dev/null
+++ b/libc/src/math/floorbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for floorbf16 ---------------------*- 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_MATH_FLOORBF16_H
+#define LLVM_LIBC_SRC_MATH_FLOORBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 floorbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FLOORBF16_H
diff --git a/libc/src/math/fmaxbf16.h b/libc/src/math/fmaxbf16.h
new file mode 100644
index 0000000..bdbd14c
--- /dev/null
+++ b/libc/src/math/fmaxbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmaxbf16 ----------------------*- 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_MATH_FMAXBF16_H
+#define LLVM_LIBC_SRC_MATH_FMAXBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fmaxbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXBF16_H
diff --git a/libc/src/math/fmaximum_mag_numbf16.h b/libc/src/math/fmaximum_mag_numbf16.h
new file mode 100644
index 0000000..7663525
--- /dev/null
+++ b/libc/src/math/fmaximum_mag_numbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmaximum_mag_numbf16 ----------*- 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_MATH_FMAXIMUM_MAG_NUMBF16_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fmaximum_mag_numbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAG_NUMBF16_H
diff --git a/libc/src/math/fmaximum_magbf16.h b/libc/src/math/fmaximum_magbf16.h
new file mode 100644
index 0000000..ff0ff1a
--- /dev/null
+++ b/libc/src/math/fmaximum_magbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmaximum_magbf16 --------------*- 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_MATH_FMAXIMUM_MAGBF16_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fmaximum_magbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_MAGBF16_H
diff --git a/libc/src/math/fmaximum_numbf16.h b/libc/src/math/fmaximum_numbf16.h
new file mode 100644
index 0000000..f23bc52
--- /dev/null
+++ b/libc/src/math/fmaximum_numbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmaximum_numbf16 --------------*- 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_MATH_FMAXIMUM_NUMBF16_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fmaximum_numbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUM_NUMBF16_H
diff --git a/libc/src/math/fmaximumbf16.h b/libc/src/math/fmaximumbf16.h
new file mode 100644
index 0000000..9842e99
--- /dev/null
+++ b/libc/src/math/fmaximumbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmaximumbf16 ------------------*- 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_MATH_FMAXIMUMBF16_H
+#define LLVM_LIBC_SRC_MATH_FMAXIMUMBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fmaximumbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMAXIMUMBF16_H
diff --git a/libc/src/math/fminbf16.h b/libc/src/math/fminbf16.h
new file mode 100644
index 0000000..4c1ada9
--- /dev/null
+++ b/libc/src/math/fminbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fminbf16 ----------------------*- 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_MATH_FMINBF16_H
+#define LLVM_LIBC_SRC_MATH_FMINBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fminbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMINBF16_H
diff --git a/libc/src/math/fminimum_mag_numbf16.h b/libc/src/math/fminimum_mag_numbf16.h
new file mode 100644
index 0000000..2773381
--- /dev/null
+++ b/libc/src/math/fminimum_mag_numbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fminimum_mag_numbf16 ----------*- 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_MATH_FMINIMUM_MAG_NUMBF16_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fminimum_mag_numbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAG_NUMBF16_H
diff --git a/libc/src/math/fminimum_magbf16.h b/libc/src/math/fminimum_magbf16.h
new file mode 100644
index 0000000..fee5c4c8
--- /dev/null
+++ b/libc/src/math/fminimum_magbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fminimum_magbf16 --------------*- 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_MATH_FMINIMUM_MAGBF16_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_MAGBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fminimum_magbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_MAGBF16_H
diff --git a/libc/src/math/fminimum_numbf16.h b/libc/src/math/fminimum_numbf16.h
new file mode 100644
index 0000000..a3fd474
--- /dev/null
+++ b/libc/src/math/fminimum_numbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fminimum_numbf16 --------------*- 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_MATH_FMINIMUM_NUMBF16_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUM_NUMBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fminimum_numbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUM_NUMBF16_H
diff --git a/libc/src/math/fminimumbf16.h b/libc/src/math/fminimumbf16.h
new file mode 100644
index 0000000..07f1ada
--- /dev/null
+++ b/libc/src/math/fminimumbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fminimumbf16 ------------------*- 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_MATH_FMINIMUMBF16_H
+#define LLVM_LIBC_SRC_MATH_FMINIMUMBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fminimumbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMINIMUMBF16_H
diff --git a/libc/src/math/fmodbf16.h b/libc/src/math/fmodbf16.h
new file mode 100644
index 0000000..176dbcc
--- /dev/null
+++ b/libc/src/math/fmodbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fmodbf16 ----------------------*- 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_MATH_FMODBF16_H
+#define LLVM_LIBC_SRC_MATH_FMODBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fmodbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FMODBF16_H
diff --git a/libc/src/math/frexpbf16.h b/libc/src/math/frexpbf16.h
new file mode 100644
index 0000000..1e9bba1
--- /dev/null
+++ b/libc/src/math/frexpbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for frexpbf16 ---------------------*- 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_MATH_FREXPFB16_H
+#define LLVM_LIBC_SRC_MATH_FREXPFB16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 frexpbf16(bfloat16 x, int *exp);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FREXPFB16_H
diff --git a/libc/src/math/fromfpbf16.h b/libc/src/math/fromfpbf16.h
new file mode 100644
index 0000000..bff991c
--- /dev/null
+++ b/libc/src/math/fromfpbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fromfpbf16 --------------------*- 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_MATH_FROMFPBF16_H
+#define LLVM_LIBC_SRC_MATH_FROMFPBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fromfpbf16(bfloat16 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPBF16_H
diff --git a/libc/src/math/fromfpxbf16.h b/libc/src/math/fromfpxbf16.h
new file mode 100644
index 0000000..e40d975
--- /dev/null
+++ b/libc/src/math/fromfpxbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for fromfpxbf16 -------------------*- 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_MATH_FROMFPXBF16_H
+#define LLVM_LIBC_SRC_MATH_FROMFPXBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 fromfpxbf16(bfloat16 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPXBF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index a866195..a1f5de7 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -53,6 +53,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ canonicalizebf16
+ SRCS
+ canonicalizebf16.cpp
+ HDRS
+ ../canonicalizebf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_entrypoint_object(
iscanonical
SRCS
iscanonical.cpp
@@ -97,6 +111,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ iscanonicalbf16
+ SRCS
+ iscanonicalbf16.cpp
+ HDRS
+ ../iscanonicalbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_entrypoint_object(
ceil
SRCS
ceil.cpp
@@ -157,6 +185,22 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ ceilbf16
+ SRCS
+ ceilbf16.cpp
+ HDRS
+ ../ceilbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ ROUND_OPT
+)
+
+add_entrypoint_object(
daddl
SRCS
daddl.cpp
@@ -262,69 +306,6 @@ add_entrypoint_object(
libc.src.__support.FPUtil.generic.add_sub
)
-add_header_library(
- range_reduction
- HDRS
- range_reduction.h
- range_reduction_fma.h
- DEPENDS
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.fma
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.nearest_integer
- libc.src.__support.common
-)
-
-add_header_library(
- range_reduction_double
- HDRS
- range_reduction_double_common.h
- range_reduction_double_fma.h
- range_reduction_double_nofma.h
- DEPENDS
- libc.src.__support.FPUtil.double_double
- libc.src.__support.FPUtil.dyadic_float
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.fma
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.nearest_integer
- libc.src.__support.common
- libc.src.__support.integer_literals
-)
-
-add_header_library(
- sincosf_utils
- HDRS
- sincosf_utils.h
- DEPENDS
- .range_reduction
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.common
-)
-
-add_header_library(
- sincosf16_utils
- HDRS
- sincosf16_utils.h
- DEPENDS
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.FPUtil.nearest_integer
- libc.src.__support.common
-)
-
-add_header_library(
- sincos_eval
- HDRS
- sincos_eval.h
- DEPENDS
- libc.src.__support.FPUtil.double_double
- libc.src.__support.FPUtil.dyadic_float
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.integer_literals
-)
-
add_entrypoint_object(
cos
SRCS
@@ -332,16 +313,7 @@ add_entrypoint_object(
HDRS
../cos.h
DEPENDS
- .range_reduction_double
- .sincos_eval
- libc.hdr.errno_macros
- libc.src.errno.errno
- libc.src.__support.FPUtil.double_double
- libc.src.__support.FPUtil.dyadic_float
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.macros.optimization
+ libc.src.__support.math.cos
)
add_entrypoint_object(
@@ -351,15 +323,7 @@ add_entrypoint_object(
HDRS
../cosf.h
DEPENDS
- .sincosf_utils
- libc.src.errno.errno
- libc.src.__support.FPUtil.basic_operations
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fma
- libc.src.__support.FPUtil.polyeval
- libc.src.__support.macros.optimization
+ libc.src.__support.math.cosf
)
add_entrypoint_object(
@@ -369,16 +333,7 @@ add_entrypoint_object(
HDRS
../cosf16.h
DEPENDS
- .sincosf16_utils
- 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.except_value_utils
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.macros.optimization
- libc.src.__support.macros.properties.types
+ libc.src.__support.math.cosf16
)
add_entrypoint_object(
@@ -388,12 +343,7 @@ add_entrypoint_object(
HDRS
../cospif.h
DEPENDS
- .sincosf_utils
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.fma
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.macros.optimization
+ libc.src.__support.math.cospif
)
add_entrypoint_object(
@@ -403,14 +353,7 @@ add_entrypoint_object(
HDRS
../cospif16.h
DEPENDS
- .sincosf16_utils
- 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.macros.optimization
+ libc.src.__support.math.cospif16
)
add_entrypoint_object(
@@ -420,8 +363,8 @@ add_entrypoint_object(
HDRS
../sin.h
DEPENDS
- .range_reduction_double
- .sincos_eval
+ libc.src.__support.math.range_reduction_double
+ libc.src.__support.math.sincos_eval
libc.hdr.errno_macros
libc.src.errno.errno
libc.src.__support.FPUtil.double_double
@@ -440,8 +383,8 @@ add_entrypoint_object(
HDRS
../sinf.h
DEPENDS
- .range_reduction
- .sincosf_utils
+ libc.src.__support.math.range_reduction
+ libc.src.__support.math.sincosf_utils
libc.src.errno.errno
libc.src.__support.FPUtil.basic_operations
libc.src.__support.FPUtil.fenv_impl
@@ -459,7 +402,6 @@ add_entrypoint_object(
HDRS
../sinf16.h
DEPENDS
- .sincosf16_utils
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -469,6 +411,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.multiply_add
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.types
+ libc.src.__support.math.sincosf16_utils
COMPILE_OPTIONS
${libc_opt_high_flag}
)
@@ -480,8 +423,8 @@ add_entrypoint_object(
HDRS
../sincos.h
DEPENDS
- .range_reduction_double
- .sincos_eval
+ libc.src.__support.math.range_reduction_double
+ libc.src.__support.math.sincos_eval
libc.hdr.errno_macros
libc.src.errno.errno
libc.src.__support.FPUtil.double_double
@@ -500,7 +443,7 @@ add_entrypoint_object(
HDRS
../sinpif.h
DEPENDS
- .sincosf_utils
+ libc.src.__support.math.sincosf_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.fma
@@ -517,8 +460,8 @@ add_entrypoint_object(
HDRS
../sincosf.h
DEPENDS
- .range_reduction
- .sincosf_utils
+ libc.src.__support.math.range_reduction
+ libc.src.__support.math.sincosf_utils
libc.src.errno.errno
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
@@ -536,7 +479,6 @@ add_entrypoint_object(
HDRS
../sinpif16.h
DEPENDS
- .sincosf16_utils
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -544,6 +486,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.multiply_add
libc.src.__support.macros.optimization
+ libc.src.__support.math.sincosf16_utils
)
add_entrypoint_object(
@@ -553,7 +496,7 @@ add_entrypoint_object(
HDRS
../tan.h
DEPENDS
- .range_reduction_double
+ libc.src.__support.math.range_reduction_double
libc.hdr.errno_macros
libc.src.errno.errno
libc.src.__support.FPUtil.double_double
@@ -572,8 +515,8 @@ add_entrypoint_object(
HDRS
../tanf.h
DEPENDS
- .range_reduction
- .sincosf_utils
+ libc.src.__support.math.range_reduction
+ libc.src.__support.math.sincosf_utils
libc.src.errno.errno
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fenv_impl
@@ -592,7 +535,6 @@ add_entrypoint_object(
HDRS
../tanf16.h
DEPENDS
- .sincosf16_utils
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -602,6 +544,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.multiply_add
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.types
+ libc.src.__support.math.sincosf16_utils
)
add_entrypoint_object(
@@ -611,7 +554,7 @@ add_entrypoint_object(
HDRS
../tanpif.h
DEPENDS
- .sincosf_utils
+ libc.src.__support.math.sincosf_utils
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
@@ -626,7 +569,6 @@ add_entrypoint_object(
HDRS
../tanpif16.h
DEPENDS
- .sincosf16_utils
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -635,6 +577,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.multiply_add
libc.src.__support.macros.optimization
+ libc.src.__support.math.sincosf16_utils
)
add_entrypoint_object(
@@ -802,6 +745,22 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ truncbf16
+ SRCS
+ truncbf16.cpp
+ HDRS
+ ../truncbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ ROUND_OPT
+)
+
+add_entrypoint_object(
floor
SRCS
floor.cpp
@@ -862,6 +821,22 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ floorbf16
+ SRCS
+ floorbf16.cpp
+ HDRS
+ ../floorbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ ROUND_OPT
+)
+
+add_entrypoint_object(
round
SRCS
round.cpp
@@ -922,6 +897,22 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ roundbf16
+ SRCS
+ roundbf16.cpp
+ HDRS
+ ../roundbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ ROUND_OPT
+)
+
+add_entrypoint_object(
roundeven
SRCS
roundeven.cpp
@@ -982,6 +973,22 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ roundevenbf16
+ SRCS
+ roundevenbf16.cpp
+ HDRS
+ ../roundevenbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ ROUND_OPT
+)
+
+add_entrypoint_object(
lround
SRCS
lround.cpp
@@ -1034,6 +1041,19 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ lroundbf16
+ SRCS
+ lroundbf16.cpp
+ HDRS
+ ../lroundf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+)
+
+add_entrypoint_object(
llround
SRCS
llround.cpp
@@ -1086,6 +1106,19 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ llroundbf16
+ SRCS
+ llroundbf16.cpp
+ HDRS
+ ../llroundf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+)
+
+add_entrypoint_object(
rint
SRCS
rint.cpp
@@ -1146,6 +1179,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ rintbf16
+ SRCS
+ rintbf16.cpp
+ HDRS
+ ../rintbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ FLAGS
+ ROUND_OPT
+)
+
+add_entrypoint_object(
lrint
SRCS
lrint.cpp
@@ -1198,6 +1246,19 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ lrintbf16
+ SRCS
+ lrintbf16.cpp
+ HDRS
+ ../lrintbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+)
+
+add_entrypoint_object(
llrint
SRCS
llrint.cpp
@@ -1250,6 +1311,17 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ llrintbf16
+ SRCS
+ llrintbf16.cpp
+ HDRS
+ ../llrintbf16.h
+ DEPENDS
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.nearest_integer_operations
+)
+
+add_entrypoint_object(
nearbyint
SRCS
nearbyint.cpp
@@ -1302,6 +1374,19 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ nearbyintbf16
+ SRCS
+ nearbyintbf16.cpp
+ HDRS
+ ../nearbyintbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+)
+
+add_entrypoint_object(
erff
SRCS
erff.cpp
@@ -1353,7 +1438,6 @@ add_entrypoint_object(
../exp2.h
DEPENDS
.common_constants
- .explogxf
libc.src.__support.CPP.bit
libc.src.__support.CPP.optional
libc.src.__support.FPUtil.dyadic_float
@@ -1366,6 +1450,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.triple_double
libc.src.__support.integer_literals
libc.src.__support.macros.optimization
+ libc.src.__support.math.exp_utils
libc.src.errno.errno
)
@@ -1374,7 +1459,6 @@ add_header_library(
HDRS
exp2f_impl.h
DEPENDS
- .explogxf
libc.src.__support.FPUtil.except_value_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
@@ -1383,6 +1467,7 @@ add_header_library(
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.exp10f_utils
libc.src.__support.common
libc.src.errno.errno
)
@@ -1404,7 +1489,6 @@ add_entrypoint_object(
HDRS
../exp2f16.h
DEPENDS
- .expxf16
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -1413,6 +1497,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.expxf16_utils
)
add_entrypoint_object(
@@ -1422,7 +1507,6 @@ add_entrypoint_object(
HDRS
../exp2m1f.h
DEPENDS
- .explogxf
libc.src.errno.errno
libc.src.__support.common
libc.src.__support.FPUtil.except_value_utils
@@ -1433,6 +1517,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.math.exp10f_utils
)
add_entrypoint_object(
@@ -1442,7 +1527,6 @@ add_entrypoint_object(
HDRS
../exp2m1f16.h
DEPENDS
- .expxf16
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.common
@@ -1455,6 +1539,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.math.expxf16_utils
)
add_entrypoint_object(
@@ -1497,7 +1582,6 @@ add_entrypoint_object(
HDRS
../exp10m1f.h
DEPENDS
- .explogxf
libc.src.errno.errno
libc.src.__support.common
libc.src.__support.FPUtil.except_value_utils
@@ -1507,6 +1591,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.exp10f_utils
)
add_entrypoint_object(
@@ -1538,14 +1623,11 @@ add_entrypoint_object(
../expm1.h
DEPENDS
.common_constants
- .explogxf
libc.src.__support.CPP.bit
- libc.src.__support.CPP.optional
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.nearest_integer
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.FPUtil.triple_double
@@ -1580,7 +1662,6 @@ add_entrypoint_object(
HDRS
../expm1f16.h
DEPENDS
- .expxf16
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -1591,6 +1672,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.expxf16_utils
)
add_entrypoint_object(
@@ -1602,7 +1684,6 @@ add_entrypoint_object(
DEPENDS
.common_constants
.exp2f_impl
- .explogxf
libc.src.__support.math.exp10f
libc.src.__support.CPP.bit
libc.src.__support.FPUtil.fenv_impl
@@ -1696,6 +1777,22 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ copysignbf16
+ SRCS
+ copysignbf16.cpp
+ HDRS
+ ../copysignbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
frexp
SRCS
frexp.cpp
@@ -1746,6 +1843,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ frexpbf16
+ SRCS
+ frexpbf16.cpp
+ HDRS
+ ../frexpbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
ilogb
SRCS
ilogb.cpp
@@ -1798,6 +1909,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ ilogbbf16
+ SRCS
+ ilogbbf16.cpp
+ HDRS
+ ../ilogbbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
llogb
SRCS
llogb.cpp
@@ -1850,6 +1975,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ llogbbf16
+ SRCS
+ llogbbf16.cpp
+ HDRS
+ ../llogbbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
ldexp
SRCS
ldexp.cpp
@@ -1899,6 +2038,20 @@ add_entrypoint_object(
libc.src.__support.math.ldexpf128
)
+add_entrypoint_object(
+ ldexpbf16
+ SRCS
+ ldexpbf16.cpp
+ HDRS
+ ../ldexpbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
add_object_library(
common_constants
HDRS
@@ -1962,7 +2115,6 @@ add_entrypoint_object(
HDRS
../log10f16.h
DEPENDS
- .expxf16
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -1973,6 +2125,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.math.expxf16_utils
)
add_entrypoint_object(
@@ -2051,7 +2204,6 @@ add_entrypoint_object(
HDRS
../log2f16.h
DEPENDS
- .expxf16
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -2062,6 +2214,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.math.expxf16_utils
)
add_entrypoint_object(
@@ -2106,7 +2259,6 @@ add_entrypoint_object(
HDRS
../logf16.h
DEPENDS
- .expxf16
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.cast
@@ -2117,6 +2269,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.cpu_features
+ libc.src.__support.math.expxf16_utils
)
add_entrypoint_object(
@@ -2172,6 +2325,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ logbbf16
+ SRCS
+ logbbf16.cpp
+ HDRS
+ ../logbbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
modf
SRCS
modf.cpp
@@ -2224,6 +2391,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ modfbf16
+ SRCS
+ modfbf16.cpp
+ HDRS
+ ../modfbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
fmin
SRCS
fmin.cpp
@@ -2281,6 +2462,21 @@ add_entrypoint_object(
MISC_MATH_BASIC_OPS_OPT
)
+add_entrypoint_object(
+ fminbf16
+ SRCS
+ fminbf16.cpp
+ HDRS
+ ../fminbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
add_entrypoint_object(
fmax
@@ -2341,6 +2537,22 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fmaxbf16
+ SRCS
+ fmaxbf16.cpp
+ HDRS
+ ../fmaxbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
fmaximum
SRCS
fmaximum.cpp
@@ -2399,6 +2611,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fmaximumbf16
+ SRCS
+ fmaximumbf16.cpp
+ HDRS
+ ../fmaximumbf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
fmaximum_num
SRCS
fmaximum_num.cpp
@@ -2457,6 +2684,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fmaximum_numbf16
+ SRCS
+ fmaximum_numbf16.cpp
+ HDRS
+ ../fmaximum_numbf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
fmaximum_mag
SRCS
fmaximum_mag.cpp
@@ -2515,6 +2757,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fmaximum_magbf16
+ SRCS
+ fmaximum_magbf16.cpp
+ HDRS
+ ../fmaximum_magbf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
fmaximum_mag_num
SRCS
fmaximum_mag_num.cpp
@@ -2573,6 +2830,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fmaximum_mag_numbf16
+ SRCS
+ fmaximum_mag_numbf16.cpp
+ HDRS
+ ../fmaximum_mag_numbf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
fminimum
SRCS
fminimum.cpp
@@ -2631,6 +2903,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fminimumbf16
+ SRCS
+ fminimumbf16.cpp
+ HDRS
+ ../fminimumbf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
fminimum_num
SRCS
fminimum_num.cpp
@@ -2689,6 +2976,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fminimum_numbf16
+ SRCS
+ fminimum_numbf16.cpp
+ HDRS
+ ../fminimum_numbf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
fminimum_mag
SRCS
fminimum_mag.cpp
@@ -2747,6 +3049,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fminimum_magbf16
+ SRCS
+ fminimum_magbf16.cpp
+ HDRS
+ ../fminimum_magbf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
fminimum_mag_num
SRCS
fminimum_mag_num.cpp
@@ -2805,6 +3122,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fminimum_mag_numbf16
+ SRCS
+ fminimum_mag_numbf16.cpp
+ HDRS
+ ../fminimum_mag_numbf16.h
+ DEPENDS
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ FLAGS
+ MISC_MATH_BASIC_OPS_OPT
+)
+
+add_entrypoint_object(
fmul
SRCS
fmul.cpp
@@ -2977,6 +3309,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ remquobf16
+ SRCS
+ remquobf16.cpp
+ HDRS
+ ../remquobf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.division_and_remainder_operations
+ libc.src.__support.macros.properties.types
+ libc.src.__support.macros.config
+)
+
+add_entrypoint_object(
remainderf
SRCS
remainderf.cpp
@@ -3029,6 +3375,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ remainderbf16
+ SRCS
+ remainderbf16.cpp
+ HDRS
+ ../remainderbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.division_and_remainder_operations
+ libc.src.__support.macros.properties.types
+ libc.src.__support.macros.config
+)
+
+add_entrypoint_object(
hypotf
SRCS
hypotf.cpp
@@ -3112,6 +3472,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fdimbf16
+ SRCS
+ fdimbf16.cpp
+ HDRS
+ ../fdimbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_entrypoint_object(
fdiv
SRCS
fdiv.cpp
@@ -3228,6 +3602,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ issignalingbf16
+ SRCS
+ issignalingbf16.cpp
+ HDRS
+ ../issignalingbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_entrypoint_object(
isnan
SRCS
isnan.cpp
@@ -3307,6 +3695,22 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ nanbf16
+ SRCS
+ nanbf16.cpp
+ HDRS
+ ../nanbf16.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.str_to_float
+)
+
+add_entrypoint_object(
nextafter
SRCS
nextafter.cpp
@@ -3359,6 +3763,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ nextafterbf16
+ SRCS
+ nextafterbf16.cpp
+ HDRS
+ ../nextafterbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
nexttoward
SRCS
nexttoward.cpp
@@ -3400,6 +3818,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ nexttowardbf16
+ SRCS
+ nexttowardbf16.cpp
+ HDRS
+ ../nexttowardbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
nextdown
SRCS
nextdown.cpp
@@ -3452,6 +3884,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ nextdownbf16
+ SRCS
+ nextdownbf16.cpp
+ HDRS
+ ../nextdownbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
nextup
SRCS
nextup.cpp
@@ -3504,6 +3950,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ nextupbf16
+ SRCS
+ nextupbf16.cpp
+ HDRS
+ ../nextupbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
fmod
SRCS
fmod.cpp
@@ -3556,6 +4016,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fmodbf16
+ SRCS
+ fmodbf16.cpp
+ HDRS
+ ../fmodbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.fmod
+)
+
+add_entrypoint_object(
fromfp
SRCS
fromfp.cpp
@@ -3608,6 +4082,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fromfpbf16
+ SRCS
+ fromfpbf16.cpp
+ HDRS
+ ../fromfpbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
fromfpx
SRCS
fromfpx.cpp
@@ -3660,6 +4148,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ fromfpxbf16
+ SRCS
+ fromfpxbf16.cpp
+ HDRS
+ ../fromfpxbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
ufromfp
SRCS
ufromfp.cpp
@@ -3712,6 +4214,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ ufromfpbf16
+ SRCS
+ ufromfpbf16.cpp
+ HDRS
+ ../ufromfpbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
ufromfpx
SRCS
ufromfpx.cpp
@@ -3763,17 +4279,18 @@ add_entrypoint_object(
libc.src.__support.FPUtil.nearest_integer_operations
)
-#TODO: Add errno include to the hyperbolic functions.
-add_header_library(
- explogxf
+add_entrypoint_object(
+ ufromfpxbf16
+ SRCS
+ ufromfpxbf16.cpp
HDRS
- explogxf.h
+ ../ufromfpxbf16.h
DEPENDS
- .common_constants
- libc.src.__support.math.exp_utils
- libc.src.__support.math.acoshf_utils
- libc.src.__support.macros.properties.cpu_features
- libc.src.errno.errno
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
)
add_entrypoint_object(
@@ -3783,11 +4300,7 @@ add_entrypoint_object(
HDRS
../coshf.h
DEPENDS
- .explogxf
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.macros.optimization
+ libc.src.__support.math.coshf
)
add_entrypoint_object(
@@ -3797,14 +4310,7 @@ add_entrypoint_object(
HDRS
../coshf16.h
DEPENDS
- .expxf16
- libc.hdr.errno_macros
- libc.hdr.fenv_macros
- libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.macros.optimization
+ libc.src.__support.math.coshf16
)
add_entrypoint_object(
@@ -3814,10 +4320,10 @@ add_entrypoint_object(
HDRS
../sinhf.h
DEPENDS
- .explogxf
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.sinhfcoshf_utils
)
add_entrypoint_object(
@@ -3827,14 +4333,14 @@ add_entrypoint_object(
HDRS
../sinhf16.h
DEPENDS
- .expxf16
libc.hdr.errno_macros
libc.hdr.fenv_macros
libc.src.__support.FPUtil.except_value_utils
- libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.expxf16_utils
)
add_entrypoint_object(
@@ -3844,12 +4350,12 @@ add_entrypoint_object(
HDRS
../tanhf.h
DEPENDS
- .explogxf
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.FPUtil.multiply_add
libc.src.__support.FPUtil.polyeval
libc.src.__support.macros.optimization
+ libc.src.__support.math.exp10f_utils
)
add_entrypoint_object(
@@ -3859,7 +4365,6 @@ add_entrypoint_object(
HDRS
../tanhf16.h
DEPENDS
- .expxf16
libc.hdr.fenv_macros
libc.src.__support.CPP.array
libc.src.__support.FPUtil.cast
@@ -3871,6 +4376,7 @@ add_entrypoint_object(
libc.src.__support.FPUtil.polyeval
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.optimization
+ libc.src.__support.math.expxf16_utils
)
add_entrypoint_object(
@@ -3880,7 +4386,6 @@ add_entrypoint_object(
HDRS
../acoshf.h
DEPENDS
- .explogxf
libc.src.__support.math.acoshf
)
@@ -3916,6 +4421,25 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ asinpif16
+ SRCS
+ asinpif16.cpp
+ HDRS
+ ../asinpif16.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
+)
+
+add_entrypoint_object(
atanhf
SRCS
atanhf.cpp
@@ -3936,6 +4460,25 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ atanpif16
+ SRCS
+ atanpif16.cpp
+ HDRS
+ ../atanpif16.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
+)
+
+add_entrypoint_object(
asinf
SRCS
asinf.cpp
@@ -4137,6 +4680,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ scalblnbf16
+ SRCS
+ scalblnbf16.cpp
+ HDRS
+ ../scalblnbf16.h
+ DEPENDS
+ libc.hdr.float_macros
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_entrypoint_object(
scalbn
SRCS
scalbn.cpp
@@ -4194,6 +4752,21 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ scalbnbf16
+ SRCS
+ scalbnbf16.cpp
+ HDRS
+ ../scalblnbf16.h
+ DEPENDS
+ libc.hdr.float_macros
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_entrypoint_object(
fmaf
SRCS
fmaf.cpp
@@ -4274,6 +4847,21 @@ add_entrypoint_object(
libc.src.__support.FPUtil.basic_operations
libc.src.__support.macros.properties.types
)
+
+add_entrypoint_object(
+ totalorderbf16
+ SRCS
+ totalorderbf16.cpp
+ HDRS
+ ../totalorderbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_entrypoint_object(
totalordermag
SRCS
@@ -4326,6 +4914,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ totalordermagbf16
+ SRCS
+ totalordermagbf16.cpp
+ HDRS
+ ../totalordermagbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_entrypoint_object(
getpayload
SRCS
getpayload.cpp
@@ -4378,6 +4980,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ getpayloadbf16
+ SRCS
+ getpayloadbf16.cpp
+ HDRS
+ ../getpayloadbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
setpayload
SRCS
setpayload.cpp
@@ -4430,6 +5046,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ setpayloadbf16
+ SRCS
+ setpayloadbf16.cpp
+ HDRS
+ ../setpayloadbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
setpayloadsig
SRCS
setpayloadsig.cpp
@@ -4482,6 +5112,20 @@ add_entrypoint_object(
)
add_entrypoint_object(
+ setpayloadsigbf16
+ SRCS
+ setpayloadsigbf16.cpp
+ HDRS
+ ../setpayloadsigbf16.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
f16add
SRCS
f16add.cpp
@@ -4739,11 +5383,7 @@ add_entrypoint_object(
HDRS
../cbrtf.h
DEPENDS
- libc.hdr.fenv_macros
- libc.src.__support.FPUtil.fenv_impl
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.macros.optimization
+ libc.src.__support.math.cbrtf
)
add_entrypoint_object(
@@ -4821,17 +5461,282 @@ add_entrypoint_object(
libc.src.__support.FPUtil.generic.mul
)
-add_header_library(
- expxf16
+add_entrypoint_object(
+ bf16add
+ SRCS
+ bf16add.cpp
HDRS
- expxf16.h
+ ../bf16add.h
DEPENDS
- libc.hdr.stdint_proxy
- libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.cast
- libc.src.__support.FPUtil.multiply_add
- libc.src.__support.FPUtil.nearest_integer
- libc.src.__support.macros.attributes
- libc.src.__support.math.expf16_utils
- libc.src.__support.math.exp10_float16_constants
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16addf
+ SRCS
+ bf16addf.cpp
+ HDRS
+ ../bf16addf.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16addl
+ SRCS
+ bf16addl.cpp
+ HDRS
+ ../bf16addl.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16addf128
+ SRCS
+ bf16addf128.cpp
+ HDRS
+ ../bf16addf128.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16div
+ SRCS
+ bf16div.cpp
+ HDRS
+ ../bf16div.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.div
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16divf
+ SRCS
+ bf16divf.cpp
+ HDRS
+ ../bf16divf.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.div
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16divl
+ SRCS
+ bf16divl.cpp
+ HDRS
+ ../bf16divl.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.div
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16divf128
+ SRCS
+ bf16divf128.cpp
+ HDRS
+ ../bf16divf128.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.div
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16fma
+ SRCS
+ bf16fma.cpp
+ HDRS
+ ../bf16fma.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fma
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16fmaf
+ SRCS
+ bf16fmaf.cpp
+ HDRS
+ ../bf16fmaf.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fma
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16fmal
+ SRCS
+ bf16fmal.cpp
+ HDRS
+ ../bf16fmal.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fma
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16fmaf128
+ SRCS
+ bf16fmaf128.cpp
+ HDRS
+ ../bf16fmaf128.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fma
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16mul
+ SRCS
+ bf16mul.cpp
+ HDRS
+ ../bf16mul.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.mul
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16mulf
+ SRCS
+ bf16mulf.cpp
+ HDRS
+ ../bf16mulf.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.mul
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16mull
+ SRCS
+ bf16mull.cpp
+ HDRS
+ ../bf16mull.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.mul
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16mulf128
+ SRCS
+ bf16mulf128.cpp
+ HDRS
+ ../bf16mulf128.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.mul
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16sub
+ SRCS
+ bf16sub.cpp
+ HDRS
+ ../bf16sub.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16subf
+ SRCS
+ bf16subf.cpp
+ HDRS
+ ../bf16subf.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16subl
+ SRCS
+ bf16subl.cpp
+ HDRS
+ ../bf16subl.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+ bf16subf128
+ SRCS
+ bf16subf128.cpp
+ HDRS
+ ../bf16subf128.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
)
diff --git a/libc/src/math/generic/acoshf.cpp b/libc/src/math/generic/acoshf.cpp
index 5c04583..c964632 100644
--- a/libc/src/math/generic/acoshf.cpp
+++ b/libc/src/math/generic/acoshf.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/acoshf.h"
-
#include "src/__support/math/acoshf.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/asinpif16.cpp b/libc/src/math/generic/asinpif16.cpp
new file mode 100644
index 0000000..aabc086
--- /dev/null
+++ b/libc/src/math/generic/asinpif16.cpp
@@ -0,0 +1,127 @@
+//===-- Half-precision asinpif16(x) function ------------------------------===//
+//
+// 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/math/asinpif16.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"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, asinpif16, (float16 x)) {
+ using FPBits = fputil::FPBits<float16>;
+
+ FPBits xbits(x);
+ bool is_neg = xbits.is_neg();
+ double x_abs = fputil::cast<double>(xbits.abs().get_val());
+
+ auto signed_result = [is_neg](auto r) -> auto { return is_neg ? -r : r; };
+
+ if (LIBC_UNLIKELY(x_abs > 1.0)) {
+ // aspinf16(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();
+ }
+
+ // the coefficients for the polynomial approximation of asin(x)/pi in the
+ // range [0, 0.5] extracted using python-sympy
+ //
+ // Python code to generate the coefficients:
+ // > from sympy import *
+ // > import math
+ // > x = symbols('x')
+ // > print(series(asin(x)/math.pi, x, 0, 21))
+ //
+ // OUTPUT:
+ //
+ // 0.318309886183791*x + 0.0530516476972984*x**3 + 0.0238732414637843*x**5 +
+ // 0.0142102627760621*x**7 + 0.00967087327815336*x**9 +
+ // 0.00712127941391293*x**11 + 0.00552355646848375*x**13 +
+ // 0.00444514782463692*x**15 + 0.00367705242846804*x**17 +
+ // 0.00310721681820837*x**19 + O(x**21)
+ //
+ // it's very accurate in the range [0, 0.5] and has a maximum error of
+ // 0.0000000000000001 in the range [0, 0.5].
+ constexpr double POLY_COEFFS[] = {
+ 0x1.45f306dc9c889p-2, // x^1
+ 0x1.b2995e7b7b5fdp-5, // x^3
+ 0x1.8723a1d588a36p-6, // x^5
+ 0x1.d1a452f20430dp-7, // x^7
+ 0x1.3ce52a3a09f61p-7, // x^9
+ 0x1.d2b33e303d375p-8, // x^11
+ 0x1.69fde663c674fp-8, // x^13
+ 0x1.235134885f19bp-8, // x^15
+ };
+ // polynomial evaluation using horner's method
+ // work only for |x| in [0, 0.5]
+ auto asinpi_polyeval = [](double x) -> double {
+ return x * fputil::polyeval(x * x, POLY_COEFFS[0], POLY_COEFFS[1],
+ POLY_COEFFS[2], POLY_COEFFS[3], POLY_COEFFS[4],
+ POLY_COEFFS[5], POLY_COEFFS[6], POLY_COEFFS[7]);
+ };
+
+ // if |x| <= 0.5:
+ if (LIBC_UNLIKELY(x_abs <= 0.5)) {
+ // Use polynomial approximation of asin(x)/pi in the range [0, 0.5]
+ double result = asinpi_polyeval(fputil::cast<double>(x));
+ return fputil::cast<float16>(result);
+ }
+
+ // If |x| > 0.5, we need to use the range reduction method:
+ // y = asin(x) => x = sin(y)
+ // because: sin(a) = cos(pi/2 - a)
+ // therefore:
+ // x = cos(pi/2 - y)
+ // let z = pi/2 - y,
+ // x = cos(z)
+ // because: cos(2a) = 1 - 2 * sin^2(a), z = 2a, a = z/2
+ // therefore:
+ // cos(z) = 1 - 2 * sin^2(z/2)
+ // sin(z/2) = sqrt((1 - cos(z))/2)
+ // sin(z/2) = sqrt((1 - x)/2)
+ // let u = (1 - x)/2
+ // then:
+ // sin(z/2) = sqrt(u)
+ // z/2 = asin(sqrt(u))
+ // z = 2 * asin(sqrt(u))
+ // pi/2 - y = 2 * asin(sqrt(u))
+ // y = pi/2 - 2 * asin(sqrt(u))
+ // y/pi = 1/2 - 2 * asin(sqrt(u))/pi
+ //
+ // Finally, we can write:
+ // asinpi(x) = 1/2 - 2 * asinpi(sqrt(u))
+ // where u = (1 - x) /2
+ // = 0.5 - 0.5 * x
+ // = multiply_add(-0.5, x, 0.5)
+
+ double u = fputil::multiply_add(-0.5, x_abs, 0.5);
+ double asinpi_sqrt_u = asinpi_polyeval(fputil::sqrt<double>(u));
+ double result = fputil::multiply_add(-2.0, asinpi_sqrt_u, 0.5);
+
+ return fputil::cast<float16>(signed_result(result));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/atanpif16.cpp b/libc/src/math/generic/atanpif16.cpp
new file mode 100644
index 0000000..c54087c
--- /dev/null
+++ b/libc/src/math/generic/atanpif16.cpp
@@ -0,0 +1,157 @@
+//===-- Half-precision atanpi function ------------------------------------===//
+//
+// 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/math/atanpif16.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"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// Using Python's SymPy library, we can obtain the polynomial approximation of
+// arctan(x)/pi. The steps are as follows:
+// >>> from sympy import *
+// >>> import math
+// >>> x = symbols('x')
+// >>> print(series(atan(x)/math.pi, x, 0, 17))
+//
+// Output:
+// 0.318309886183791*x - 0.106103295394597*x**3 + 0.0636619772367581*x**5 -
+// 0.0454728408833987*x**7 + 0.0353677651315323*x**9 - 0.0289372623803446*x**11
+// + 0.0244853758602916*x**13 - 0.0212206590789194*x**15 + O(x**17)
+//
+// We will assign this degree-15 Taylor polynomial as g(x). This polynomial
+// approximation is accurate for arctan(x)/pi when |x| is in the range [0, 0.5].
+//
+//
+// To compute arctan(x) for all real x, we divide the domain into the following
+// cases:
+//
+// * Case 1: |x| <= 0.5
+// In this range, the direct polynomial approximation is used:
+// arctan(x)/pi = sign(x) * g(|x|)
+// or equivalently, arctan(x) = sign(x) * pi * g(|x|).
+//
+// * Case 2: 0.5 < |x| <= 1
+// We use the double-angle identity for the tangent function, specifically:
+// arctan(x) = 2 * arctan(x / (1 + sqrt(1 + x^2))).
+// Applying this, we have:
+// arctan(x)/pi = sign(x) * 2 * arctan(x')/pi,
+// where x' = |x| / (1 + sqrt(1 + x^2)).
+// Thus, arctan(x)/pi = sign(x) * 2 * g(x')
+//
+// When |x| is in (0.5, 1], the value of x' will always fall within the
+// interval [0.207, 0.414], which is within the accurate range of g(x).
+//
+// * Case 3: |x| > 1
+// For values of |x| greater than 1, we use the reciprocal transformation
+// identity:
+// arctan(x) = pi/2 - arctan(1/x) for x > 0.
+// For any x (real number), this generalizes to:
+// arctan(x)/pi = sign(x) * (1/2 - arctan(1/|x|)/pi).
+// Then, using g(x) for arctan(1/|x|)/pi:
+// arctan(x)/pi = sign(x) * (1/2 - g(1/|x|)).
+//
+// Note that if 1/|x| still falls outside the
+// g(x)'s primary range of accuracy (i.e., if 0.5 < 1/|x| <= 1), the rule
+// from Case 2 must be applied recursively to 1/|x|.
+
+LLVM_LIBC_FUNCTION(float16, atanpif16, (float16 x)) {
+ using FPBits = fputil::FPBits<float16>;
+
+ FPBits xbits(x);
+ bool is_neg = xbits.is_neg();
+
+ auto signed_result = [is_neg](double r) -> float16 {
+ return fputil::cast<float16>(is_neg ? -r : r);
+ };
+
+ if (LIBC_UNLIKELY(xbits.is_inf_or_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;
+ }
+ // atanpi(±∞) = ±0.5
+ return signed_result(0.5);
+ }
+
+ if (LIBC_UNLIKELY(xbits.is_zero()))
+ return x;
+
+ double x_abs = fputil::cast<double>(xbits.abs().get_val());
+
+ if (LIBC_UNLIKELY(x_abs == 1.0))
+ return signed_result(0.25);
+
+ // evaluate atan(x)/pi using polynomial approximation, valid for |x| <= 0.5
+ constexpr auto atanpi_eval = [](double x) -> double {
+ // polynomial coefficients for atan(x)/pi taylor series
+ // generated using sympy: series(atan(x)/pi, x, 0, 17)
+ constexpr static double POLY_COEFFS[] = {
+ 0x1.45f306dc9c889p-2, // x^1: 1/pi
+ -0x1.b2995e7b7b60bp-4, // x^3: -1/(3*pi)
+ 0x1.04c26be3b06ccp-4, // x^5: 1/(5*pi)
+ -0x1.7483758e69c08p-5, // x^7: -1/(7*pi)
+ 0x1.21bb945252403p-5, // x^9: 1/(9*pi)
+ -0x1.da1bace3cc68ep-6, // x^11: -1/(11*pi)
+ 0x1.912b1c2336cf2p-6, // x^13: 1/(13*pi)
+ -0x1.5bade52f95e7p-6, // x^15: -1/(15*pi)
+ };
+ double x_sq = x * x;
+ return x * fputil::polyeval(x_sq, POLY_COEFFS[0], POLY_COEFFS[1],
+ POLY_COEFFS[2], POLY_COEFFS[3], POLY_COEFFS[4],
+ POLY_COEFFS[5], POLY_COEFFS[6], POLY_COEFFS[7]);
+ };
+
+ // Case 1: |x| <= 0.5 - Direct polynomial evaluation
+ if (LIBC_LIKELY(x_abs <= 0.5)) {
+ double result = atanpi_eval(x_abs);
+ return signed_result(result);
+ }
+
+ // case 2: 0.5 < |x| <= 1 - use double-angle reduction
+ // atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2)))
+ // so atanpi(x) = 2 * atanpi(x') where x' = x / (1 + sqrt(1 + x^2))
+ if (x_abs <= 1.0) {
+ double x_abs_sq = x_abs * x_abs;
+ double sqrt_term = fputil::sqrt<double>(1.0 + x_abs_sq);
+ double x_prime = x_abs / (1.0 + sqrt_term);
+ double result = 2.0 * atanpi_eval(x_prime);
+ return signed_result(result);
+ }
+
+ // case 3: |x| > 1 - use reciprocal transformation
+ // atan(x) = pi/2 - atan(1/x) for x > 0
+ // so atanpi(x) = 1/2 - atanpi(1/x)
+ double x_recip = 1.0 / x_abs;
+ double result;
+
+ // if 1/|x| > 0.5, we need to apply Case 2 transformation to 1/|x|
+ if (x_recip > 0.5) {
+ double x_recip_sq = x_recip * x_recip;
+ double sqrt_term = fputil::sqrt<double>(1.0 + x_recip_sq);
+ double x_prime = x_recip / (1.0 + sqrt_term);
+ result = fputil::multiply_add(-2.0, atanpi_eval(x_prime), 0.5);
+ } else {
+ // direct evaluation since 1/|x| <= 0.5
+ result = 0.5 - atanpi_eval(x_recip);
+ }
+
+ return signed_result(result);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16add.cpp b/libc/src/math/generic/bf16add.cpp
new file mode 100644
index 0000000..257596a
--- /dev/null
+++ b/libc/src/math/generic/bf16add.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16add function --------------------------------===//
+//
+// 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/math/bf16add.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16add, (double x, double y)) {
+ return fputil::generic::add<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16addf.cpp b/libc/src/math/generic/bf16addf.cpp
new file mode 100644
index 0000000..65e6cbf
--- /dev/null
+++ b/libc/src/math/generic/bf16addf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16addf function -------------------------------===//
+//
+// 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/math/bf16addf.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16addf, (float x, float y)) {
+ return fputil::generic::add<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16addf128.cpp b/libc/src/math/generic/bf16addf128.cpp
new file mode 100644
index 0000000..03f70af
--- /dev/null
+++ b/libc/src/math/generic/bf16addf128.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16addf128 function ----------------------------===//
+//
+// 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/math/bf16addf128.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16addf128, (float128 x, float128 y)) {
+ return fputil::generic::add<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16addl.cpp b/libc/src/math/generic/bf16addl.cpp
new file mode 100644
index 0000000..c212195
--- /dev/null
+++ b/libc/src/math/generic/bf16addl.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16addl function -------------------------------===//
+//
+// 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/math/bf16addl.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16addl, (long double x, long double y)) {
+ return fputil::generic::add<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16div.cpp b/libc/src/math/generic/bf16div.cpp
new file mode 100644
index 0000000..5e9b1b4
--- /dev/null
+++ b/libc/src/math/generic/bf16div.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16div function --------------------------------===//
+//
+// 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/math/bf16div.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/div.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16div, (double x, double y)) {
+ return fputil::generic::div<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16divf.cpp b/libc/src/math/generic/bf16divf.cpp
new file mode 100644
index 0000000..2054a64
--- /dev/null
+++ b/libc/src/math/generic/bf16divf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16divf function -------------------------------===//
+//
+// 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/math/bf16divf.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/div.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16divf, (float x, float y)) {
+ return fputil::generic::div<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16divf128.cpp b/libc/src/math/generic/bf16divf128.cpp
new file mode 100644
index 0000000..fbe9775
--- /dev/null
+++ b/libc/src/math/generic/bf16divf128.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16divf128 function ----------------------------===//
+//
+// 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/math/bf16divf128.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/div.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16divf128, (float128 x, float128 y)) {
+ return fputil::generic::div<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16divl.cpp b/libc/src/math/generic/bf16divl.cpp
new file mode 100644
index 0000000..21dd6b1
--- /dev/null
+++ b/libc/src/math/generic/bf16divl.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16divl function -------------------------------===//
+//
+// 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/math/bf16divl.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/div.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16divl, (long double x, long double y)) {
+ return fputil::generic::div<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fma.cpp b/libc/src/math/generic/bf16fma.cpp
new file mode 100644
index 0000000..0f0fe86
--- /dev/null
+++ b/libc/src/math/generic/bf16fma.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16fma function --------------------------------===//
+//
+// 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/math/bf16fma.h"
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fma, (double x, double y, double z)) {
+ return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fmaf.cpp b/libc/src/math/generic/bf16fmaf.cpp
new file mode 100644
index 0000000..739691c
--- /dev/null
+++ b/libc/src/math/generic/bf16fmaf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16fmaf function -------------------------------===//
+//
+// 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/math/bf16fmaf.h"
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf, (float x, float y, float z)) {
+ return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fmaf128.cpp b/libc/src/math/generic/bf16fmaf128.cpp
new file mode 100644
index 0000000..a29a0b0
--- /dev/null
+++ b/libc/src/math/generic/bf16fmaf128.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bf16fmaf128 function ----------------------------===//
+//
+// 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/math/bf16fmaf128.h"
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fmaf128,
+ (float128 x, float128 y, float128 z)) {
+ return fputil::fma<bfloat16>(x, y, z);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16fmal.cpp b/libc/src/math/generic/bf16fmal.cpp
new file mode 100644
index 0000000..f31ec69
--- /dev/null
+++ b/libc/src/math/generic/bf16fmal.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of bf16fmal function -------------------------------===//
+//
+// 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/math/bf16fmal.h"
+
+#include "src/__support/FPUtil/FMA.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16fmal,
+ (long double x, long double y, long double z)) {
+ return fputil::fma<bfloat16>(x, y, z);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16mul.cpp b/libc/src/math/generic/bf16mul.cpp
new file mode 100644
index 0000000..c50eec2
--- /dev/null
+++ b/libc/src/math/generic/bf16mul.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16mul function --------------------------------===//
+//
+// 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/math/bf16mul.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/mul.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16mul, (double x, double y)) {
+ return fputil::generic::mul<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16mulf.cpp b/libc/src/math/generic/bf16mulf.cpp
new file mode 100644
index 0000000..117fcd1
--- /dev/null
+++ b/libc/src/math/generic/bf16mulf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16mulf function -------------------------------===//
+//
+// 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/math/bf16mulf.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/mul.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16mulf, (float x, float y)) {
+ return fputil::generic::mul<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16mulf128.cpp b/libc/src/math/generic/bf16mulf128.cpp
new file mode 100644
index 0000000..ff2a081
--- /dev/null
+++ b/libc/src/math/generic/bf16mulf128.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16mulf128 function ----------------------------===//
+//
+// 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/math/bf16mulf128.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/mul.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16mulf128, (float128 x, float128 y)) {
+ return fputil::generic::mul<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16mull.cpp b/libc/src/math/generic/bf16mull.cpp
new file mode 100644
index 0000000..e7c4fc0
--- /dev/null
+++ b/libc/src/math/generic/bf16mull.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16mull function -------------------------------===//
+//
+// 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/math/bf16mull.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/mul.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16mull, (long double x, long double y)) {
+ return fputil::generic::mul<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16sub.cpp b/libc/src/math/generic/bf16sub.cpp
new file mode 100644
index 0000000..65eb209
--- /dev/null
+++ b/libc/src/math/generic/bf16sub.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16sub function --------------------------------===//
+//
+// 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/math/bf16sub.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16sub, (double x, double y)) {
+ return fputil::generic::sub<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16subf.cpp b/libc/src/math/generic/bf16subf.cpp
new file mode 100644
index 0000000..6bba4be
--- /dev/null
+++ b/libc/src/math/generic/bf16subf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16subf function -------------------------------===//
+//
+// 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/math/bf16subf.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16subf, (float x, float y)) {
+ return fputil::generic::sub<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16subf128.cpp b/libc/src/math/generic/bf16subf128.cpp
new file mode 100644
index 0000000..e5fe107
--- /dev/null
+++ b/libc/src/math/generic/bf16subf128.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16subf128 function ----------------------------===//
+//
+// 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/math/bf16subf128.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16subf128, (float128 x, float128 y)) {
+ return fputil::generic::sub<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/bf16subl.cpp b/libc/src/math/generic/bf16subl.cpp
new file mode 100644
index 0000000..d3a970c
--- /dev/null
+++ b/libc/src/math/generic/bf16subl.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of bf16subl function -------------------------------===//
+//
+// 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/math/bf16subl.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, bf16subl, (long double x, long double y)) {
+ return fputil::generic::sub<bfloat16>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/canonicalizebf16.cpp b/libc/src/math/generic/canonicalizebf16.cpp
new file mode 100644
index 0000000..9cc3790
--- /dev/null
+++ b/libc/src/math/generic/canonicalizebf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of canonicalizebf16 function -----------------------===//
+//
+// 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/math/canonicalizebf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, canonicalizebf16, (bfloat16 * cx, const bfloat16 *x)) {
+ return fputil::canonicalize(*cx, *x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/cbrtf.cpp b/libc/src/math/generic/cbrtf.cpp
index 71b23c4..0bd8f71 100644
--- a/libc/src/math/generic/cbrtf.cpp
+++ b/libc/src/math/generic/cbrtf.cpp
@@ -7,153 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/cbrtf.h"
-#include "hdr/fenv_macros.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.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/cbrtf.h"
namespace LIBC_NAMESPACE_DECL {
-namespace {
-
-// Look up table for 2^(i/3) for i = 0, 1, 2.
-constexpr double CBRT2[3] = {1.0, 0x1.428a2f98d728bp0, 0x1.965fea53d6e3dp0};
-
-// Degree-7 polynomials approximation of ((1 + x)^(1/3) - 1)/x for 0 <= x <= 1
-// generated by Sollya with:
-// > for i from 0 to 15 do {
-// P = fpminimax(((1 + x)^(1/3) - 1)/x, 6, [|D...|], [i/16, (i + 1)/16]);
-// print("{", coeff(P, 0), ",", coeff(P, 1), ",", coeff(P, 2), ",",
-// coeff(P, 3), ",", coeff(P, 4), ",", coeff(P, 5), ",",
-// coeff(P, 6), "},");
-// };
-// Then (1 + x)^(1/3) ~ 1 + x * P(x).
-constexpr double COEFFS[16][7] = {
- {0x1.55555555554ebp-2, -0x1.c71c71c678c0cp-4, 0x1.f9add2776de81p-5,
- -0x1.511e10aa964a7p-5, 0x1.ee44165937fa2p-6, -0x1.7c5c9e059345dp-6,
- 0x1.047f75e0aff14p-6},
- {0x1.5555554d1149ap-2, -0x1.c71c676fcb5bp-4, 0x1.f9ab127dc57ebp-5,
- -0x1.50ea8fd1d4c15p-5, 0x1.e9d68f28ced43p-6, -0x1.60e0e1e661311p-6,
- 0x1.716eca1d6e3bcp-7},
- {0x1.5555546377d45p-2, -0x1.c71bc1c6d49d2p-4, 0x1.f9924cc0ed24dp-5,
- -0x1.4fea3beb53b3bp-5, 0x1.de028a9a07b1bp-6, -0x1.3b090d2233524p-6,
- 0x1.0aeca34893785p-7},
- {0x1.55554dce9f649p-2, -0x1.c7188b34b98f8p-4, 0x1.f93e1af34af49p-5,
- -0x1.4d9a06be75c63p-5, 0x1.cb943f4f68992p-6, -0x1.139a685a5e3c4p-6,
- 0x1.88410674c6a5dp-8},
- {0x1.5555347d211c3p-2, -0x1.c70f2a4b1a5fap-4, 0x1.f88420e8602c3p-5,
- -0x1.49becfa4ed3ep-5, 0x1.b475cd9013162p-6, -0x1.dcfee1dd2f8efp-7,
- 0x1.249bb51a1c498p-8},
- {0x1.5554f01b33dbap-2, -0x1.c6facb929dbf1p-4, 0x1.f73fb7861252ep-5,
- -0x1.4459a4a0071fap-5, 0x1.9a8df2b504fc2p-6, -0x1.9a7ce3006d06ep-7,
- 0x1.ba9230918fa2ep-9},
- {0x1.55545c695db5fp-2, -0x1.c6d6089f20275p-4, 0x1.f556e0ea80efp-5,
- -0x1.3d91372d083f4p-5, 0x1.7f66cff331f4p-6, -0x1.606a562491737p-7,
- 0x1.52e3e17c71069p-9},
- {0x1.55534a879232ap-2, -0x1.c69b836998b84p-4, 0x1.f2bb26dac0e4cp-5,
- -0x1.359eed43716d7p-5, 0x1.64218cd824fbcp-6, -0x1.2e703e2e091e8p-7,
- 0x1.0677d9af6aad4p-9},
- {0x1.5551836bb5494p-2, -0x1.c64658c15353bp-4, 0x1.ef68517451a6ep-5,
- -0x1.2cc20a980dceep-5, 0x1.49843e0fad93ap-6, -0x1.03c59ccb68e54p-7,
- 0x1.9ad325dc7adcbp-10},
- {0x1.554ecacb0d035p-2, -0x1.c5d2664026ffcp-4, 0x1.eb624796ba809p-5,
- -0x1.233803d19a535p-5, 0x1.300decb1c3c28p-6, -0x1.befe18031ec3dp-8,
- 0x1.449f5ee175c69p-10},
- {0x1.554ae1f5ae815p-2, -0x1.c53c6b14ff6b2p-4, 0x1.e6b2d5127bb5bp-5,
- -0x1.19387336788a3p-5, 0x1.180955a6ab255p-6, -0x1.81696703ba369p-8,
- 0x1.02cb36389bd79p-10},
- {0x1.55458a59f356ep-2, -0x1.c4820dd631ae9p-4, 0x1.e167af818bd15p-5,
- -0x1.0ef35f6f72e52p-5, 0x1.019c33b65e4ebp-6, -0x1.4d25bdd52d3a5p-8,
- 0x1.a008ae91f5936p-11},
- {0x1.553e878eafee1p-2, -0x1.c3a1d0b2a3db2p-4, 0x1.db90d8ed9f89bp-5,
- -0x1.0490e20f1ae91p-5, 0x1.d9a5d1fc42fe3p-7, -0x1.20bf8227c2abfp-8,
- 0x1.50f8174cdb6e9p-11},
- {0x1.5535a0dedf1b1p-2, -0x1.c29afb8bd01a1p-4, 0x1.d53f6371c1e27p-5,
- -0x1.f463209b433e2p-6, 0x1.b35222a17e44p-7, -0x1.f5efbf505e133p-9,
- 0x1.12e0e94e8586dp-11},
- {0x1.552aa25e57bfdp-2, -0x1.c16d811e4acadp-4, 0x1.ce8489b47aa51p-5,
- -0x1.dfde7ff758ea8p-6, 0x1.901f43aac38c8p-7, -0x1.b581d07df5ad5p-9,
- 0x1.c3726535f1fc6p-12},
- {0x1.551d5d9b204d3p-2, -0x1.c019e328f8db1p-4, 0x1.c7710f44fc3cep-5,
- -0x1.cbbbe25ea8ba4p-6, 0x1.6fe270088623dp-7, -0x1.7e6fc79733761p-9,
- 0x1.75077abf18d84p-12},
-};
-
-} // anonymous namespace
-
-LLVM_LIBC_FUNCTION(float, cbrtf, (float x)) {
- using FloatBits = typename fputil::FPBits<float>;
- using DoubleBits = typename fputil::FPBits<double>;
-
- FloatBits x_bits(x);
-
- uint32_t x_abs = x_bits.uintval() & 0x7fff'ffff;
- uint32_t sign_bit = (x_bits.uintval() >> 31) << DoubleBits::EXP_LEN;
-
- if (LIBC_UNLIKELY(x == 0.0f || x_abs >= 0x7f80'0000)) {
- // x is 0, Inf, or NaN.
- // Make sure it works for FTZ/DAZ modes.
- return x + x;
- }
-
- double xd = static_cast<double>(x);
- DoubleBits xd_bits(xd);
-
- // When using biased exponent of x in double precision,
- // x_e = real_exponent_of_x + 1023
- // Then:
- // x_e / 3 = real_exponent_of_x / 3 + 1023/3
- // = real_exponent_of_x / 3 + 341
- // So to make it the correct biased exponent of x^(1/3), we add
- // 1023 - 341 = 682
- // to the quotient x_e / 3.
- unsigned x_e = static_cast<unsigned>(xd_bits.get_biased_exponent());
- unsigned out_e = (x_e / 3 + 682) | sign_bit;
- unsigned shift_e = x_e % 3;
-
- // Set x_m = 2^(x_e % 3) * (1.mantissa)
- uint64_t x_m = xd_bits.get_mantissa();
- // Use the leading 4 bits for look up table
- unsigned idx = static_cast<unsigned>(x_m >> (DoubleBits::FRACTION_LEN - 4));
-
- x_m |= static_cast<uint64_t>(DoubleBits::EXP_BIAS)
- << DoubleBits::FRACTION_LEN;
-
- double x_reduced = DoubleBits(x_m).get_val();
- double dx = x_reduced - 1.0;
-
- double dx_sq = dx * dx;
- double c0 = fputil::multiply_add(dx, COEFFS[idx][0], 1.0);
- double c1 = fputil::multiply_add(dx, COEFFS[idx][2], COEFFS[idx][1]);
- double c2 = fputil::multiply_add(dx, COEFFS[idx][4], COEFFS[idx][3]);
- double c3 = fputil::multiply_add(dx, COEFFS[idx][6], COEFFS[idx][5]);
-
- double dx_4 = dx_sq * dx_sq;
- double p0 = fputil::multiply_add(dx_sq, c1, c0);
- double p1 = fputil::multiply_add(dx_sq, c3, c2);
-
- double r = fputil::multiply_add(dx_4, p1, p0) * CBRT2[shift_e];
-
- uint64_t r_m = DoubleBits(r).get_mantissa();
- // Check if the output is exact. To be exact, the smallest 1-bit of the
- // output has to be at least 2^-7 or higher. So we check the lowest 44 bits
- // to see if they are within 2^(-52 + 3) errors from all zeros, then the
- // result cube root is exact.
- if (LIBC_UNLIKELY(((r_m + 8) & 0xfffffffffff) <= 16)) {
- if ((r_m & 0xfffffffffff) <= 8)
- r_m &= 0xffff'ffff'ffff'ffe0;
- else
- r_m = (r_m & 0xffff'ffff'ffff'ffe0) + 0x20;
- fputil::clear_except_if_required(FE_INEXACT);
- }
- // Adjust exponent and sign.
- uint64_t r_bits =
- r_m | (static_cast<uint64_t>(out_e) << DoubleBits::FRACTION_LEN);
-
- return static_cast<float>(DoubleBits(r_bits).get_val());
-}
+LLVM_LIBC_FUNCTION(float, cbrtf, (float x)) { return math::cbrtf(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/ceilbf16.cpp b/libc/src/math/generic/ceilbf16.cpp
new file mode 100644
index 0000000..441dcf0
--- /dev/null
+++ b/libc/src/math/generic/ceilbf16.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ceilbf16 function -------------------------------===//
+//
+// 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/math/ceilbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, ceilbf16, (bfloat16 x)) { return fputil::ceil(x); }
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/copysignbf16.cpp b/libc/src/math/generic/copysignbf16.cpp
new file mode 100644
index 0000000..48ade2b
--- /dev/null
+++ b/libc/src/math/generic/copysignbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of copysignbf16 function ---------------------------===//
+//
+// 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/math/copysignbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, copysignbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::copysign(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/cos.cpp b/libc/src/math/generic/cos.cpp
index 5da0f868..aabf3bc 100644
--- a/libc/src/math/generic/cos.cpp
+++ b/libc/src/math/generic/cos.cpp
@@ -7,161 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/cos.h"
-#include "hdr/errno_macros.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/except_value_utils.h"
-#include "src/__support/common.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/math/generic/range_reduction_double_common.h"
-#include "src/math/generic/sincos_eval.h"
-
-#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
-#include "range_reduction_double_fma.h"
-#else
-#include "range_reduction_double_nofma.h"
-#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+#include "src/__support/math/cos.h"
namespace LIBC_NAMESPACE_DECL {
-using DoubleDouble = fputil::DoubleDouble;
-using Float128 = typename fputil::DyadicFloat<128>;
-
-LLVM_LIBC_FUNCTION(double, cos, (double x)) {
- using FPBits = typename fputil::FPBits<double>;
- FPBits xbits(x);
-
- uint16_t x_e = xbits.get_biased_exponent();
-
- DoubleDouble y;
- unsigned k;
- LargeRangeReduction range_reduction_large{};
-
- // |x| < 2^16.
- if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) {
- // |x| < 2^-7
- if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 7)) {
- // |x| < 2^-27
- if (LIBC_UNLIKELY(x_e < FPBits::EXP_BIAS - 27)) {
- // Signed zeros.
- if (LIBC_UNLIKELY(x == 0.0))
- return 1.0;
-
- // For |x| < 2^-27, |cos(x) - 1| < |x|^2/2 < 2^-54 = ulp(1 - 2^-53)/2.
- return fputil::round_result_slightly_down(1.0);
- }
- // No range reduction needed.
- k = 0;
- y.lo = 0.0;
- y.hi = x;
- } else {
- // Small range reduction.
- k = range_reduction_small(x, y);
- }
- } else {
- // Inf or NaN
- if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
- // cos(+-Inf) = NaN
- if (xbits.get_mantissa() == 0) {
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- }
- return x + FPBits::quiet_nan().get_val();
- }
-
- // Large range reduction.
- k = range_reduction_large.fast(x, y);
- }
-
- DoubleDouble sin_y, cos_y;
-
- [[maybe_unused]] double err = generic::sincos_eval(y, sin_y, cos_y);
-
- // Look up sin(k * pi/128) and cos(k * pi/128)
-#ifdef LIBC_MATH_HAS_SMALL_TABLES
- // Memory saving versions. Use 65-entry table.
- auto get_idx_dd = [](unsigned kk) -> DoubleDouble {
- unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63);
- DoubleDouble ans = SIN_K_PI_OVER_128[idx];
- if (kk & 128) {
- ans.hi = -ans.hi;
- ans.lo = -ans.lo;
- }
- return ans;
- };
- DoubleDouble msin_k = get_idx_dd(k + 128);
- DoubleDouble cos_k = get_idx_dd(k + 64);
-#else
- // Fast look up version, but needs 256-entry table.
- // -sin(k * pi/128) = sin((k + 128) * pi/128)
- // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128).
- DoubleDouble msin_k = SIN_K_PI_OVER_128[(k + 128) & 255];
- DoubleDouble cos_k = SIN_K_PI_OVER_128[(k + 64) & 255];
-#endif // LIBC_MATH_HAS_SMALL_TABLES
-
- // After range reduction, k = round(x * 128 / pi) and y = x - k * (pi / 128).
- // So k is an integer and -pi / 256 <= y <= pi / 256.
- // Then cos(x) = cos((k * pi/128 + y)
- // = cos(y) * cos(k*pi/128) - sin(y) * sin(k*pi/128)
- DoubleDouble cos_k_cos_y = fputil::quick_mult(cos_y, cos_k);
- DoubleDouble msin_k_sin_y = fputil::quick_mult(sin_y, msin_k);
-
- DoubleDouble rr = fputil::exact_add<false>(cos_k_cos_y.hi, msin_k_sin_y.hi);
- rr.lo += msin_k_sin_y.lo + cos_k_cos_y.lo;
-
-#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- return rr.hi + rr.lo;
-#else
-
- double rlp = rr.lo + err;
- double rlm = rr.lo - err;
-
- double r_upper = rr.hi + rlp; // (rr.lo + ERR);
- double r_lower = rr.hi + rlm; // (rr.lo - ERR);
-
- // Ziv's rounding test.
- if (LIBC_LIKELY(r_upper == r_lower))
- return r_upper;
-
- Float128 u_f128, sin_u, cos_u;
- if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT))
- u_f128 = range_reduction_small_f128(x);
- else
- u_f128 = range_reduction_large.accurate();
-
- generic::sincos_eval(u_f128, sin_u, cos_u);
-
- auto get_sin_k = [](unsigned kk) -> Float128 {
- unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63);
- Float128 ans = SIN_K_PI_OVER_128_F128[idx];
- if (kk & 128)
- ans.sign = Sign::NEG;
- return ans;
- };
-
- // -sin(k * pi/128) = sin((k + 128) * pi/128)
- // cos(k * pi/128) = sin(k * pi/128 + pi/2) = sin((k + 64) * pi/128).
- Float128 msin_k_f128 = get_sin_k(k + 128);
- Float128 cos_k_f128 = get_sin_k(k + 64);
-
- // cos(x) = cos((k * pi/128 + u)
- // = cos(u) * cos(k*pi/128) - sin(u) * sin(k*pi/128)
- Float128 r = fputil::quick_add(fputil::quick_mul(cos_k_f128, cos_u),
- fputil::quick_mul(msin_k_f128, sin_u));
-
- // TODO: Add assertion if Ziv's accuracy tests fail in debug mode.
- // https://github.com/llvm/llvm-project/issues/96452.
-
- return static_cast<double>(r);
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-}
+LLVM_LIBC_FUNCTION(double, cos, (double x)) { return math::cos(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/cosf.cpp b/libc/src/math/generic/cosf.cpp
index 7cdae09..5c23d99 100644
--- a/libc/src/math/generic/cosf.cpp
+++ b/libc/src/math/generic/cosf.cpp
@@ -7,139 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/cosf.h"
-#include "sincosf_utils.h"
-#include "src/__support/FPUtil/BasicOperations.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/common.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/cosf.h"
namespace LIBC_NAMESPACE_DECL {
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-// Exceptional cases for cosf.
-static constexpr size_t N_EXCEPTS = 6;
-
-static constexpr fputil::ExceptValues<float, N_EXCEPTS> COSF_EXCEPTS{{
- // (inputs, RZ output, RU offset, RD offset, RN offset)
- // x = 0x1.64a032p43, cos(x) = 0x1.9d4ba4p-1 (RZ)
- {0x55325019, 0x3f4ea5d2, 1, 0, 0},
- // x = 0x1.4555p51, cos(x) = 0x1.115d7cp-1 (RZ)
- {0x5922aa80, 0x3f08aebe, 1, 0, 1},
- // x = 0x1.48a858p54, cos(x) = 0x1.f48148p-2 (RZ)
- {0x5aa4542c, 0x3efa40a4, 1, 0, 0},
- // x = 0x1.3170fp63, cos(x) = 0x1.fe2976p-1 (RZ)
- {0x5f18b878, 0x3f7f14bb, 1, 0, 0},
- // x = 0x1.2b9622p67, cos(x) = 0x1.f0285cp-1 (RZ)
- {0x6115cb11, 0x3f78142e, 1, 0, 1},
- // x = 0x1.ddebdep120, cos(x) = 0x1.114438p-1 (RZ)
- {0x7beef5ef, 0x3f08a21c, 1, 0, 0},
-}};
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-LLVM_LIBC_FUNCTION(float, cosf, (float x)) {
- using FPBits = typename fputil::FPBits<float>;
-
- FPBits xbits(x);
- xbits.set_sign(Sign::POS);
-
- uint32_t x_abs = xbits.uintval();
- double xd = static_cast<double>(xbits.get_val());
-
- // Range reduction:
- // For |x| > pi/16, we perform range reduction as follows:
- // Find k and y such that:
- // x = (k + y) * pi/32
- // k is an integer
- // |y| < 0.5
- // For small range (|x| < 2^45 when FMA instructions are available, 2^22
- // otherwise), this is done by performing:
- // k = round(x * 32/pi)
- // y = x * 32/pi - k
- // For large range, we will omit all the higher parts of 16/pi such that the
- // least significant bits of their full products with x are larger than 63,
- // since cos((k + y + 64*i) * pi/32) = cos(x + i * 2pi) = cos(x).
- //
- // When FMA instructions are not available, we store the digits of 32/pi in
- // chunks of 28-bit precision. This will make sure that the products:
- // x * THIRTYTWO_OVER_PI_28[i] are all exact.
- // When FMA instructions are available, we simply store the digits of 32/pi in
- // chunks of doubles (53-bit of precision).
- // So when multiplying by the largest values of single precision, the
- // resulting output should be correct up to 2^(-208 + 128) ~ 2^-80. By the
- // worst-case analysis of range reduction, |y| >= 2^-38, so this should give
- // us more than 40 bits of accuracy. For the worst-case estimation of range
- // reduction, see for instances:
- // Elementary Functions by J-M. Muller, Chapter 11,
- // Handbook of Floating-Point Arithmetic by J-M. Muller et. al.,
- // Chapter 10.2.
- //
- // Once k and y are computed, we then deduce the answer by the cosine of sum
- // formula:
- // cos(x) = cos((k + y)*pi/32)
- // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
- // The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed
- // and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are
- // computed using degree-7 and degree-6 minimax polynomials generated by
- // Sollya respectively.
-
- // |x| < 0x1.0p-12f
- if (LIBC_UNLIKELY(x_abs < 0x3980'0000U)) {
- // When |x| < 2^-12, the relative error of the approximation cos(x) ~ 1
- // is:
- // |cos(x) - 1| < |x^2 / 2| = 2^-25 < epsilon(1)/2.
- // So the correctly rounded values of cos(x) are:
- // = 1 - eps(x) if rounding mode = FE_TOWARDZERO or FE_DOWWARD,
- // = 1 otherwise.
- // To simplify the rounding decision and make it more efficient and to
- // prevent compiler to perform constant folding, we use
- // fma(x, -2^-25, 1) instead.
- // Note: to use the formula 1 - 2^-25*x to decide the correct rounding, we
- // do need fma(x, -2^-25, 1) 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(xbits.get_val(), -0x1.0p-25f, 1.0f);
-#else
- return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0));
-#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
- }
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- if (auto r = COSF_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value()))
- return r.value();
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // x is inf or nan.
- 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();
- }
-
- 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();
- }
-
- // Combine the results with the sine of sum formula:
- // cos(x) = cos((k + y)*pi/32)
- // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
- // = cosm1_y * cos_k + sin_y * sin_k
- // = (cosm1_y * cos_k + cos_k) + sin_y * sin_k
- double sin_k, cos_k, sin_y, cosm1_y;
-
- sincosf_eval(xd, x_abs, sin_k, cos_k, sin_y, cosm1_y);
-
- return static_cast<float>(fputil::multiply_add(
- sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k)));
-}
+LLVM_LIBC_FUNCTION(float, cosf, (float x)) { return math::cosf(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/cosf16.cpp b/libc/src/math/generic/cosf16.cpp
index 99bb03e..031c3e1 100644
--- a/libc/src/math/generic/cosf16.cpp
+++ b/libc/src/math/generic/cosf16.cpp
@@ -7,87 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/cosf16.h"
-#include "hdr/errno_macros.h"
-#include "hdr/fenv_macros.h"
-#include "sincosf16_utils.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.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/macros/optimization.h"
+#include "src/__support/math/cosf16.h"
namespace LIBC_NAMESPACE_DECL {
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-constexpr size_t N_EXCEPTS = 4;
-
-constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{
- // (input, RZ output, RU offset, RD offset, RN offset)
- {0x2b7c, 0x3bfc, 1, 0, 1},
- {0x4ac1, 0x38b5, 1, 0, 0},
- {0x5c49, 0xb8c6, 0, 1, 0},
- {0x7acc, 0xa474, 0, 1, 0},
-}};
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-LLVM_LIBC_FUNCTION(float16, cosf16, (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;
-
- // Range reduction:
- // For |x| > pi/32, we perform range reduction as follows:
- // Find k and y such that:
- // x = (k + y) * pi/32
- // k is an integer, |y| < 0.5
- //
- // This is done by performing:
- // k = round(x * 32/pi)
- // y = x * 32/pi - k
- //
- // Once k and y are computed, we then deduce the answer by the cosine of sum
- // formula:
- // cos(x) = cos((k + y) * pi/32)
- // = cos(k * pi/32) * cos(y * pi/32) -
- // sin(k * pi/32) * sin(y * pi/32)
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- // Handle exceptional values
- if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value()))
- return r.value();
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- // cos(+/-0) = 1
- if (LIBC_UNLIKELY(x_abs == 0U))
- return fputil::cast<float16>(1.0f);
-
- // cos(+/-inf) = NaN, and cos(NaN) = NaN
- if (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_inf()) {
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- }
-
- return x + FPBits::quiet_nan().get_val();
- }
-
- float sin_k, cos_k, sin_y, cosm1_y;
- sincosf16_eval(xf, sin_k, cos_k, sin_y, cosm1_y);
- // Since, cosm1_y = cos_y - 1, therefore:
- // cos(x) = cos_k * cos_y - sin_k * sin_y
- // = cos_k * (cos_y - 1 + 1) - sin_k * sin_y
- // = cos_k * cosm1_y - sin_k * sin_y + cos_k
- return fputil::cast<float16>(fputil::multiply_add(
- cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k)));
-}
+LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) { return math::cosf16(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/coshf.cpp b/libc/src/math/generic/coshf.cpp
index 9f87564..368c0fd 100644
--- a/libc/src/math/generic/coshf.cpp
+++ b/libc/src/math/generic/coshf.cpp
@@ -7,50 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/coshf.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/rounding_mode.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/math/generic/explogxf.h"
+#include "src/__support/math/coshf.h"
namespace LIBC_NAMESPACE_DECL {
-LLVM_LIBC_FUNCTION(float, coshf, (float x)) {
- using FPBits = typename fputil::FPBits<float>;
-
- FPBits xbits(x);
- xbits.set_sign(Sign::POS);
- x = xbits.get_val();
-
- uint32_t x_u = xbits.uintval();
-
- // When |x| >= 90, or x is inf or nan
- if (LIBC_UNLIKELY(x_u >= 0x42b4'0000U || x_u <= 0x3280'0000U)) {
- // |x| <= 2^-26
- if (x_u <= 0x3280'0000U) {
- return 1.0f + x;
- }
-
- if (xbits.is_inf_or_nan())
- return x + FPBits::inf().get_val();
-
- int rounding = fputil::quick_get_round();
- if (LIBC_UNLIKELY(rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO))
- return FPBits::max_normal().get_val();
-
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_OVERFLOW);
-
- return x + FPBits::inf().get_val();
- }
-
- // TODO: We should be able to reduce the latency and reciprocal throughput
- // further by using a low degree (maybe 3-7 ?) minimax polynomial for small
- // but not too small inputs, such as |x| < 2^-2, or |x| < 2^-3.
-
- // cosh(x) = (e^x + e^(-x)) / 2.
- return static_cast<float>(exp_pm_eval</*is_sinh*/ false>(x));
-}
+LLVM_LIBC_FUNCTION(float, coshf, (float x)) { return math::coshf(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/coshf16.cpp b/libc/src/math/generic/coshf16.cpp
index 689d16a..d86edd9 100644
--- a/libc/src/math/generic/coshf16.cpp
+++ b/libc/src/math/generic/coshf16.cpp
@@ -7,105 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/coshf16.h"
-#include "expxf16.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/except_value_utils.h"
-#include "src/__support/FPUtil/rounding_mode.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/optimization.h"
+#include "src/__support/math/coshf16.h"
namespace LIBC_NAMESPACE_DECL {
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-static constexpr fputil::ExceptValues<float16, 9> COSHF16_EXCEPTS_POS = {{
- // x = 0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
- {0x29a8U, 0x3c00U, 1U, 0U, 1U},
- // x = 0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)
- {0x3e31U, 0x40eaU, 1U, 0U, 0U},
- // x = 0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)
- {0x3e65U, 0x4126U, 1U, 0U, 0U},
- // x = 0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)
- {0x3ed8U, 0x41b6U, 1U, 0U, 1U},
- // x = 0x1.aap+1, coshf16(x) = 0x1.be8p+3 (RZ)
- {0x42a8U, 0x4afaU, 1U, 0U, 1U},
- // x = 0x1.cc4p+1, coshf16(x) = 0x1.23cp+4 (RZ)
- {0x4331U, 0x4c8fU, 1U, 0U, 0U},
- // x = 0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)
- {0x44a2U, 0x526dU, 1U, 0U, 0U},
- // x = 0x1.958p+2, coshf16(x) = 0x1.1a4p+8 (RZ)
- {0x4656U, 0x5c69U, 1U, 0U, 0U},
- // x = 0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
- {0x497cU, 0x7715U, 1U, 0U, 1U},
-}};
-
-static constexpr fputil::ExceptValues<float16, 6> COSHF16_EXCEPTS_NEG = {{
- // x = -0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
- {0xa9a8U, 0x3c00U, 1U, 0U, 1U},
- // x = -0x1.b6p+0, coshf16(x) = 0x1.6d8p+1 (RZ)
- {0xbed8U, 0x41b6U, 1U, 0U, 1U},
- // x = -0x1.288p+2, coshf16(x) = 0x1.9b4p+5 (RZ)
- {0xc4a2U, 0x526dU, 1U, 0U, 0U},
- // x = -0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
- {0xc97cU, 0x7715U, 1U, 0U, 1U},
- // x = -0x1.8c4p+0, coshf16(x) = 0x1.3a8p+1 (RZ)
- {0xbe31U, 0x40eaU, 1U, 0U, 0U},
- // x = -0x1.994p+0, coshf16(x) = 0x1.498p+1 (RZ)
- {0xbe65U, 0x4126U, 1U, 0U, 0U},
-}};
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
-LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) {
- using FPBits = fputil::FPBits<float16>;
- FPBits x_bits(x);
-
- uint16_t x_u = x_bits.uintval();
- uint16_t x_abs = x_u & 0x7fffU;
-
- // When |x| >= acosh(2^16), or x is NaN.
- if (LIBC_UNLIKELY(x_abs >= 0x49e5U)) {
- // cosh(NaN) = NaN
- if (x_bits.is_nan()) {
- if (x_bits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
-
- return x;
- }
-
- // When |x| >= acosh(2^16).
- if (x_abs >= 0x49e5U) {
- // cosh(+/-inf) = +inf
- if (x_bits.is_inf())
- return FPBits::inf().get_val();
-
- switch (fputil::quick_get_round()) {
- case FE_TONEAREST:
- case FE_UPWARD:
- fputil::set_errno_if_required(ERANGE);
- fputil::raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
- return FPBits::inf().get_val();
- default:
- return FPBits::max_normal().get_val();
- }
- }
- }
-
-#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
- if (x_bits.is_pos()) {
- if (auto r = COSHF16_EXCEPTS_POS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
- return r.value();
- } else {
- if (auto r = COSHF16_EXCEPTS_NEG.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
- return r.value();
- }
-#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
- return eval_sinh_or_cosh</*IsSinh=*/false>(x);
-}
+LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) { return math::coshf16(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/cospif.cpp b/libc/src/math/generic/cospif.cpp
index 5b6880f..b9a4637 100644
--- a/libc/src/math/generic/cospif.cpp
+++ b/libc/src/math/generic/cospif.cpp
@@ -7,95 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/cospif.h"
-#include "sincosf_utils.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.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/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
+#include "src/__support/math/cospif.h"
namespace LIBC_NAMESPACE_DECL {
-LLVM_LIBC_FUNCTION(float, cospif, (float x)) {
- using FPBits = typename fputil::FPBits<float>;
-
- FPBits xbits(x);
- xbits.set_sign(Sign::POS);
-
- uint32_t x_abs = xbits.uintval();
- double xd = static_cast<double>(xbits.get_val());
-
- // Range reduction:
- // For |x| > 1/32, we perform range reduction as follows:
- // Find k and y such that:
- // x = (k + y) * 1/32
- // k is an integer
- // |y| < 0.5
- //
- // This is done by performing:
- // k = round(x * 32)
- // y = x * 32 - k
- //
- // Once k and y are computed, we then deduce the answer by the cosine of sum
- // formula:
- // cospi(x) = cos((k + y)*pi/32)
- // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
- // The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed
- // and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are
- // computed using degree-7 and degree-6 minimax polynomials generated by
- // Sollya respectively.
-
- // The exhautive test passes for smaller values
- if (LIBC_UNLIKELY(x_abs < 0x38A2'F984U)) {
-
-#if defined(LIBC_TARGET_CPU_HAS_FMA_FLOAT)
- return fputil::multiply_add(xbits.get_val(), -0x1.0p-25f, 1.0f);
-#else
- return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0));
-#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
- }
-
- // Numbers greater or equal to 2^23 are always integers or NaN
- if (LIBC_UNLIKELY(x_abs >= 0x4B00'0000)) {
-
- if (LIBC_UNLIKELY(x_abs < 0x4B80'0000)) {
- return (x_abs & 0x1) ? -1.0f : 1.0f;
- }
-
- // x is inf or nan.
- 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();
- }
-
- 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();
- }
-
- return 1.0f;
- }
-
- // Combine the results with the sine of sum formula:
- // cos(pi * x) = cos((k + y)*pi/32)
- // = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
- // = (cosm1_y + 1) * cos_k - sin_y * sin_k
- // = (cosm1_y * cos_k + cos_k) - sin_y * sin_k
- double sin_k, cos_k, sin_y, cosm1_y;
-
- sincospif_eval(xd, sin_k, cos_k, sin_y, cosm1_y);
-
- if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) {
- return 0.0f;
- }
-
- return static_cast<float>(fputil::multiply_add(
- sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k)));
-}
+LLVM_LIBC_FUNCTION(float, cospif, (float x)) { return math::cospif(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/cospif16.cpp b/libc/src/math/generic/cospif16.cpp
index 9dc2592..a4bae8e 100644
--- a/libc/src/math/generic/cospif16.cpp
+++ b/libc/src/math/generic/cospif16.cpp
@@ -7,79 +7,10 @@
//===----------------------------------------------------------------------===//
#include "src/math/cospif16.h"
-#include "hdr/errno_macros.h"
-#include "hdr/fenv_macros.h"
-#include "sincosf16_utils.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/cast.h"
-#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/macros/optimization.h"
+#include "src/__support/math/cospif16.h"
namespace LIBC_NAMESPACE_DECL {
-LLVM_LIBC_FUNCTION(float16, cospif16, (float16 x)) {
- using FPBits = typename fputil::FPBits<float16>;
- FPBits xbits(x);
-
- uint16_t x_u = xbits.uintval();
- uint16_t x_abs = x_u & 0x7fff;
- float xf = x;
-
- // Range reduction:
- // For |x| > 1/32, we perform range reduction as follows:
- // Find k and y such that:
- // x = (k + y) * 1/32
- // k is an integer
- // |y| < 0.5
- //
- // This is done by performing:
- // k = round(x * 32)
- // y = x * 32 - k
- //
- // Once k and y are computed, we then deduce the answer by the cosine of sum
- // formula:
- // cos(x * pi) = cos((k + y) * pi/32)
- // = cos(k * pi/32) * cos(y * pi/32) +
- // sin(y * pi/32) * sin(k * pi/32)
-
- // For signed zeros
- if (LIBC_UNLIKELY(x_abs == 0U))
- return fputil::cast<float16>(1.0f);
-
- // Numbers greater or equal to 2^10 are integers, or infinity, or NaN
- if (LIBC_UNLIKELY(x_abs >= 0x6400)) {
- if (LIBC_UNLIKELY(x_abs <= 0x67FF))
- return fputil::cast<float16>((x_abs & 0x1) ? -1.0f : 1.0f);
-
- // Check for NaN or infintiy values
- if (LIBC_UNLIKELY(x_abs >= 0x7c00)) {
- if (xbits.is_signaling_nan()) {
- fputil::raise_except_if_required(FE_INVALID);
- return FPBits::quiet_nan().get_val();
- }
- // If value is equal to infinity
- if (x_abs == 0x7c00) {
- fputil::set_errno_if_required(EDOM);
- fputil::raise_except_if_required(FE_INVALID);
- }
-
- return x + FPBits::quiet_nan().get_val();
- }
-
- return fputil::cast<float16>(1.0f);
- }
-
- float sin_k, cos_k, sin_y, cosm1_y;
- sincospif16_eval(xf, sin_k, cos_k, sin_y, cosm1_y);
-
- if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0))
- return fputil::cast<float16>(0.0f);
-
- // Since, cosm1_y = cos_y - 1, therefore:
- // cos(x * pi) = cos_k(cosm1_y) + cos_k - sin_k * sin_y
- return fputil::cast<float16>(fputil::multiply_add(
- cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k)));
-}
+LLVM_LIBC_FUNCTION(float16, cospif16, (float16 x)) { return math::cospif16(x); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/exp10m1f.cpp b/libc/src/math/generic/exp10m1f.cpp
index 2772910..8589e3f 100644
--- a/libc/src/math/generic/exp10m1f.cpp
+++ b/libc/src/math/generic/exp10m1f.cpp
@@ -17,8 +17,7 @@
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
-
-#include "explogxf.h"
+#include "src/__support/math/exp10f_utils.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/exp2.cpp b/libc/src/math/generic/exp2.cpp
index 726f88b..154154f 100644
--- a/libc/src/math/generic/exp2.cpp
+++ b/libc/src/math/generic/exp2.cpp
@@ -8,7 +8,6 @@
#include "src/math/exp2.h"
#include "common_constants.h" // Lookup tables EXP2_MID1 and EXP_M2.
-#include "explogxf.h" // ziv_test_denorm.
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -24,6 +23,7 @@
#include "src/__support/integer_literals.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/exp_utils.h" // ziv_test_denorm.
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/exp2f16.cpp b/libc/src/math/generic/exp2f16.cpp
index 5c039c5..5db0c3a 100644
--- a/libc/src/math/generic/exp2f16.cpp
+++ b/libc/src/math/generic/exp2f16.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/exp2f16.h"
-#include "expxf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -18,6 +17,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
+#include "src/__support/math/expxf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -34,6 +34,7 @@ static constexpr fputil::ExceptValues<float16, 3> EXP2F16_EXCEPTS = {{
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, exp2f16, (float16 x)) {
+ using namespace math::expxf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits x_bits(x);
diff --git a/libc/src/math/generic/exp2f_impl.h b/libc/src/math/generic/exp2f_impl.h
index 5c6c2bd..b85bb15 100644
--- a/libc/src/math/generic/exp2f_impl.h
+++ b/libc/src/math/generic/exp2f_impl.h
@@ -20,8 +20,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/__support/macros/properties/cpu_features.h"
-
-#include "explogxf.h"
+#include "src/__support/math/exp10f_utils.h"
namespace LIBC_NAMESPACE_DECL {
namespace generic {
diff --git a/libc/src/math/generic/exp2m1f.cpp b/libc/src/math/generic/exp2m1f.cpp
index 127c6ea..16244ed 100644
--- a/libc/src/math/generic/exp2m1f.cpp
+++ b/libc/src/math/generic/exp2m1f.cpp
@@ -18,8 +18,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/cpu_features.h"
-
-#include "explogxf.h"
+#include "src/__support/math/exp10f_utils.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/exp2m1f16.cpp b/libc/src/math/generic/exp2m1f16.cpp
index 61633cd..ce0cc60 100644
--- a/libc/src/math/generic/exp2m1f16.cpp
+++ b/libc/src/math/generic/exp2m1f16.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/exp2m1f16.h"
-#include "expxf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -21,6 +20,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/expxf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -76,6 +76,7 @@ static constexpr fputil::ExceptValues<float16, N_EXP2M1F16_EXCEPTS_HI>
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, exp2m1f16, (float16 x)) {
+ using namespace math::expxf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits x_bits(x);
diff --git a/libc/src/math/generic/expm1.cpp b/libc/src/math/generic/expm1.cpp
index a4dbf38..c360554 100644
--- a/libc/src/math/generic/expm1.cpp
+++ b/libc/src/math/generic/expm1.cpp
@@ -8,9 +8,7 @@
#include "src/math/expm1.h"
#include "common_constants.h" // Lookup tables EXP_M1 and EXP_M2.
-#include "explogxf.h" // ziv_test_denorm.
#include "src/__support/CPP/bit.h"
-#include "src/__support/CPP/optional.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -18,7 +16,6 @@
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/except_value_utils.h"
#include "src/__support/FPUtil/multiply_add.h"
-#include "src/__support/FPUtil/nearest_integer.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/FPUtil/triple_double.h"
#include "src/__support/common.h"
diff --git a/libc/src/math/generic/expm1f16.cpp b/libc/src/math/generic/expm1f16.cpp
index 2188dfb..c2231f0 100644
--- a/libc/src/math/generic/expm1f16.cpp
+++ b/libc/src/math/generic/expm1f16.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/expm1f16.h"
-#include "expxf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -20,6 +19,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
+#include "src/__support/math/expxf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -51,6 +51,7 @@ static constexpr fputil::ExceptValues<float16, N_EXPM1F16_EXCEPTS_HI>
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, expm1f16, (float16 x)) {
+ using namespace math::expxf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits x_bits(x);
diff --git a/libc/src/math/generic/fdimbf16.cpp b/libc/src/math/generic/fdimbf16.cpp
new file mode 100644
index 0000000..0f54055
--- /dev/null
+++ b/libc/src/math/generic/fdimbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fdimbf16 function -------------------------------===//
+//
+// 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/math/fdimbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fdimbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fdim(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/floorbf16.cpp b/libc/src/math/generic/floorbf16.cpp
new file mode 100644
index 0000000..d157096
--- /dev/null
+++ b/libc/src/math/generic/floorbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of floorbf16 function ------------------------------===//
+//
+// 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/math/floorbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, floorbf16, (bfloat16 x)) {
+ return fputil::floor(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fmaxbf16.cpp b/libc/src/math/generic/fmaxbf16.cpp
new file mode 100644
index 0000000..01d395b
--- /dev/null
+++ b/libc/src/math/generic/fmaxbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fmaxbf16 function -------------------------------===//
+//
+// 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/math/fmaxbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fmaxbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fmax(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fmaximum_mag_numbf16.cpp b/libc/src/math/generic/fmaximum_mag_numbf16.cpp
new file mode 100644
index 0000000..485e3295
--- /dev/null
+++ b/libc/src/math/generic/fmaximum_mag_numbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fmaximum_mag_numbf16 function -------------------===//
+//
+// 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/math/fmaximum_mag_numbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fmaximum_mag_numbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fmaximum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fmaximum_magbf16.cpp b/libc/src/math/generic/fmaximum_magbf16.cpp
new file mode 100644
index 0000000..0654ed9
--- /dev/null
+++ b/libc/src/math/generic/fmaximum_magbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fmaximum_magbf16 function -----------------------===//
+//
+// 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/math/fmaximum_magbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fmaximum_magbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fmaximum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fmaximum_numbf16.cpp b/libc/src/math/generic/fmaximum_numbf16.cpp
new file mode 100644
index 0000000..b058d50
--- /dev/null
+++ b/libc/src/math/generic/fmaximum_numbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fmaximum_numbf16 function -----------------------===//
+//
+// 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/math/fmaximum_numbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fmaximum_numbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fmaximum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fmaximumbf16.cpp b/libc/src/math/generic/fmaximumbf16.cpp
new file mode 100644
index 0000000..e10830b
--- /dev/null
+++ b/libc/src/math/generic/fmaximumbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fmaximumbf16 function ---------------------------===//
+//
+// 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/math/fmaximumbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fmaximumbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fmaximum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fminbf16.cpp b/libc/src/math/generic/fminbf16.cpp
new file mode 100644
index 0000000..c3e29ee
--- /dev/null
+++ b/libc/src/math/generic/fminbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fminbf16 function -------------------------------===//
+//
+// 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/math/fminbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fminbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fmin(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fminimum_mag_numbf16.cpp b/libc/src/math/generic/fminimum_mag_numbf16.cpp
new file mode 100644
index 0000000..5056fc7
--- /dev/null
+++ b/libc/src/math/generic/fminimum_mag_numbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fminimum_mag_numbf16 function -------------------===//
+//
+// 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/math/fminimum_mag_numbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fminimum_mag_numbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fminimum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fminimum_magbf16.cpp b/libc/src/math/generic/fminimum_magbf16.cpp
new file mode 100644
index 0000000..f61d2d2
--- /dev/null
+++ b/libc/src/math/generic/fminimum_magbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fminimum_magbf16 function -----------------------===//
+//
+// 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/math/fminimum_magbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fminimum_magbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fminimum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fminimum_numbf16.cpp b/libc/src/math/generic/fminimum_numbf16.cpp
new file mode 100644
index 0000000..079a830
--- /dev/null
+++ b/libc/src/math/generic/fminimum_numbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fminimum_numbf16 function -----------------------===//
+//
+// 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/math/fminimum_numbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fminimum_numbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fminimum_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fminimumbf16.cpp b/libc/src/math/generic/fminimumbf16.cpp
new file mode 100644
index 0000000..da976b9
--- /dev/null
+++ b/libc/src/math/generic/fminimumbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fminimumbf16 function ---------------------------===//
+//
+// 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/math/fminimumbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fminimumbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::fminimum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fmodbf16.cpp b/libc/src/math/generic/fmodbf16.cpp
new file mode 100644
index 0000000..902a680
--- /dev/null
+++ b/libc/src/math/generic/fmodbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fmodbf16 function -------------------------------===//
+//
+// 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/math/fmodbf16.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/FPUtil/generic/FMod.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fmodbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::generic::FMod<bfloat16>::eval(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/frexpbf16.cpp b/libc/src/math/generic/frexpbf16.cpp
new file mode 100644
index 0000000..004f64f
--- /dev/null
+++ b/libc/src/math/generic/frexpbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of frexpbf16 function ------------------------------===//
+//
+// 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/math/frexpbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, frexpbf16, (bfloat16 x, int *exp)) {
+ return fputil::frexp(x, *exp);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fromfpbf16.cpp b/libc/src/math/generic/fromfpbf16.cpp
new file mode 100644
index 0000000..db1b8f1
--- /dev/null
+++ b/libc/src/math/generic/fromfpbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of fromfpbf16 function -----------------------------===//
+//
+// 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/math/fromfpbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fromfpbf16,
+ (bfloat16 x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/fromfpxbf16.cpp b/libc/src/math/generic/fromfpxbf16.cpp
new file mode 100644
index 0000000..8c16c41
--- /dev/null
+++ b/libc/src/math/generic/fromfpxbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of fromfpxbf16 function ----------------------------===//
+//
+// 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/math/fromfpxbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, fromfpxbf16,
+ (bfloat16 x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/true>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/getpayloadbf16.cpp b/libc/src/math/generic/getpayloadbf16.cpp
new file mode 100644
index 0000000..544ed0a
--- /dev/null
+++ b/libc/src/math/generic/getpayloadbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of getpayloadbf16 function -------------------------===//
+//
+// 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/math/getpayloadbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, getpayloadbf16, (const bfloat16 *x)) {
+ return fputil::getpayload(*x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/hypotf16.cpp b/libc/src/math/generic/hypotf16.cpp
index d782c26..fa90069 100644
--- a/libc/src/math/generic/hypotf16.cpp
+++ b/libc/src/math/generic/hypotf16.cpp
@@ -48,16 +48,15 @@ LLVM_LIBC_FUNCTION(float16, hypotf16, (float16 x, float16 y)) {
return a_bits.get_val();
}
- // TODO: Investigate why replacing the return line below with:
- // return x_bits.get_val() + y_bits.get_val();
- // fails the hypotf16 smoke tests.
+ float af = fputil::cast<float>(a_bits.get_val());
+ float bf = fputil::cast<float>(b_bits.get_val());
+
+ // Compiler runtime basic operations for float16 might not be correctly
+ // rounded for all rounding modes.
if (LIBC_UNLIKELY(a_u - b_u >=
static_cast<uint16_t>((FPBits::FRACTION_LEN + 2)
<< FPBits::FRACTION_LEN)))
- return a_bits.get_val() + b_bits.get_val();
-
- float af = fputil::cast<float>(a_bits.get_val());
- float bf = fputil::cast<float>(b_bits.get_val());
+ return fputil::cast<float16>(af + bf);
// These squares are exact.
float a_sq = af * af;
diff --git a/libc/src/math/generic/ilogbbf16.cpp b/libc/src/math/generic/ilogbbf16.cpp
new file mode 100644
index 0000000..6811139
--- /dev/null
+++ b/libc/src/math/generic/ilogbbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of ilogbbf16 function ------------------------------===//
+//
+// 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/math/ilogbbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, ilogbbf16, (bfloat16 x)) {
+ return fputil::intlogb<int>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/iscanonicalbf16.cpp b/libc/src/math/generic/iscanonicalbf16.cpp
new file mode 100644
index 0000000..34c11bf
--- /dev/null
+++ b/libc/src/math/generic/iscanonicalbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of iscanonicalbf16 function ------------------------===//
+//
+// 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/math/iscanonicalbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, iscanonicalbf16, (bfloat16 x)) {
+ bfloat16 tmp;
+ return fputil::canonicalize(tmp, x) == 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/issignalingbf16.cpp b/libc/src/math/generic/issignalingbf16.cpp
new file mode 100644
index 0000000..3bb17ef
--- /dev/null
+++ b/libc/src/math/generic/issignalingbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of issignalingbf16 function ------------------------===//
+//
+// 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/math/issignalingbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, issignalingbf16, (bfloat16 x)) {
+ return fputil::issignaling_impl(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/ldexpbf16.cpp b/libc/src/math/generic/ldexpbf16.cpp
new file mode 100644
index 0000000..42a5039
--- /dev/null
+++ b/libc/src/math/generic/ldexpbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of ldexpbf16 function ------------------------------===//
+//
+// 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/math/ldexpbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, ldexpbf16, (bfloat16 x, int exp)) {
+ return fputil::ldexp(x, exp);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/llogbbf16.cpp b/libc/src/math/generic/llogbbf16.cpp
new file mode 100644
index 0000000..74c2762
--- /dev/null
+++ b/libc/src/math/generic/llogbbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of llogbbf16 function ------------------------------===//
+//
+// 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/math/llogbbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long, llogbbf16, (bfloat16 x)) {
+ return fputil::intlogb<long>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/llrintbf16.cpp b/libc/src/math/generic/llrintbf16.cpp
new file mode 100644
index 0000000..ec85454
--- /dev/null
+++ b/libc/src/math/generic/llrintbf16.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of llrintbf16 function -----------------------------===//
+//
+// 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/math/llrintbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long long, llrintbf16, (bfloat16 x)) {
+ return fputil::round_to_signed_integer_using_current_rounding_mode<bfloat16,
+ long long>(
+ x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/llroundbf16.cpp b/libc/src/math/generic/llroundbf16.cpp
new file mode 100644
index 0000000..2497b6b
--- /dev/null
+++ b/libc/src/math/generic/llroundbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of llroundbf16 function ----------------------------===//
+//
+// 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/math/llroundbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long long, llroundbf16, (bfloat16 x)) {
+ return fputil::round_to_signed_integer<bfloat16, long long>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/log10f16.cpp b/libc/src/math/generic/log10f16.cpp
index 2626af4..4bb684a 100644
--- a/libc/src/math/generic/log10f16.cpp
+++ b/libc/src/math/generic/log10f16.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/log10f16.h"
-#include "expxf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -20,6 +19,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/expxf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -75,6 +75,7 @@ static constexpr fputil::ExceptValues<float16, N_LOG10F16_EXCEPTS>
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, log10f16, (float16 x)) {
+ using namespace math::expxf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits x_bits(x);
diff --git a/libc/src/math/generic/log2f16.cpp b/libc/src/math/generic/log2f16.cpp
index 34be780..5b60323 100644
--- a/libc/src/math/generic/log2f16.cpp
+++ b/libc/src/math/generic/log2f16.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/log2f16.h"
-#include "expxf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -20,6 +19,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/expxf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -61,6 +61,7 @@ static constexpr fputil::ExceptValues<float16, N_LOG2F16_EXCEPTS>
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, log2f16, (float16 x)) {
+ using namespace math::expxf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits x_bits(x);
diff --git a/libc/src/math/generic/logbbf16.cpp b/libc/src/math/generic/logbbf16.cpp
new file mode 100644
index 0000000..5a43ddf
--- /dev/null
+++ b/libc/src/math/generic/logbbf16.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of logbbf16 function -------------------------------===//
+//
+// 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/math/logbbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, logbbf16, (bfloat16 x)) { return fputil::logb(x); }
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/logf16.cpp b/libc/src/math/generic/logf16.cpp
index 8e0d7d8..22e0dc8 100644
--- a/libc/src/math/generic/logf16.cpp
+++ b/libc/src/math/generic/logf16.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/logf16.h"
-#include "expxf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -20,6 +19,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/math/expxf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -68,6 +68,7 @@ static constexpr fputil::ExceptValues<float16, N_LOGF16_EXCEPTS>
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, logf16, (float16 x)) {
+ using namespace math::expxf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits x_bits(x);
diff --git a/libc/src/math/generic/lrintbf16.cpp b/libc/src/math/generic/lrintbf16.cpp
new file mode 100644
index 0000000..4b37890
--- /dev/null
+++ b/libc/src/math/generic/lrintbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of lrintbf16 function ------------------------------===//
+//
+// 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/math/lrintbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long, lrintbf16, (bfloat16 x)) {
+ return fputil::round_to_signed_integer_using_current_rounding_mode<bfloat16,
+ long>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/lroundbf16.cpp b/libc/src/math/generic/lroundbf16.cpp
new file mode 100644
index 0000000..89095d17
--- /dev/null
+++ b/libc/src/math/generic/lroundbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of lroundbf16 function -----------------------------===//
+//
+// 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/math/lroundbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long, lroundbf16, (bfloat16 x)) {
+ return fputil::round_to_signed_integer<bfloat16, long>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/modfbf16.cpp b/libc/src/math/generic/modfbf16.cpp
new file mode 100644
index 0000000..09458f6
--- /dev/null
+++ b/libc/src/math/generic/modfbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of modfbf16 function -------------------------------===//
+//
+// 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/math/modfbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, modfbf16, (bfloat16 x, bfloat16 *iptr)) {
+ return fputil::modf(x, *iptr);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/nanbf16.cpp b/libc/src/math/generic/nanbf16.cpp
new file mode 100644
index 0000000..678dd6a
--- /dev/null
+++ b/libc/src/math/generic/nanbf16.cpp
@@ -0,0 +1,25 @@
+//===-- Implementation of nanbf16 function --------------------------------===//
+//
+// 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/math/nanbf16.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/str_to_float.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, nanbf16, (const char *arg)) {
+ auto result = internal::strtonan<bfloat16>(arg);
+ if (result.has_error())
+ libc_errno = result.error;
+ return result.value;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/nearbyintbf16.cpp b/libc/src/math/generic/nearbyintbf16.cpp
new file mode 100644
index 0000000..a639199
--- /dev/null
+++ b/libc/src/math/generic/nearbyintbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of nearbyintbf16 function --------------------------===//
+//
+// 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/math/nearbyintbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, nearbyintbf16, (bfloat16 x)) {
+ return fputil::round_using_current_rounding_mode(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/nextafterbf16.cpp b/libc/src/math/generic/nextafterbf16.cpp
new file mode 100644
index 0000000..e21a2dc
--- /dev/null
+++ b/libc/src/math/generic/nextafterbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of nextafterbf16 function --------------------------===//
+//
+// 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/math/nextafterbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, nextafterbf16, (bfloat16 x, bfloat16 y)) {
+ return fputil::nextafter(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/nextdownbf16.cpp b/libc/src/math/generic/nextdownbf16.cpp
new file mode 100644
index 0000000..2115df9
--- /dev/null
+++ b/libc/src/math/generic/nextdownbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of nextdownbf16 function ---------------------------===//
+//
+// 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/math/nextdownbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, nextdownbf16, (bfloat16 x)) {
+ return fputil::nextupdown</*IsDown=*/true>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/nexttowardbf16.cpp b/libc/src/math/generic/nexttowardbf16.cpp
new file mode 100644
index 0000000..3deab87
--- /dev/null
+++ b/libc/src/math/generic/nexttowardbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of nexttowardbf16 function -------------------------===//
+//
+// 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/math/nexttowardbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, nexttowardbf16, (bfloat16 x, long double y)) {
+ // nextafter<T, U> where T != U is nexttoward
+ return fputil::nextafter(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/nextupbf16.cpp b/libc/src/math/generic/nextupbf16.cpp
new file mode 100644
index 0000000..147ce37
--- /dev/null
+++ b/libc/src/math/generic/nextupbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of nextupbf16 function -----------------------------===//
+//
+// 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/math/nextupbf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, nextupbf16, (bfloat16 x)) {
+ return fputil::nextupdown</*IsDown=*/false>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/remainderbf16.cpp b/libc/src/math/generic/remainderbf16.cpp
new file mode 100644
index 0000000..e70726a
--- /dev/null
+++ b/libc/src/math/generic/remainderbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of remainderbf16 function --------------------------===//
+//
+// 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/math/remainderbf16.h"
+#include "src/__support/FPUtil/DivisionAndRemainderOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, remainderbf16, (bfloat16 x, bfloat16 y)) {
+ int quotient;
+ return fputil::remquo(x, y, quotient);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/remquobf16.cpp b/libc/src/math/generic/remquobf16.cpp
new file mode 100644
index 0000000..e1b13f8
--- /dev/null
+++ b/libc/src/math/generic/remquobf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of remquobf16 function -----------------------------===//
+//
+// 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/math/remquobf16.h"
+#include "src/__support/FPUtil/DivisionAndRemainderOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, remquobf16, (bfloat16 x, bfloat16 y, int *exp)) {
+ return fputil::remquo(x, y, *exp);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/rintbf16.cpp b/libc/src/math/generic/rintbf16.cpp
new file mode 100644
index 0000000..2ffe16a
--- /dev/null
+++ b/libc/src/math/generic/rintbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of rintbf16 function -------------------------------===//
+//
+// 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/math/rintbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, rintbf16, (bfloat16 x)) {
+ return fputil::round_using_current_rounding_mode(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/roundbf16.cpp b/libc/src/math/generic/roundbf16.cpp
new file mode 100644
index 0000000..cc7e5e2
--- /dev/null
+++ b/libc/src/math/generic/roundbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of roundbf16 function ------------------------------===//
+//
+// 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/math/roundbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, roundbf16, (bfloat16 x)) {
+ return fputil::round(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/roundevenbf16.cpp b/libc/src/math/generic/roundevenbf16.cpp
new file mode 100644
index 0000000..39419e4
--- /dev/null
+++ b/libc/src/math/generic/roundevenbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of roundevenbf16 function --------------------------===//
+//
+// 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/math/roundevenbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, roundevenbf16, (bfloat16 x)) {
+ return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/scalblnbf16.cpp b/libc/src/math/generic/scalblnbf16.cpp
new file mode 100644
index 0000000..f85f702
--- /dev/null
+++ b/libc/src/math/generic/scalblnbf16.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of scalblnbf16 function ----------------------------===//
+//
+// 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/math/scalblnbf16.h"
+#include "hdr/float_macros.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+#if FLT_RADIX != 2
+#error "FLT_RADIX != 2 is not supported."
+#endif
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, scalblnbf16, (bfloat16 x, long n)) {
+ return fputil::ldexp(x, n);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/scalbnbf16.cpp b/libc/src/math/generic/scalbnbf16.cpp
new file mode 100644
index 0000000..108f9e7
--- /dev/null
+++ b/libc/src/math/generic/scalbnbf16.cpp
@@ -0,0 +1,26 @@
+//===-- Implementation of scalbnbf16 function -----------------------------===//
+//
+// 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/math/scalbnbf16.h"
+#include "hdr/float_macros.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+#if FLT_RADIX != 2
+#error "FLT_RADIX != 2 is not supported."
+#endif
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, scalbnbf16, (bfloat16 x, int n)) {
+ return fputil::ldexp(x, n);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/setpayloadbf16.cpp b/libc/src/math/generic/setpayloadbf16.cpp
new file mode 100644
index 0000000..49f9b9c
--- /dev/null
+++ b/libc/src/math/generic/setpayloadbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of setpayloadbf16 function -------------------------===//
+//
+// 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/math/setpayloadbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, setpayloadbf16, (bfloat16 * res, bfloat16 pl)) {
+ return static_cast<int>(fputil::setpayload</*IsSignaling=*/false>(*res, pl));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/setpayloadsigbf16.cpp b/libc/src/math/generic/setpayloadsigbf16.cpp
new file mode 100644
index 0000000..7a2b7c7
--- /dev/null
+++ b/libc/src/math/generic/setpayloadsigbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of setpayloadsigbf16 function ----------------------===//
+//
+// 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/math/setpayloadsigbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, setpayloadsigbf16, (bfloat16 * res, bfloat16 pl)) {
+ return static_cast<int>(fputil::setpayload</*IsSignaling=*/true>(*res, pl));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/sin.cpp b/libc/src/math/generic/sin.cpp
index a614427b..1b6310f 100644
--- a/libc/src/math/generic/sin.cpp
+++ b/libc/src/math/generic/sin.cpp
@@ -18,13 +18,13 @@
#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/math/generic/range_reduction_double_common.h"
-#include "src/math/generic/sincos_eval.h"
+#include "src/__support/math/range_reduction_double_common.h"
+#include "src/__support/math/sincos_eval.h"
#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
-#include "range_reduction_double_fma.h"
+#include "src/__support/math/range_reduction_double_fma.h"
#else
-#include "range_reduction_double_nofma.h"
+#include "src/__support/math/range_reduction_double_nofma.h"
#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
namespace LIBC_NAMESPACE_DECL {
@@ -33,6 +33,7 @@ using DoubleDouble = fputil::DoubleDouble;
using Float128 = typename fputil::DyadicFloat<128>;
LLVM_LIBC_FUNCTION(double, sin, (double x)) {
+ using namespace math::range_reduction_double_internal;
using FPBits = typename fputil::FPBits<double>;
FPBits xbits(x);
@@ -95,7 +96,8 @@ LLVM_LIBC_FUNCTION(double, sin, (double x)) {
DoubleDouble sin_y, cos_y;
- [[maybe_unused]] double err = generic::sincos_eval(y, sin_y, cos_y);
+ [[maybe_unused]] double err =
+ math::sincos_eval_internal::sincos_eval(y, sin_y, cos_y);
// Look up sin(k * pi/128) and cos(k * pi/128)
#ifdef LIBC_MATH_HAS_SMALL_TABLES
@@ -149,7 +151,7 @@ LLVM_LIBC_FUNCTION(double, sin, (double x)) {
else
u_f128 = range_reduction_large.accurate();
- generic::sincos_eval(u_f128, sin_u, cos_u);
+ math::sincos_eval_internal::sincos_eval(u_f128, sin_u, cos_u);
auto get_sin_k = [](unsigned kk) -> Float128 {
unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63);
diff --git a/libc/src/math/generic/sincos.cpp b/libc/src/math/generic/sincos.cpp
index 08c8a82..38661de 100644
--- a/libc/src/math/generic/sincos.cpp
+++ b/libc/src/math/generic/sincos.cpp
@@ -19,13 +19,13 @@
#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/math/generic/range_reduction_double_common.h"
-#include "src/math/generic/sincos_eval.h"
+#include "src/__support/math/range_reduction_double_common.h"
+#include "src/__support/math/sincos_eval.h"
#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
-#include "range_reduction_double_fma.h"
+#include "src/__support/math/range_reduction_double_fma.h"
#else
-#include "range_reduction_double_nofma.h"
+#include "src/__support/math/range_reduction_double_nofma.h"
#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
namespace LIBC_NAMESPACE_DECL {
@@ -34,6 +34,7 @@ using DoubleDouble = fputil::DoubleDouble;
using Float128 = typename fputil::DyadicFloat<128>;
LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sin_x, double *cos_x)) {
+ using namespace math::range_reduction_double_internal;
using FPBits = typename fputil::FPBits<double>;
FPBits xbits(x);
@@ -106,7 +107,8 @@ LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sin_x, double *cos_x)) {
DoubleDouble sin_y, cos_y;
- [[maybe_unused]] double err = generic::sincos_eval(y, sin_y, cos_y);
+ [[maybe_unused]] double err =
+ math::sincos_eval_internal::sincos_eval(y, sin_y, cos_y);
// Look up sin(k * pi/128) and cos(k * pi/128)
#ifdef LIBC_MATH_HAS_SMALL_TABLES
@@ -179,7 +181,7 @@ LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sin_x, double *cos_x)) {
else
u_f128 = range_reduction_large.accurate();
- generic::sincos_eval(u_f128, sin_u, cos_u);
+ math::sincos_eval_internal::sincos_eval(u_f128, sin_u, cos_u);
auto get_sin_k = [](unsigned kk) -> Float128 {
unsigned idx = (kk & 64) ? 64 - (kk & 63) : (kk & 63);
diff --git a/libc/src/math/generic/sincosf.cpp b/libc/src/math/generic/sincosf.cpp
index 9c7bf18..5179c98 100644
--- a/libc/src/math/generic/sincosf.cpp
+++ b/libc/src/math/generic/sincosf.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/sincosf.h"
-#include "sincosf_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/multiply_add.h"
@@ -16,6 +15,7 @@
#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/sincosf_utils.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/sinf.cpp b/libc/src/math/generic/sinf.cpp
index 38ea56f..a8e634c 100644
--- a/libc/src/math/generic/sinf.cpp
+++ b/libc/src/math/generic/sinf.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/sinf.h"
-#include "sincosf_utils.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
@@ -18,11 +17,12 @@
#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/sincosf_utils.h"
#if defined(LIBC_TARGET_CPU_HAS_FMA_DOUBLE)
-#include "range_reduction_fma.h"
+#include "src/__support/math/range_reduction_fma.h"
#else
-#include "range_reduction.h"
+#include "src/__support/math/range_reduction.h"
#endif
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/sinf16.cpp b/libc/src/math/generic/sinf16.cpp
index 28debbd..2b57920 100644
--- a/libc/src/math/generic/sinf16.cpp
+++ b/libc/src/math/generic/sinf16.cpp
@@ -9,13 +9,13 @@
#include "src/math/sinf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
-#include "sincosf16_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.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/macros/optimization.h"
+#include "src/__support/math/sincosf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -32,6 +32,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> SINF16_EXCEPTS{{
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, sinf16, (float16 x)) {
+ using namespace sincosf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/sinhf.cpp b/libc/src/math/generic/sinhf.cpp
index 63111f8..5f2d0b5 100644
--- a/libc/src/math/generic/sinhf.cpp
+++ b/libc/src/math/generic/sinhf.cpp
@@ -12,7 +12,7 @@
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
-#include "src/math/generic/explogxf.h"
+#include "src/__support/math/sinhfcoshf_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -73,7 +73,8 @@ LLVM_LIBC_FUNCTION(float, sinhf, (float x)) {
}
// sinh(x) = (e^x - e^(-x)) / 2.
- return static_cast<float>(exp_pm_eval</*is_sinh*/ true>(x));
+ return static_cast<float>(
+ math::sinhfcoshf_internal::exp_pm_eval</*is_sinh*/ true>(x));
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/sinhf16.cpp b/libc/src/math/generic/sinhf16.cpp
index b426ea7..f6b5c9b 100644
--- a/libc/src/math/generic/sinhf16.cpp
+++ b/libc/src/math/generic/sinhf16.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/sinhf16.h"
-#include "expxf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -17,6 +16,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
+#include "src/__support/math/expxf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -89,6 +89,7 @@ static constexpr fputil::ExceptValues<float16, 13> SINHF16_EXCEPTS_NEG = {{
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, sinhf16, (float16 x)) {
+ using namespace math::expxf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits x_bits(x);
diff --git a/libc/src/math/generic/sinpif.cpp b/libc/src/math/generic/sinpif.cpp
index 492689d..f3383f1 100644
--- a/libc/src/math/generic/sinpif.cpp
+++ b/libc/src/math/generic/sinpif.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/sinpif.h"
-#include "sincosf_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
@@ -15,6 +14,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/sincosf_utils.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/sinpif16.cpp b/libc/src/math/generic/sinpif16.cpp
index 68af484..311e6f9 100644
--- a/libc/src/math/generic/sinpif16.cpp
+++ b/libc/src/math/generic/sinpif16.cpp
@@ -9,15 +9,16 @@
#include "src/math/sinpif16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
-#include "sincosf16_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/math/sincosf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(float16, sinpif16, (float16 x)) {
+ using namespace sincosf16_internal;
using FPBits = typename fputil::FPBits<float16>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/tan.cpp b/libc/src/math/generic/tan.cpp
index 89b812c..7ea40c9 100644
--- a/libc/src/math/generic/tan.cpp
+++ b/libc/src/math/generic/tan.cpp
@@ -20,12 +20,12 @@
#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/math/generic/range_reduction_double_common.h"
+#include "src/__support/math/range_reduction_double_common.h"
#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
-#include "range_reduction_double_fma.h"
+#include "src/__support/math/range_reduction_double_fma.h"
#else
-#include "range_reduction_double_nofma.h"
+#include "src/__support/math/range_reduction_double_nofma.h"
#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
namespace LIBC_NAMESPACE_DECL {
@@ -121,6 +121,7 @@ LIBC_INLINE double tan_eval(const DoubleDouble &u, DoubleDouble &result) {
} // anonymous namespace
LLVM_LIBC_FUNCTION(double, tan, (double x)) {
+ using namespace math::range_reduction_double_internal;
using FPBits = typename fputil::FPBits<double>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/tanf.cpp b/libc/src/math/generic/tanf.cpp
index ca5e35d..a8c557b 100644
--- a/libc/src/math/generic/tanf.cpp
+++ b/libc/src/math/generic/tanf.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/tanf.h"
-#include "sincosf_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/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/sincosf_utils.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/tanf16.cpp b/libc/src/math/generic/tanf16.cpp
index 229f4a3..20323a8 100644
--- a/libc/src/math/generic/tanf16.cpp
+++ b/libc/src/math/generic/tanf16.cpp
@@ -9,13 +9,13 @@
#include "src/math/tanf16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
-#include "sincosf16_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.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/macros/optimization.h"
+#include "src/__support/math/sincosf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -37,6 +37,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> TANF16_EXCEPTS{{
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, tanf16, (float16 x)) {
+ using namespace sincosf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/tanhf.cpp b/libc/src/math/generic/tanhf.cpp
index 32153c3..0c55047 100644
--- a/libc/src/math/generic/tanhf.cpp
+++ b/libc/src/math/generic/tanhf.cpp
@@ -14,7 +14,7 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/__support/macros/properties/cpu_features.h"
-#include "src/math/generic/explogxf.h"
+#include "src/__support/math/exp10f_utils.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/tanhf16.cpp b/libc/src/math/generic/tanhf16.cpp
index 4c43cfd..fc0e28b 100644
--- a/libc/src/math/generic/tanhf16.cpp
+++ b/libc/src/math/generic/tanhf16.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/tanhf16.h"
-#include "expxf16.h"
#include "hdr/fenv_macros.h"
#include "src/__support/CPP/array.h"
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -21,6 +20,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
+#include "src/__support/math/expxf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -34,6 +34,7 @@ static constexpr fputil::ExceptValues<float16, 2> TANHF16_EXCEPTS = {{
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, tanhf16, (float16 x)) {
+ using namespace math::expxf16_internal;
using FPBits = fputil::FPBits<float16>;
FPBits x_bits(x);
diff --git a/libc/src/math/generic/tanpif.cpp b/libc/src/math/generic/tanpif.cpp
index 58d46c9..b49f3ce 100644
--- a/libc/src/math/generic/tanpif.cpp
+++ b/libc/src/math/generic/tanpif.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "src/math/tanpif.h"
-#include "sincosf_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/cast.h"
@@ -16,6 +15,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math/sincosf_utils.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/math/generic/tanpif16.cpp b/libc/src/math/generic/tanpif16.cpp
index 792d405..b137b09 100644
--- a/libc/src/math/generic/tanpif16.cpp
+++ b/libc/src/math/generic/tanpif16.cpp
@@ -9,13 +9,13 @@
#include "src/math/tanpif16.h"
#include "hdr/errno_macros.h"
#include "hdr/fenv_macros.h"
-#include "sincosf16_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.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/macros/optimization.h"
+#include "src/__support/math/sincosf16_utils.h"
namespace LIBC_NAMESPACE_DECL {
@@ -39,6 +39,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> TANPIF16_EXCEPTS{{
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
LLVM_LIBC_FUNCTION(float16, tanpif16, (float16 x)) {
+ using namespace sincosf16_internal;
using FPBits = typename fputil::FPBits<float16>;
FPBits xbits(x);
diff --git a/libc/src/math/generic/totalorderbf16.cpp b/libc/src/math/generic/totalorderbf16.cpp
new file mode 100644
index 0000000..bb9c86e
--- /dev/null
+++ b/libc/src/math/generic/totalorderbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of totalorderbf16 function -------------------------===//
+//
+// 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/math/totalorderbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, totalorderbf16,
+ (const bfloat16 *x, const bfloat16 *y)) {
+ return static_cast<int>(fputil::totalorder(*x, *y));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/totalordermagbf16.cpp b/libc/src/math/generic/totalordermagbf16.cpp
new file mode 100644
index 0000000..3fc61d9
--- /dev/null
+++ b/libc/src/math/generic/totalordermagbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of totalordermagbf16 function ----------------------===//
+//
+// 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/math/totalordermagbf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, totalordermagbf16,
+ (const bfloat16 *x, const bfloat16 *y)) {
+ return static_cast<int>(fputil::totalordermag(*x, *y));
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/truncbf16.cpp b/libc/src/math/generic/truncbf16.cpp
new file mode 100644
index 0000000..dfbe83d
--- /dev/null
+++ b/libc/src/math/generic/truncbf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of truncbf16 function ------------------------------===//
+//
+// 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/math/truncbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, truncbf16, (bfloat16 x)) {
+ return fputil::trunc(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/ufromfpbf16.cpp b/libc/src/math/generic/ufromfpbf16.cpp
new file mode 100644
index 0000000..336771b
--- /dev/null
+++ b/libc/src/math/generic/ufromfpbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of ufromfpbf16 function ----------------------------===//
+//
+// 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/math/ufromfpbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, ufromfpbf16,
+ (bfloat16 x, int rnd, unsigned int width)) {
+ return fputil::fromfp</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/ufromfpxbf16.cpp b/libc/src/math/generic/ufromfpxbf16.cpp
new file mode 100644
index 0000000..ac9cf44
--- /dev/null
+++ b/libc/src/math/generic/ufromfpxbf16.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of ufromfpxbf16 function ---------------------------===//
+//
+// 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/math/ufromfpxbf16.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(bfloat16, ufromfpxbf16,
+ (bfloat16 x, int rnd, unsigned int width)) {
+ return fputil::fromfpx</*IsSigned=*/false>(x, rnd, width);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/getpayloadbf16.h b/libc/src/math/getpayloadbf16.h
new file mode 100644
index 0000000..e4767f0
--- /dev/null
+++ b/libc/src/math/getpayloadbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for getpayloadbf16 ----------------*- 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_MATH_GETPAYLOADBF16_H
+#define LLVM_LIBC_SRC_MATH_GETPAYLOADBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 getpayloadbf16(const bfloat16 *x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_GETPAYLOADBF16_H
diff --git a/libc/src/math/ilogbbf16.h b/libc/src/math/ilogbbf16.h
new file mode 100644
index 0000000..da2384b
--- /dev/null
+++ b/libc/src/math/ilogbbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for ilogbbf16 ---------------------*- 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_MATH_ILOGBBF16_H
+#define LLVM_LIBC_SRC_MATH_ILOGBBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int ilogbbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ILOGBBF16_H
diff --git a/libc/src/math/iscanonicalbf16.h b/libc/src/math/iscanonicalbf16.h
new file mode 100644
index 0000000..f4f975e
--- /dev/null
+++ b/libc/src/math/iscanonicalbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for iscanonicalbf16 ---------------*- 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_MATH_ISCANONICALBF16_H
+#define LLVM_LIBC_SRC_MATH_ISCANONICALBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int iscanonicalbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISCANONICALBF16_H
diff --git a/libc/src/math/issignalingbf16.h b/libc/src/math/issignalingbf16.h
new file mode 100644
index 0000000..afbe70f
--- /dev/null
+++ b/libc/src/math/issignalingbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for issignalingbf16 ---------------*- 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_MATH_ISSIGNALINGBF16_H
+#define LLVM_LIBC_SRC_MATH_ISSIGNALINGBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int issignalingbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISSIGNALINGBF16_H
diff --git a/libc/src/math/ldexpbf16.h b/libc/src/math/ldexpbf16.h
new file mode 100644
index 0000000..7436d8d
--- /dev/null
+++ b/libc/src/math/ldexpbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for ldexpbf16 ---------------------*- 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_MATH_LDEXPBF16_H
+#define LLVM_LIBC_SRC_MATH_LDEXPBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 ldexpbf16(bfloat16 x, int exp);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LDEXPBF16_H
diff --git a/libc/src/math/llogbbf16.h b/libc/src/math/llogbbf16.h
new file mode 100644
index 0000000..13f0570
--- /dev/null
+++ b/libc/src/math/llogbbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for llogbbf16 ---------------------*- 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_MATH_LLOGBBF16_H
+#define LLVM_LIBC_SRC_MATH_LLOGBBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long llogbbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LLOGBBF16_H
diff --git a/libc/src/math/llrintbf16.h b/libc/src/math/llrintbf16.h
new file mode 100644
index 0000000..23402a5
--- /dev/null
+++ b/libc/src/math/llrintbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for llrintbf16 --------------------*- 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_MATH_LLRINTBF16_H
+#define LLVM_LIBC_SRC_MATH_LLRINTBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long long llrintbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LLRINTBF16_H
diff --git a/libc/src/math/llroundbf16.h b/libc/src/math/llroundbf16.h
new file mode 100644
index 0000000..69878e4
--- /dev/null
+++ b/libc/src/math/llroundbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for llroundbf16 -------------------*- 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_MATH_LLROUNDBF16_H
+#define LLVM_LIBC_SRC_MATH_LLROUNDBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long long llroundbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LLROUNDBF16_H
diff --git a/libc/src/math/logbbf16.h b/libc/src/math/logbbf16.h
new file mode 100644
index 0000000..2c0d77e
--- /dev/null
+++ b/libc/src/math/logbbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for logbbf16 ----------------------*- 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_MATH_LOGBBF16_H
+#define LLVM_LIBC_SRC_MATH_LOGBBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 logbbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LOGBBF16_H
diff --git a/libc/src/math/lrintbf16.h b/libc/src/math/lrintbf16.h
new file mode 100644
index 0000000..ec24472
--- /dev/null
+++ b/libc/src/math/lrintbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for lrintbf16 ---------------------*- 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_MATH_LRINTBF16_H
+#define LLVM_LIBC_SRC_MATH_LRINTBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long lrintbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LRINTBF16_H
diff --git a/libc/src/math/lroundbf16.h b/libc/src/math/lroundbf16.h
new file mode 100644
index 0000000..c08db7a
--- /dev/null
+++ b/libc/src/math/lroundbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for lroundbf16 --------------------*- 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_MATH_LROUNDBF16_H
+#define LLVM_LIBC_SRC_MATH_LROUNDBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long lroundbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LROUNDBF16_H
diff --git a/libc/src/math/modfbf16.h b/libc/src/math/modfbf16.h
new file mode 100644
index 0000000..df05b6c
--- /dev/null
+++ b/libc/src/math/modfbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for modfbf16 ----------------------*- 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_MATH_MODFBF16_H
+#define LLVM_LIBC_SRC_MATH_MODFBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 modfbf16(bfloat16 x, bfloat16 *iptr);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_MODFBF16_H
diff --git a/libc/src/math/nanbf16.h b/libc/src/math/nanbf16.h
new file mode 100644
index 0000000..1551044
--- /dev/null
+++ b/libc/src/math/nanbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for nanbf16 -----------------------*- 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_MATH_NANBF16_H
+#define LLVM_LIBC_SRC_MATH_NANBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 nanbf16(const char *arg);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_NANBF16_H
diff --git a/libc/src/math/nearbyintbf16.h b/libc/src/math/nearbyintbf16.h
new file mode 100644
index 0000000..bc7eb3b
--- /dev/null
+++ b/libc/src/math/nearbyintbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for nearbyintbf16 -----------------*- 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_MATH_NEARBYINTBF16_H
+#define LLVM_LIBC_SRC_MATH_NEARBYINTBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 nearbyintbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_NEARBYINTBF16_H
diff --git a/libc/src/math/nextafterbf16.h b/libc/src/math/nextafterbf16.h
new file mode 100644
index 0000000..f962c7c
--- /dev/null
+++ b/libc/src/math/nextafterbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for nextafterbf16 -----------------*- 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_MATH_NEXTAFTERBF16_H
+#define LLVM_LIBC_SRC_MATH_NEXTAFTERBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 nextafterbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTAFTERBF16_H
diff --git a/libc/src/math/nextdownbf16.h b/libc/src/math/nextdownbf16.h
new file mode 100644
index 0000000..36b0cd7
--- /dev/null
+++ b/libc/src/math/nextdownbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for nextdownbf16 ------------------*- 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_MATH_NEXTDOWNBF16_H
+#define LLVM_LIBC_SRC_MATH_NEXTDOWNBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 nextdownbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNBF16_H
diff --git a/libc/src/math/nexttowardbf16.h b/libc/src/math/nexttowardbf16.h
new file mode 100644
index 0000000..930abf8
--- /dev/null
+++ b/libc/src/math/nexttowardbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for nexttowardbf16 ----------------*- 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_MATH_NEXTTOWARDBF16_H
+#define LLVM_LIBC_SRC_MATH_NEXTTOWARDBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 nexttowardbf16(bfloat16 x, long double y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTTOWARDBF16_H
diff --git a/libc/src/math/nextupbf16.h b/libc/src/math/nextupbf16.h
new file mode 100644
index 0000000..872de84
--- /dev/null
+++ b/libc/src/math/nextupbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for nextupbf16 --------------------*- 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_MATH_NEXTUPBF16_H
+#define LLVM_LIBC_SRC_MATH_NEXTUPBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 nextupbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_NEXTUPBF16_H
diff --git a/libc/src/math/remainderbf16.h b/libc/src/math/remainderbf16.h
new file mode 100644
index 0000000..a1a2eaa
--- /dev/null
+++ b/libc/src/math/remainderbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for remainderbf16 -----------------*- 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_MATH_REMAINDERBF16_H
+#define LLVM_LIBC_SRC_MATH_REMAINDERBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 remainderbf16(bfloat16 x, bfloat16 y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_REMAINDERBF16_H
diff --git a/libc/src/math/remquobf16.h b/libc/src/math/remquobf16.h
new file mode 100644
index 0000000..909db17
--- /dev/null
+++ b/libc/src/math/remquobf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for remquobf16 --------------------*- 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_MATH_REMQUOBF16_H
+#define LLVM_LIBC_SRC_MATH_REMQUOBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 remquobf16(bfloat16 x, bfloat16 y, int *exp);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_REMQUOBF16_H
diff --git a/libc/src/math/rintbf16.h b/libc/src/math/rintbf16.h
new file mode 100644
index 0000000..aae1541
--- /dev/null
+++ b/libc/src/math/rintbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for rintbf16 ----------------------*- 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_MATH_RINTBF16_H
+#define LLVM_LIBC_SRC_MATH_RINTBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 rintbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_RINTBF16_H
diff --git a/libc/src/math/roundbf16.h b/libc/src/math/roundbf16.h
new file mode 100644
index 0000000..0f74e43
--- /dev/null
+++ b/libc/src/math/roundbf16.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for roundbf16 ---------------------*- 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_MATH_ROUNDBF16_H
+#define LLVM_LIBC_SRC_MATH_ROUNDBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 roundbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDBF16_H
diff --git a/libc/src/math/roundevenbf16.h b/libc/src/math/roundevenbf16.h
new file mode 100644
index 0000000..f4374d2
--- /dev/null
+++ b/libc/src/math/roundevenbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for roundevenbf16 -----------------*- 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_MATH_ROUNDEVENBF16_H
+#define LLVM_LIBC_SRC_MATH_ROUNDEVENBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 roundevenbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ROUNDEVENBF16_H
diff --git a/libc/src/math/scalblnbf16.h b/libc/src/math/scalblnbf16.h
new file mode 100644
index 0000000..10aad05
--- /dev/null
+++ b/libc/src/math/scalblnbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for scalblnbf16 -------------------*- 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_MATH_SCALBLNBF16_H
+#define LLVM_LIBC_SRC_MATH_SCALBLNBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 scalblnbf16(bfloat16 x, long n);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_SCALBLNBF16_H
diff --git a/libc/src/math/scalbnbf16.h b/libc/src/math/scalbnbf16.h
new file mode 100644
index 0000000..67efa33
--- /dev/null
+++ b/libc/src/math/scalbnbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for scalbnbf16 --------------------*- 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_MATH_SCALBNBF16_H
+#define LLVM_LIBC_SRC_MATH_SCALBNBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 scalbnbf16(bfloat16 x, int n);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_SCALBNBF16_H
diff --git a/libc/src/math/setpayloadbf16.h b/libc/src/math/setpayloadbf16.h
new file mode 100644
index 0000000..e3a60b2
--- /dev/null
+++ b/libc/src/math/setpayloadbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for setpayloadbf16 ----------------*- 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_MATH_SETPAYLOADBF16_H
+#define LLVM_LIBC_SRC_MATH_SETPAYLOADBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int setpayloadbf16(bfloat16 *res, bfloat16 pl);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_SETPAYLOADBF16_H
diff --git a/libc/src/math/setpayloadsigbf16.h b/libc/src/math/setpayloadsigbf16.h
new file mode 100644
index 0000000..5baba95
--- /dev/null
+++ b/libc/src/math/setpayloadsigbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for setpayloadsigbf16 -------------*- 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_MATH_SETPAYLOADSIGBF16_H
+#define LLVM_LIBC_SRC_MATH_SETPAYLOADSIGBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int setpayloadsigbf16(bfloat16 *res, bfloat16 pl);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_SETPAYLOADSIGBF16_H
diff --git a/libc/src/math/totalorderbf16.h b/libc/src/math/totalorderbf16.h
new file mode 100644
index 0000000..2414852
--- /dev/null
+++ b/libc/src/math/totalorderbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for totalorderbf16 ----------------*- 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_MATH_TOTALORDERF16_H
+#define LLVM_LIBC_SRC_MATH_TOTALORDERF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int totalorderbf16(const bfloat16 *x, const bfloat16 *y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_TOTALORDERF16_H
diff --git a/libc/src/math/totalordermagbf16.h b/libc/src/math/totalordermagbf16.h
new file mode 100644
index 0000000..c48de1c
--- /dev/null
+++ b/libc/src/math/totalordermagbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for totalordermagbf16 -------------*- 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_MATH_TOTALORDERMAGF16_H
+#define LLVM_LIBC_SRC_MATH_TOTALORDERMAGF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int totalordermagbf16(const bfloat16 *x, const bfloat16 *y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_TOTALORDERMAGF16_H
diff --git a/libc/src/math/truncbf16.h b/libc/src/math/truncbf16.h
new file mode 100644
index 0000000..c87d4cc
--- /dev/null
+++ b/libc/src/math/truncbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for truncbf16 ---------------------*- 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_MATH_TRUNCBF16_H
+#define LLVM_LIBC_SRC_MATH_TRUNCBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 truncbf16(bfloat16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_TRUNCBF16_H
diff --git a/libc/src/math/ufromfpbf16.h b/libc/src/math/ufromfpbf16.h
new file mode 100644
index 0000000..1fd876a
--- /dev/null
+++ b/libc/src/math/ufromfpbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for ufromfpbf16 -------------------*- 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_MATH_UFROMFPBF16_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 ufromfpbf16(bfloat16 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPBF16_H
diff --git a/libc/src/math/ufromfpxbf16.h b/libc/src/math/ufromfpxbf16.h
new file mode 100644
index 0000000..ec63744
--- /dev/null
+++ b/libc/src/math/ufromfpxbf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for ufromfpxbf16 ------------------*- 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_MATH_UFROMFPXBF16_H
+#define LLVM_LIBC_SRC_MATH_UFROMFPXBF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+bfloat16 ufromfpxbf16(bfloat16 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_UFROMFPXBF16_H
diff --git a/libc/src/stdlib/exit.cpp b/libc/src/stdlib/exit.cpp
index 28a6f8a..ef3b8dd 100644
--- a/libc/src/stdlib/exit.cpp
+++ b/libc/src/stdlib/exit.cpp
@@ -15,7 +15,17 @@ namespace LIBC_NAMESPACE_DECL {
extern "C" void __cxa_finalize(void *);
+// exit needs to clean up TLS and call associated destructors.
+// TODO: Strictly speaking, it is not valid to call exit in overlay mode
+// as we have no way to ensure system libc will call the TLS destructors.
+// We should run exit related tests in hermetic mode but this is currently
+// blocked by https://github.com/llvm/llvm-project/issues/133925.
+extern "C" [[gnu::weak]] void __cxa_thread_finalize();
+
+// TODO: use recursive mutex to protect this routine.
[[noreturn]] LLVM_LIBC_FUNCTION(void, exit, (int status)) {
+ if (__cxa_thread_finalize)
+ __cxa_thread_finalize();
__cxa_finalize(nullptr);
internal::exit(status);
}
diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index 809decf..5c9f622 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -20,6 +20,7 @@ add_header_library(
libc.hdr.stdint_proxy
libc.src.__support.CPP.bitset
libc.src.__support.CPP.type_traits
+ libc.src.__support.CPP.simd
libc.src.__support.common
${string_config_options}
)
diff --git a/libc/src/string/memory_utils/aarch64/inline_strlen.h b/libc/src/string/memory_utils/aarch64/inline_strlen.h
new file mode 100644
index 0000000..36fd1aa
--- /dev/null
+++ b/libc/src/string/memory_utils/aarch64/inline_strlen.h
@@ -0,0 +1,53 @@
+//===-- Strlen implementation for aarch64 ---------------------------------===//
+//
+// 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_STRING_MEMORY_UTILS_AARCH64_INLINE_STRLEN_H
+#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_STRLEN_H
+
+#if defined(__ARM_NEON)
+#include "src/__support/CPP/bit.h" // countr_zero
+
+#include <arm_neon.h>
+#include <stddef.h> // size_t
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace neon {
+[[gnu::no_sanitize_address]] [[maybe_unused]] LIBC_INLINE static size_t
+string_length(const char *src) {
+ using Vector __attribute__((may_alias)) = uint8x8_t;
+
+ uintptr_t misalign_bytes = reinterpret_cast<uintptr_t>(src) % sizeof(Vector);
+ const Vector *block_ptr =
+ reinterpret_cast<const Vector *>(src - misalign_bytes);
+ Vector v = *block_ptr;
+ Vector vcmp = vceqz_u8(v);
+ uint64x1_t cmp_mask = vreinterpret_u64_u8(vcmp);
+ uint64_t cmp = vget_lane_u64(cmp_mask, 0);
+ cmp = cmp >> (misalign_bytes << 3);
+ if (cmp)
+ return cpp::countr_zero(cmp) >> 3;
+
+ while (true) {
+ ++block_ptr;
+ v = *block_ptr;
+ vcmp = vceqz_u8(v);
+ cmp_mask = vreinterpret_u64_u8(vcmp);
+ cmp = vget_lane_u64(cmp_mask, 0);
+ if (cmp)
+ return static_cast<size_t>(reinterpret_cast<uintptr_t>(block_ptr) -
+ reinterpret_cast<uintptr_t>(src) +
+ (cpp::countr_zero(cmp) >> 3));
+ }
+}
+} // namespace neon
+
+namespace string_length_impl = neon;
+
+} // namespace LIBC_NAMESPACE_DECL
+#endif // __ARM_NEON
+#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_STRLEN_H
diff --git a/libc/src/string/memory_utils/generic/inline_strlen.h b/libc/src/string/memory_utils/generic/inline_strlen.h
new file mode 100644
index 0000000..68fba2a
--- /dev/null
+++ b/libc/src/string/memory_utils/generic/inline_strlen.h
@@ -0,0 +1,54 @@
+//===-- Strlen for generic SIMD types -------------------------------------===//
+//
+// 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_STRING_MEMORY_UTILS_GENERIC_INLINE_STRLEN_H
+#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_INLINE_STRLEN_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+// Exploit the underlying integer representation to do a variable shift.
+LIBC_INLINE constexpr cpp::simd_mask<char> shift_mask(cpp::simd_mask<char> m,
+ size_t shift) {
+ using bitmask_ty = cpp::internal::get_as_integer_type_t<cpp::simd_mask<char>>;
+ bitmask_ty r = cpp::bit_cast<bitmask_ty>(m) >> shift;
+ return cpp::bit_cast<cpp::simd_mask<char>>(r);
+}
+
+[[clang::no_sanitize("address")]] LIBC_INLINE size_t
+string_length(const char *src) {
+ constexpr cpp::simd<char> null_byte = cpp::splat('\0');
+
+ size_t alignment = alignof(cpp::simd<char>);
+ const cpp::simd<char> *aligned = reinterpret_cast<const cpp::simd<char> *>(
+ __builtin_align_down(src, alignment));
+
+ cpp::simd<char> chars = cpp::load_aligned<cpp::simd<char>>(aligned);
+ cpp::simd_mask<char> mask = cpp::simd_cast<bool>(chars == null_byte);
+ size_t offset = src - reinterpret_cast<const char *>(aligned);
+ if (cpp::any_of(shift_mask(mask, offset)))
+ return cpp::find_first_set(shift_mask(mask, offset));
+
+ for (;;) {
+ cpp::simd<char> chars = cpp::load_aligned<cpp::simd<char>>(++aligned);
+ cpp::simd_mask<char> mask = cpp::simd_cast<bool>(chars == null_byte);
+ if (cpp::any_of(mask))
+ return (reinterpret_cast<const char *>(aligned) - src) +
+ cpp::find_first_set(mask);
+ }
+}
+} // namespace internal
+
+namespace string_length_impl = internal;
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_INLINE_STRLEN_H
diff --git a/libc/src/string/memory_utils/x86_64/inline_strlen.h b/libc/src/string/memory_utils/x86_64/inline_strlen.h
new file mode 100644
index 0000000..739f8c1
--- /dev/null
+++ b/libc/src/string/memory_utils/x86_64/inline_strlen.h
@@ -0,0 +1,107 @@
+//===-- Strlen implementation for x86_64 ----------------------------------===//
+//
+// 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_STRING_MEMORY_UTILS_X86_64_INLINE_STRLEN_H
+#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_X86_64_INLINE_STRLEN_H
+
+#include "src/__support/CPP/bit.h" // countr_zero
+
+#include <immintrin.h>
+#include <stddef.h> // size_t
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace string_length_internal {
+// Return a bit-mask with the nth bit set if the nth-byte in block_ptr is zero.
+template <typename Vector, typename Mask>
+[[gnu::no_sanitize_address]] LIBC_INLINE static Mask
+compare_and_mask(const Vector *block_ptr);
+
+template <typename Vector, typename Mask,
+ decltype(compare_and_mask<Vector, Mask>)>
+[[gnu::no_sanitize_address]] LIBC_INLINE static size_t
+string_length_vector(const char *src) {
+ uintptr_t misalign_bytes = reinterpret_cast<uintptr_t>(src) % sizeof(Vector);
+
+ const Vector *block_ptr =
+ reinterpret_cast<const Vector *>(src - misalign_bytes);
+ auto cmp = compare_and_mask<Vector, Mask>(block_ptr) >> misalign_bytes;
+ if (cmp)
+ return cpp::countr_zero(cmp);
+
+ while (true) {
+ block_ptr++;
+ cmp = compare_and_mask<Vector, Mask>(block_ptr);
+ if (cmp)
+ return static_cast<size_t>(reinterpret_cast<uintptr_t>(block_ptr) -
+ reinterpret_cast<uintptr_t>(src) +
+ cpp::countr_zero(cmp));
+ }
+}
+
+template <>
+LIBC_INLINE uint32_t
+compare_and_mask<__m128i, uint32_t>(const __m128i *block_ptr) {
+ __m128i v = _mm_load_si128(block_ptr);
+ __m128i z = _mm_setzero_si128();
+ __m128i c = _mm_cmpeq_epi8(z, v);
+ return _mm_movemask_epi8(c);
+}
+
+namespace sse2 {
+[[maybe_unused]] LIBC_INLINE size_t string_length(const char *src) {
+ return string_length_vector<__m128i, uint32_t,
+ compare_and_mask<__m128i, uint32_t>>(src);
+}
+} // namespace sse2
+
+#if defined(__AVX2__)
+template <>
+LIBC_INLINE uint32_t
+compare_and_mask<__m256i, uint32_t>(const __m256i *block_ptr) {
+ __m256i v = _mm256_load_si256(block_ptr);
+ __m256i z = _mm256_setzero_si256();
+ __m256i c = _mm256_cmpeq_epi8(z, v);
+ return _mm256_movemask_epi8(c);
+}
+
+namespace avx2 {
+[[maybe_unused]] LIBC_INLINE size_t string_length(const char *src) {
+ return string_length_vector<__m256i, uint32_t,
+ compare_and_mask<__m256i, uint32_t>>(src);
+}
+} // namespace avx2
+#endif
+
+#if defined(__AVX512F__)
+template <>
+LIBC_INLINE __mmask64
+compare_and_mask<__m512i, __mmask64>(const __m512i *block_ptr) {
+ __m512i v = _mm512_load_si512(block_ptr);
+ __m512i z = _mm512_setzero_si512();
+ return _mm512_cmp_epu8_mask(z, v, _MM_CMPINT_EQ);
+}
+namespace avx512 {
+[[maybe_unused]] LIBC_INLINE size_t string_length(const char *src) {
+ return string_length_vector<__m512i, __mmask64,
+ compare_and_mask<__m512i, __mmask64>>(src);
+}
+} // namespace avx512
+#endif
+} // namespace string_length_internal
+
+#if defined(__AVX512F__)
+namespace string_length_impl = string_length_internal::avx512;
+#elif defined(__AVX2__)
+namespace string_length_impl = string_length_internal::avx2;
+#else
+namespace string_length_impl = string_length_internal::sse2;
+#endif
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_X86_64_INLINE_STRLEN_H
diff --git a/libc/src/string/string_utils.h b/libc/src/string/string_utils.h
index 80e5783..1080348 100644
--- a/libc/src/string/string_utils.h
+++ b/libc/src/string/string_utils.h
@@ -22,6 +22,18 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#if defined(LIBC_COPT_STRING_UNSAFE_WIDE_READ)
+#if LIBC_HAS_VECTOR_TYPE
+#include "src/string/memory_utils/generic/inline_strlen.h"
+#elif defined(LIBC_TARGET_ARCH_IS_X86)
+#include "src/string/memory_utils/x86_64/inline_strlen.h"
+#elif defined(LIBC_TARGET_ARCH_IS_AARCH64) && defined(__ARM_NEON)
+#include "src/string/memory_utils/aarch64/inline_strlen.h"
+#else
+namespace string_length_impl = LIBC_NAMESPACE::wide_read;
+#endif
+#endif // defined(LIBC_COPT_STRING_UNSAFE_WIDE_READ)
+
namespace LIBC_NAMESPACE_DECL {
namespace internal {
@@ -53,7 +65,7 @@ template <typename Word> LIBC_INLINE constexpr Word repeat_byte(Word byte) {
// high bit set will no longer have it set, narrowing the list of bytes which
// result in non-zero values to just the zero byte.
template <typename Word> LIBC_INLINE constexpr bool has_zeroes(Word block) {
- constexpr Word LOW_BITS = repeat_byte<Word>(0x01);
+ constexpr unsigned int LOW_BITS = repeat_byte<Word>(0x01);
constexpr Word HIGH_BITS = repeat_byte<Word>(0x80);
Word subtracted = block - LOW_BITS;
Word inverted = ~block;
@@ -81,16 +93,23 @@ LIBC_INLINE size_t string_length_wide_read(const char *src) {
return static_cast<size_t>(char_ptr - src);
}
-// Returns the length of a string, denoted by the first occurrence
-// of a null terminator.
-template <typename T> LIBC_INLINE size_t string_length(const T *src) {
-#ifdef LIBC_COPT_STRING_UNSAFE_WIDE_READ
+namespace wide_read {
+LIBC_INLINE size_t string_length(const char *src) {
// Unsigned int is the default size for most processors, and on x86-64 it
// performs better than larger sizes when the src pointer can't be assumed to
// be aligned to a word boundary, so it's the size we use for reading the
// string a block at a time.
+ return string_length_wide_read<unsigned int>(src);
+}
+
+} // namespace wide_read
+
+// Returns the length of a string, denoted by the first occurrence
+// of a null terminator.
+template <typename T> LIBC_INLINE size_t string_length(const T *src) {
+#ifdef LIBC_COPT_STRING_UNSAFE_WIDE_READ
if constexpr (cpp::is_same_v<T, char>)
- return string_length_wide_read<unsigned int>(src);
+ return string_length_impl::string_length(src);
#endif
size_t length;
for (length = 0; *src; ++src, ++length)
@@ -99,8 +118,9 @@ template <typename T> LIBC_INLINE size_t string_length(const T *src) {
}
template <typename Word>
-LIBC_INLINE void *find_first_character_wide_read(const unsigned char *src,
- unsigned char ch, size_t n) {
+[[gnu::no_sanitize_address]] LIBC_INLINE void *
+find_first_character_wide_read(const unsigned char *src, unsigned char ch,
+ size_t n) {
const unsigned char *char_ptr = src;
size_t cur = 0;
@@ -184,33 +204,36 @@ LIBC_INLINE size_t complementary_span(const char *src, const char *segment) {
template <bool SkipDelim = true>
LIBC_INLINE char *string_token(char *__restrict src,
const char *__restrict delimiter_string,
- char **__restrict saveptr) {
- // Return nullptr immediately if both src AND saveptr are nullptr
- if (LIBC_UNLIKELY(src == nullptr && ((src = *saveptr) == nullptr)))
+ char **__restrict context) {
+ // Return nullptr immediately if both src AND context are nullptr
+ if (LIBC_UNLIKELY(src == nullptr && ((src = *context) == nullptr)))
return nullptr;
static_assert(CHAR_BIT == 8, "bitset of 256 assumes char is 8 bits");
- cpp::bitset<256> delimiter_set;
+ cpp::bitset<256> delims;
for (; *delimiter_string != '\0'; ++delimiter_string)
- delimiter_set.set(static_cast<size_t>(*delimiter_string));
+ delims.set(*reinterpret_cast<const unsigned char *>(delimiter_string));
+ unsigned char *tok_start = reinterpret_cast<unsigned char *>(src);
if constexpr (SkipDelim)
- for (; *src != '\0' && delimiter_set.test(static_cast<size_t>(*src)); ++src)
- ;
- if (*src == '\0') {
- *saveptr = src;
+ while (*tok_start != '\0' && delims.test(*tok_start))
+ ++tok_start;
+ if (*tok_start == '\0' && SkipDelim) {
+ *context = nullptr;
return nullptr;
}
- char *token = src;
- for (; *src != '\0'; ++src) {
- if (delimiter_set.test(static_cast<size_t>(*src))) {
- *src = '\0';
- ++src;
- break;
- }
+
+ unsigned char *tok_end = tok_start;
+ while (*tok_end != '\0' && !delims.test(*tok_end))
+ ++tok_end;
+
+ if (*tok_end == '\0') {
+ *context = nullptr;
+ } else {
+ *tok_end = '\0';
+ *context = reinterpret_cast<char *>(tok_end + 1);
}
- *saveptr = src;
- return token;
+ return reinterpret_cast<char *>(tok_start);
}
LIBC_INLINE size_t strlcpy(char *__restrict dst, const char *__restrict src,
diff --git a/libc/src/sys/time/linux/utimes.cpp b/libc/src/sys/time/linux/utimes.cpp
index 9c00ce9..e740190b 100644
--- a/libc/src/sys/time/linux/utimes.cpp
+++ b/libc/src/sys/time/linux/utimes.cpp
@@ -21,24 +21,21 @@
namespace LIBC_NAMESPACE_DECL {
-#ifdef SYS_utimes
-constexpr auto UTIMES_SYSCALL_ID = SYS_utimes;
-#elif defined(SYS_utimensat)
-constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat;
-#elif defined(SYS_utimensat_time64)
-constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat_time64;
-#else
-#error "utimes, utimensat, utimensat_time64, syscalls not available."
-#endif
-
LLVM_LIBC_FUNCTION(int, utimes,
(const char *path, const struct timeval times[2])) {
int ret;
#ifdef SYS_utimes
// No need to define a timespec struct, use the syscall directly.
- ret = LIBC_NAMESPACE::syscall_impl<int>(UTIMES_SYSCALL_ID, path, times);
+ ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_utimes, path, times);
#elif defined(SYS_utimensat) || defined(SYS_utimensat_time64)
+
+#if defined(SYS_utimensat)
+ constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat;
+#elif defined(SYS_utimensat_time64)
+ constexpr auto UTIMES_SYSCALL_ID = SYS_utimensat_time64;
+#endif
+
// the utimensat syscall requires a timespec struct, not timeval.
struct timespec ts[2];
struct timespec *ts_ptr = nullptr; // default value if times is nullptr
@@ -74,6 +71,9 @@ LLVM_LIBC_FUNCTION(int, utimes,
// flags=0 means don't follow symlinks (like utimes)
ret = LIBC_NAMESPACE::syscall_impl<int>(UTIMES_SYSCALL_ID, AT_FDCWD, path,
ts_ptr, 0);
+
+#else
+#error "utimes, utimensat, utimensat_time64, syscalls not available."
#endif // SYS_utimensat
if (ret < 0) {
diff --git a/libc/src/unistd/linux/setsid.cpp b/libc/src/unistd/linux/setsid.cpp
index df4629b..b1a265c 100644
--- a/libc/src/unistd/linux/setsid.cpp
+++ b/libc/src/unistd/linux/setsid.cpp
@@ -11,6 +11,7 @@
#include "hdr/types/pid_t.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 <sys/syscall.h> // For syscall numbers.
@@ -18,7 +19,12 @@
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(pid_t, setsid, ()) {
- return LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_setsid);
+ pid_t ret = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_setsid);
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return ret;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wchar/wcsncmp.cpp b/libc/src/wchar/wcsncmp.cpp
index f2e052b..baca12b 100644
--- a/libc/src/wchar/wcsncmp.cpp
+++ b/libc/src/wchar/wcsncmp.cpp
@@ -30,8 +30,7 @@ LLVM_LIBC_FUNCTION(int, wcsncmp,
if (!comp(lc, '\0') || comp(lc, *right))
break;
}
- return comp(*reinterpret_cast<const wchar_t *>(left),
- *reinterpret_cast<const wchar_t *>(right));
+ return comp(*left, *right);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wctype/iswalpha.cpp b/libc/src/wctype/iswalpha.cpp
index e18f293..09f55d3 100644
--- a/libc/src/wctype/iswalpha.cpp
+++ b/libc/src/wctype/iswalpha.cpp
@@ -14,6 +14,6 @@
namespace LIBC_NAMESPACE_DECL {
-LLVM_LIBC_FUNCTION(bool, iswalpha, (wint_t c)) { return internal::iswalpha(c); }
+LLVM_LIBC_FUNCTION(int, iswalpha, (wint_t c)) { return internal::iswalpha(c); }
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/wctype/iswalpha.h b/libc/src/wctype/iswalpha.h
index 681fc6b..0353388 100644
--- a/libc/src/wctype/iswalpha.h
+++ b/libc/src/wctype/iswalpha.h
@@ -14,7 +14,7 @@
namespace LIBC_NAMESPACE_DECL {
-bool iswalpha(wint_t c);
+int iswalpha(wint_t c);
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/startup/baremetal/aarch64/CMakeLists.txt b/libc/startup/baremetal/aarch64/CMakeLists.txt
new file mode 100644
index 0000000..f75bd89
--- /dev/null
+++ b/libc/startup/baremetal/aarch64/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_startup_object(
+ crt1
+ SRC
+ start.cpp
+ DEPENDS
+ libc.src.stdlib.atexit
+ libc.src.stdlib.exit
+ libc.src.string.memcpy
+ libc.src.string.memset
+ libc.startup.baremetal.init
+ libc.startup.baremetal.fini
+ COMPILE_OPTIONS
+ -ffreestanding # To avoid compiler warnings about calling the main function.
+ -fno-builtin
+ -Wno-global-constructors # To allow vector table initialization
+)
diff --git a/libc/startup/baremetal/aarch64/start.cpp b/libc/startup/baremetal/aarch64/start.cpp
new file mode 100644
index 0000000..ff3ea933
--- /dev/null
+++ b/libc/startup/baremetal/aarch64/start.cpp
@@ -0,0 +1,112 @@
+//===-- Implementation of crt for aarch64 ---------------------------------===//
+//
+// 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/stdint_proxy.h"
+#include "src/__support/macros/config.h"
+#include "src/stdlib/atexit.h"
+#include "src/stdlib/exit.h"
+#include "src/string/memcpy.h"
+#include "src/string/memset.h"
+#include "startup/baremetal/fini.h"
+#include "startup/baremetal/init.h"
+
+#include <arm_acle.h>
+
+extern "C" {
+int main(int argc, char **argv);
+void _start();
+
+// Semihosting library initialisation if applicable. Required for printf, etc.
+[[gnu::weak]] void _platform_init() {}
+
+// These symbols are provided by the linker. The exact names are not defined by
+// a standard.
+extern uintptr_t __stack;
+extern uintptr_t __data_source[];
+extern uintptr_t __data_start[];
+extern uintptr_t __data_size[];
+extern uintptr_t __bss_start[];
+extern uintptr_t __bss_size[];
+} // extern "C"
+
+namespace {
+// The Arm ARM for the A-profile architecture (D14.1.5) defines the exceptions.
+// However, for simplicity, we don't bother logging, and just exit.
+void GenericException_Handler() { LIBC_NAMESPACE::exit(1); }
+
+// The AArch64 exception vector table has 16 entries, each of which is 128
+// bytes long, and contains code. The whole table must be 2048-byte aligned.
+// For our purposes, each entry just contains one branch instruction to the
+// exception reporting function, since we never want to resume after an
+// exception.
+[[gnu::section(".vectors"), gnu::aligned(2048), gnu::used, gnu::naked]]
+void vector_table() {
+#define VECTOR_TABLE_ENTRY \
+ asm(".balign 128"); \
+ asm("B %0" : : "X"(GenericException_Handler));
+
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+ VECTOR_TABLE_ENTRY;
+}
+} // namespace
+
+namespace LIBC_NAMESPACE_DECL {
+
+[[noreturn]] void do_start() {
+ // TODO: This startup code is not extensive, but rather the MVP for QEMU
+ // testing.
+ // TODO: Setup memory (MMU, page table, caches)
+ // TODO: Consider v8-R variants
+
+ // Set up exception handling
+ __arm_wsr64("VBAR_EL1", reinterpret_cast<uint64_t>(&vector_table));
+
+#ifdef __ARM_FP
+ // Do not trap FP/SME/SVE instructions
+ static constexpr uint64_t CPACR_SHIFT_FPEN = 20;
+ static constexpr uint64_t CPACR_SHIFT_SMEN = 24;
+ uint64_t cpacr = __arm_rsr64("CPACR_EL1");
+ cpacr |= (0x3 << CPACR_SHIFT_FPEN);
+ cpacr |= (0x3 << CPACR_SHIFT_SMEN);
+ __arm_wsr64("CPACR_EL1", cpacr);
+#endif
+
+ // Perform the equivalent of scatterloading
+ LIBC_NAMESPACE::memcpy(__data_start, __data_source,
+ reinterpret_cast<uintptr_t>(__data_size));
+ LIBC_NAMESPACE::memset(__bss_start, '\0',
+ reinterpret_cast<uintptr_t>(__bss_size));
+ __libc_init_array();
+
+ _platform_init();
+ LIBC_NAMESPACE::atexit(&__libc_fini_array);
+ LIBC_NAMESPACE::exit(main(0, 0));
+}
+} // namespace LIBC_NAMESPACE_DECL
+
+extern "C" {
+[[gnu::section(".text.init.enter"), gnu::naked]]
+void _start() {
+ asm volatile("mov sp, %0" : : "r"(&__stack));
+ asm volatile("bl %0" : : "X"(LIBC_NAMESPACE::do_start));
+}
+} // extern "C"
diff --git a/libc/startup/baremetal/arm/start.cpp b/libc/startup/baremetal/arm/start.cpp
index 123efc4..c089a14 100644
--- a/libc/startup/baremetal/arm/start.cpp
+++ b/libc/startup/baremetal/arm/start.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/stdint_proxy.h"
#include "src/__support/macros/config.h"
#include "src/stdlib/atexit.h"
#include "src/stdlib/exit.h"
@@ -14,7 +15,7 @@
#include "startup/baremetal/fini.h"
#include "startup/baremetal/init.h"
-#include <stdint.h>
+#include <arm_acle.h> // For __arm_wsr
extern "C" {
int main(int argc, char **argv);
@@ -31,7 +32,10 @@ extern uintptr_t __data_start[];
extern uintptr_t __data_size[];
extern uintptr_t __bss_start[];
extern uintptr_t __bss_size[];
+} // extern "C"
+namespace {
+#if __ARM_ARCH_PROFILE == 'M'
// Based on
// https://developer.arm.com/documentation/107565/0101/Use-case-examples/Generic-Information/What-is-inside-a-program-image-/Vector-table
void NMI_Handler() {}
@@ -49,35 +53,89 @@ void SysTick_Handler() {}
// to be zero and Cortex-M23 can require up to 10, so 1024-byte align the vector
// table.
using HandlerType = void (*)(void);
-const HandlerType vector_table[]
- __attribute__((section(".vectors"), aligned(1024), used)) = {
- (HandlerType)&__stack, // SP
- _start, // Reset
- NMI_Handler, // NMI Handler
- HardFault_Handler, // Hard Fault Handlerß
- MemManage_Handler, // MPU Fault Han`dler
- BusFault_Handler, // Bus Fault Handler
- UsageFault_Handler, // Usage Fault Handler
- 0, // Reserved
- 0, // Reserved
- 0, // Reserved
- 0, // Reserved
- SVC_Handler, // SVC Handler
- DebugMon_Handler, // Debug Monitor Handler
- 0, // Reserved
- PendSV_Handler, // PendSV Handler
- SysTick_Handler, // SysTick Handler
- // Unused
+[[gnu::section(".vectors"), gnu::aligned(1024), gnu::used]]
+const HandlerType vector_table[] = {
+ reinterpret_cast<HandlerType>(&__stack), // SP
+ _start, // Reset
+ NMI_Handler, // NMI Handler
+ HardFault_Handler, // Hard Fault Handler
+ MemManage_Handler, // MPU Fault Handler
+ BusFault_Handler, // Bus Fault Handler
+ UsageFault_Handler, // Usage Fault Handler
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ SVC_Handler, // SVC Handler
+ DebugMon_Handler, // Debug Monitor Handler
+ 0, // Reserved
+ PendSV_Handler, // PendSV Handler
+ SysTick_Handler, // SysTick Handler
+ // Unused
};
-} // extern "C"
+#else
+// Based on
+// https://developer.arm.com/documentation/den0013/0400/Boot-Code/Booting-a-bare-metal-system
+void Reset_Handler() { LIBC_NAMESPACE::exit(1); }
+void Undefined_Handler() { LIBC_NAMESPACE::exit(1); }
+void SWI_Handler() { LIBC_NAMESPACE::exit(1); }
+void PrefetchAbort_Handler() { LIBC_NAMESPACE::exit(1); }
+void DataAbort_Handler() { LIBC_NAMESPACE::exit(1); }
+void IRQ_Handler() { LIBC_NAMESPACE::exit(1); }
+void FIQ_Handler() { LIBC_NAMESPACE::exit(1); }
+
+// The AArch32 exception vector table has 8 entries, each of which is 4
+// bytes long, and contains code. The whole table must be 32-byte aligned.
+// The table may also be relocated, so we make it position-independent by
+// having a table of handler addresses and loading the address to pc.
+[[gnu::section(".vectors"), gnu::aligned(32), gnu::used, gnu::naked,
+ gnu::target("arm")]]
+void vector_table() {
+ asm("LDR pc, [pc, #24]");
+ asm("LDR pc, [pc, #24]");
+ asm("LDR pc, [pc, #24]");
+ asm("LDR pc, [pc, #24]");
+ asm("LDR pc, [pc, #24]");
+ asm("LDR pc, [pc, #24]");
+ asm("LDR pc, [pc, #24]");
+ asm("LDR pc, [pc, #24]");
+ asm(".word %c0" : : "X"(Reset_Handler));
+ asm(".word %c0" : : "X"(Undefined_Handler));
+ asm(".word %c0" : : "X"(SWI_Handler));
+ asm(".word %c0" : : "X"(PrefetchAbort_Handler));
+ asm(".word %c0" : : "X"(DataAbort_Handler));
+ asm(".word %c0" : : "X"(0));
+ asm(".word %c0" : : "X"(IRQ_Handler));
+ asm(".word %c0" : : "X"(FIQ_Handler));
+}
+#endif
+} // namespace
namespace LIBC_NAMESPACE_DECL {
[[noreturn]] void do_start() {
// FIXME: set up the QEMU test environment
+#if __ARM_ARCH_PROFILE == 'A' || __ARM_ARCH_PROFILE == 'R'
+ // Set up registers to be used in exception handling
+ // Copy the current sp value to each of the banked copies of sp.
+ __arm_wsr("CPSR_c", 0x11); // FIQ
+ asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0)));
+ __arm_wsr("CPSR_c", 0x12); // IRQ
+ asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0)));
+ __arm_wsr("CPSR_c", 0x17); // ABT
+ asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0)));
+ __arm_wsr("CPSR_c", 0x1B); // UND
+ asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0)));
+ __arm_wsr("CPSR_c", 0x1F); // SYS
+ asm volatile("mov sp, %0" : : "r"(__builtin_frame_address(0)));
+ __arm_wsr("CPSR_c", 0x13); // SVC
+#endif
+
// Perform the equivalent of scatterloading
- LIBC_NAMESPACE::memcpy(__data_start, __data_source, (uintptr_t)__data_size);
- LIBC_NAMESPACE::memset(__bss_start, '\0', (uintptr_t)__bss_size);
+ LIBC_NAMESPACE::memcpy(__data_start, __data_source,
+ reinterpret_cast<uintptr_t>(__data_size));
+ LIBC_NAMESPACE::memset(__bss_start, '\0',
+ reinterpret_cast<uintptr_t>(__bss_size));
__libc_init_array();
_platform_init();
@@ -86,7 +144,13 @@ namespace LIBC_NAMESPACE_DECL {
}
} // namespace LIBC_NAMESPACE_DECL
-extern "C" void _start() {
+extern "C" {
+#ifdef __ARM_ARCH_ISA_ARM
+// If ARM state is supported, it must be used (instead of Thumb)
+[[gnu::naked, gnu::target("arm")]]
+#endif
+void _start() {
asm volatile("mov sp, %0" : : "r"(&__stack));
asm volatile("bl %0" : : "X"(LIBC_NAMESPACE::do_start));
}
+} // extern "C"
diff --git a/libc/test/IntegrationTest/CMakeLists.txt b/libc/test/IntegrationTest/CMakeLists.txt
index 3afe354..235e9fe 100644
--- a/libc/test/IntegrationTest/CMakeLists.txt
+++ b/libc/test/IntegrationTest/CMakeLists.txt
@@ -13,5 +13,6 @@ add_object_library(
DEPENDS
libc.hdr.stdint_proxy
libc.src.__support.OSUtil.osutil
+ libc.src.__support.CPP.atomic
${arch_specific_deps}
)
diff --git a/libc/test/IntegrationTest/test.cpp b/libc/test/IntegrationTest/test.cpp
index 8baf746..19eb255 100644
--- a/libc/test/IntegrationTest/test.cpp
+++ b/libc/test/IntegrationTest/test.cpp
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-
#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/atomic.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include <stddef.h>
@@ -63,16 +63,21 @@ int atexit(void (*func)(void)) { return LIBC_NAMESPACE::atexit(func); }
// which just hands out continuous blocks from a statically allocated chunk of
// memory.
-static constexpr uint64_t MEMORY_SIZE = 16384;
-static uint8_t memory[MEMORY_SIZE];
-static uint8_t *ptr = memory;
+static constexpr uint64_t ALIGNMENT = alignof(double);
+static constexpr uint64_t MEMORY_SIZE = 256 * 1024 /* 256 KiB */;
+alignas(ALIGNMENT) static uint8_t memory[MEMORY_SIZE];
+static size_t ptr = 0;
extern "C" {
-void *malloc(size_t s) {
- void *mem = ptr;
- ptr += s;
- return static_cast<uint64_t>(ptr - memory) >= MEMORY_SIZE ? nullptr : mem;
+void *malloc(size_t size) {
+ LIBC_NAMESPACE::cpp::AtomicRef<size_t> ref(ptr);
+ size = (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1);
+ size_t old_ptr =
+ ref.fetch_add(size, LIBC_NAMESPACE::cpp::MemoryOrder::RELAXED);
+ if (static_cast<size_t>(old_ptr + size) >= MEMORY_SIZE)
+ return nullptr;
+ return &memory[old_ptr];
}
void free(void *) {}
diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt
index d92ab6f..f1a83fc 100644
--- a/libc/test/UnitTest/CMakeLists.txt
+++ b/libc/test/UnitTest/CMakeLists.txt
@@ -125,6 +125,7 @@ add_unittest_framework_library(
RoundingModeUtils.h
DEPENDS
LibcTest
+ libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.string_utils
libc.src.__support.CPP.array
libc.src.__support.FPUtil.fp_bits
diff --git a/libc/test/UnitTest/FEnvSafeTest.cpp b/libc/test/UnitTest/FEnvSafeTest.cpp
index 168b1d4..f644569 100644
--- a/libc/test/UnitTest/FEnvSafeTest.cpp
+++ b/libc/test/UnitTest/FEnvSafeTest.cpp
@@ -9,8 +9,10 @@
#include "FEnvSafeTest.h"
#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
namespace LIBC_NAMESPACE_DECL {
namespace testing {
@@ -25,6 +27,10 @@ void FEnvSafeTest::TearDown() {
if (!should_be_unchanged) {
restore_fenv();
}
+ // TODO (PR 135320): Remove this override once all FEnvSafeTest instances are
+ // updated to validate or ignore errno.
+ libc_errno = 0;
+ ErrnoCheckingTest::TearDown();
}
void FEnvSafeTest::get_fenv(fenv_t &fenv) {
diff --git a/libc/test/UnitTest/FEnvSafeTest.h b/libc/test/UnitTest/FEnvSafeTest.h
index a3c5e62..1e10629 100644
--- a/libc/test/UnitTest/FEnvSafeTest.h
+++ b/libc/test/UnitTest/FEnvSafeTest.h
@@ -12,6 +12,7 @@
#include "hdr/types/fenv_t.h"
#include "src/__support/CPP/utility.h"
#include "src/__support/macros/config.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/Test.h"
namespace LIBC_NAMESPACE_DECL {
@@ -20,7 +21,7 @@ namespace testing {
// This provides a test fixture (or base class for other test fixtures) that
// asserts that each test does not leave the FPU state represented by `fenv_t`
// (aka `FPState`) perturbed from its initial state.
-class FEnvSafeTest : public Test {
+class FEnvSafeTest : public ErrnoCheckingTest {
public:
void TearDown() override;
diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index da15cf2..592cd1b 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -14,8 +14,10 @@
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/fpbits_str.h"
+#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/RoundingModeUtils.h"
#include "test/UnitTest/StringUtils.h"
#include "test/UnitTest/Test.h"
@@ -166,7 +168,7 @@ CFPMatcher<T, C> getMatcherComplex(T expectedValue) {
return CFPMatcher<T, C>(expectedValue);
}
-template <typename T> struct FPTest : public Test {
+template <typename T> struct FPTest : public ErrnoCheckingTest {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
static constexpr StorageType STORAGE_MAX =
@@ -191,6 +193,13 @@ template <typename T> struct FPTest : public Test {
fputil::testing::RoundingMode::Downward,
fputil::testing::RoundingMode::TowardZero,
};
+
+ void TearDown() override {
+ // TODO (PR 135320): Remove this override once all FPTest instances are
+ // updated to validate or ignore errno.
+ libc_errno = 0;
+ ErrnoCheckingTest::TearDown();
+ }
};
// Add facility to test Flush-Denormal-To-Zero (FTZ) and Denormal-As-Zero (DAZ)
diff --git a/libc/test/integration/src/__support/GPU/CMakeLists.txt b/libc/test/integration/src/__support/GPU/CMakeLists.txt
index e066830..1fb175b 100644
--- a/libc/test/integration/src/__support/GPU/CMakeLists.txt
+++ b/libc/test/integration/src/__support/GPU/CMakeLists.txt
@@ -27,3 +27,16 @@ add_integration_test(
LOADER_ARGS
--threads 64
)
+
+add_libc_test(
+ fixedstack_test
+ SUITE
+ libc-support-gpu-tests
+ SRCS
+ fixedstack_test.cpp
+ DEPENDS
+ libc.src.__support.GPU.fixedstack
+ LOADER_ARGS
+ --threads 32
+ --blocks 16
+)
diff --git a/libc/test/integration/src/__support/GPU/fixedstack_test.cpp b/libc/test/integration/src/__support/GPU/fixedstack_test.cpp
new file mode 100644
index 0000000..fde51df
--- /dev/null
+++ b/libc/test/integration/src/__support/GPU/fixedstack_test.cpp
@@ -0,0 +1,44 @@
+//===-- Integration test for the lock-free stack --------------------------===//
+//
+// 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/GPU/fixedstack.h"
+#include "src/__support/GPU/utils.h"
+#include "test/IntegrationTest/test.h"
+
+using namespace LIBC_NAMESPACE;
+
+static FixedStack<uint32_t, 2048> global_stack;
+
+void run() {
+ // We need enough space in the stack as threads in flight can temporarily
+ // consume memory before they finish comitting it back to the stack.
+ ASSERT_EQ(gpu::get_num_blocks() * gpu::get_num_threads(), 512);
+
+ uint32_t val;
+ uint32_t num_threads = static_cast<uint32_t>(gpu::get_num_threads());
+ for (int i = 0; i < 256; ++i) {
+ EXPECT_TRUE(global_stack.push(UINT32_MAX))
+ EXPECT_TRUE(global_stack.pop(val))
+ ASSERT_TRUE(val < num_threads || val == UINT32_MAX);
+ }
+
+ EXPECT_TRUE(global_stack.push(static_cast<uint32_t>(gpu::get_thread_id())));
+ EXPECT_TRUE(global_stack.push(static_cast<uint32_t>(gpu::get_thread_id())));
+ EXPECT_TRUE(global_stack.pop(val));
+ ASSERT_TRUE(val < num_threads || val == UINT32_MAX);
+
+ // Fill the rest of the stack with the default value.
+ while (!global_stack.push(UINT32_MAX))
+ ;
+}
+
+TEST_MAIN(int argc, char **argv, char **envp) {
+ run();
+
+ return 0;
+}
diff --git a/libc/test/integration/src/__support/GPU/match.cpp b/libc/test/integration/src/__support/GPU/match.cpp
index 2d314c2..70c22b7 100644
--- a/libc/test/integration/src/__support/GPU/match.cpp
+++ b/libc/test/integration/src/__support/GPU/match.cpp
@@ -21,7 +21,9 @@ static void test_match() {
gpu::match_any(mask, gpu::get_lane_id()));
EXPECT_EQ(mask, gpu::match_any(mask, 1));
- uint64_t expected = gpu::get_lane_id() < 16 ? 0xffff : 0xffff0000;
+ uint64_t full_mask =
+ gpu::get_lane_size() > 32 ? 0xffffffffffffffff : 0xffffffff;
+ uint64_t expected = gpu::get_lane_id() < 16 ? 0xffff : full_mask & ~0xffff;
EXPECT_EQ(expected, gpu::match_any(mask, gpu::get_lane_id() < 16));
EXPECT_EQ(mask, gpu::match_all(mask, 1));
EXPECT_EQ(0ull, gpu::match_all(mask, gpu::get_lane_id()));
diff --git a/libc/test/integration/src/__support/threads/CMakeLists.txt b/libc/test/integration/src/__support/threads/CMakeLists.txt
index 5a12d28..40e9668 100644
--- a/libc/test/integration/src/__support/threads/CMakeLists.txt
+++ b/libc/test/integration/src/__support/threads/CMakeLists.txt
@@ -25,3 +25,24 @@ add_integration_test(
DEPENDS
libc.src.__support.threads.thread
)
+
+add_integration_test(
+ main_exit_test
+ SUITE
+ libc-support-threads-integration-tests
+ SRCS
+ main_exit_test.cpp
+ DEPENDS
+ libc.src.__support.threads.thread
+)
+
+add_integration_test(
+ double_exit_test
+ SUITE
+ libc-support-threads-integration-tests
+ SRCS
+ double_exit_test.cpp
+ DEPENDS
+ libc.src.__support.threads.thread
+ libc.src.stdlib.exit
+)
diff --git a/libc/test/integration/src/__support/threads/double_exit_test.cpp b/libc/test/integration/src/__support/threads/double_exit_test.cpp
new file mode 100644
index 0000000..86749d9
--- /dev/null
+++ b/libc/test/integration/src/__support/threads/double_exit_test.cpp
@@ -0,0 +1,33 @@
+//===-- Test handling of thread local data --------------------------------===//
+//
+// 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/threads/thread.h"
+#include "src/stdlib/exit.h"
+#include "test/IntegrationTest/test.h"
+
+extern "C" {
+[[gnu::weak]]
+void *__dso_handle = nullptr;
+int __cxa_thread_atexit_impl(void (*func)(void *), void *arg, void *dso);
+}
+
+int call_num = 0;
+
+[[gnu::destructor]]
+void check() {
+ // This destructor should be called only once.
+ if (call_num != 1)
+ __builtin_trap();
+}
+
+TEST_MAIN() {
+ __cxa_thread_atexit_impl([](void *) { LIBC_NAMESPACE::exit(0); }, nullptr,
+ __dso_handle);
+ __cxa_thread_atexit_impl([](void *) { ++call_num; }, nullptr, __dso_handle);
+ LIBC_NAMESPACE::exit(1);
+}
diff --git a/libc/test/integration/src/__support/threads/main_exit_test.cpp b/libc/test/integration/src/__support/threads/main_exit_test.cpp
new file mode 100644
index 0000000..c90e4e5
--- /dev/null
+++ b/libc/test/integration/src/__support/threads/main_exit_test.cpp
@@ -0,0 +1,30 @@
+//===-- Test handling of thread local data --------------------------------===//
+//
+// 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/threads/thread.h"
+#include "test/IntegrationTest/test.h"
+
+bool called = false;
+
+extern "C" {
+[[gnu::weak]]
+void *__dso_handle = nullptr;
+int __cxa_thread_atexit_impl(void (*func)(void *), void *arg, void *dso);
+}
+
+[[gnu::destructor]]
+void destructor() {
+ if (!called)
+ __builtin_trap();
+}
+
+TEST_MAIN() {
+ __cxa_thread_atexit_impl([](void *) { called = true; }, nullptr,
+ __dso_handle);
+ return 0;
+}
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index f5ea510..48241d3 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -27,6 +27,14 @@ add_fp_unittest(
libc.src.__support.math.atanhf
libc.src.__support.math.atanhf16
libc.src.__support.math.cbrt
+ libc.src.__support.math.cbrtf
+ libc.src.__support.math.cos
+ libc.src.__support.math.cosf
+ libc.src.__support.math.cosf16
+ libc.src.__support.math.coshf
+ libc.src.__support.math.coshf16
+ libc.src.__support.math.cospif
+ libc.src.__support.math.cospif16
libc.src.__support.math.erff
libc.src.__support.math.exp
libc.src.__support.math.exp10
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 3d64e5e..2e5a2d5 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -21,7 +21,9 @@ TEST(LlvmLibcSharedMathTest, AllFloat16) {
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::asinhf16(0.0f16));
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atanf16(0.0f16));
EXPECT_FP_EQ(0x0p+0f16, LIBC_NAMESPACE::shared::atanhf16(0.0f16));
-
+ EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::cosf16(0.0f16));
+ EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::coshf16(0.0f16));
+ EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::cospif16(0.0f16));
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::exp10f16(0.0f16));
EXPECT_FP_EQ(0x1p+0f16, LIBC_NAMESPACE::shared::expf16(0.0f16));
@@ -49,6 +51,10 @@ TEST(LlvmLibcSharedMathTest, AllFloat) {
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::atan2f(0.0f, 0.0f));
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::atanf(0.0f));
EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::atanhf(0.0f));
+ EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::cbrtf(0.0f));
+ EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::cosf(0.0f));
+ EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::coshf(0.0f));
+ EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::cospif(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));
@@ -65,8 +71,9 @@ 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(0x0p+0, LIBC_NAMESPACE::shared::atan(0.0));
- EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::cbrt(0.0));
EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::atan2(0.0, 0.0));
+ EXPECT_FP_EQ(0x0p+0, LIBC_NAMESPACE::shared::cbrt(0.0));
+ EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::cos(0.0));
EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::exp(0.0));
EXPECT_FP_EQ(0x1p+0, LIBC_NAMESPACE::shared::exp10(0.0));
}
diff --git a/libc/test/src/__support/File/file_test.cpp b/libc/test/src/__support/File/file_test.cpp
index b3c9f2b..17dad4d 100644
--- a/libc/test/src/__support/File/file_test.cpp
+++ b/libc/test/src/__support/File/file_test.cpp
@@ -493,3 +493,22 @@ TEST(LlvmLibcFileTest, WriteNothing) {
ASSERT_EQ(f_lbf->close(), 0);
ASSERT_EQ(f_nbf->close(), 0);
}
+
+TEST(LlvmLibcFileTest, WriteSplit) {
+ constexpr size_t FILE_BUFFER_SIZE = 8;
+ char file_buffer[FILE_BUFFER_SIZE];
+ StringFile *f =
+ new_string_file(file_buffer, FILE_BUFFER_SIZE, _IOFBF, false, "w");
+
+ static constexpr size_t AVAIL = 12;
+ f->seek(-AVAIL, SEEK_END);
+
+ const char data[] = "hello";
+ ASSERT_EQ(sizeof(data) - 1, f->write(data, sizeof(data) - 1).value);
+
+ const char data2[] = " extra data";
+ static constexpr size_t WR_EXPECTED = AVAIL - (sizeof(data) - 1);
+ ASSERT_EQ(WR_EXPECTED, f->write(data2, sizeof(data2) - 1).value);
+ EXPECT_TRUE(f->error());
+ ASSERT_EQ(f->close(), 0);
+}
diff --git a/libc/test/src/__support/OSUtil/linux/vdso_test.cpp b/libc/test/src/__support/OSUtil/linux/vdso_test.cpp
index 2f68470..71892a0 100644
--- a/libc/test/src/__support/OSUtil/linux/vdso_test.cpp
+++ b/libc/test/src/__support/OSUtil/linux/vdso_test.cpp
@@ -110,8 +110,8 @@ TEST(LlvmLibcOSUtilVDSOTest, RtSigReturn) {
using namespace testing::ErrnoSetterMatcher;
// must use struct since there is a function of the same name in the same
// scope.
- struct sigaction sa {};
- struct sigaction old_sa {};
+ struct sigaction sa{};
+ struct sigaction old_sa{};
sa.sa_handler = sigprof_handler;
sa.sa_flags = SA_RESTORER;
vdso::TypedSymbol<vdso::VDSOSym::RTSigReturn> symbol;
@@ -158,4 +158,30 @@ TEST(LlvmLibcOSUtilVDSOTest, RiscvHwProbe) {
}
}
+TEST(LlvmLibcOSUtilVDSOTest, GetRandom) {
+ using namespace testing::ErrnoSetterMatcher;
+ vdso::TypedSymbol<vdso::VDSOSym::GetRandom> symbol;
+ if (!symbol)
+ return;
+ // This structure exists in kernel UAPI header; but we define it on our own to
+ // make sure we can test it even on platform without support.
+ struct VGetrandomOpaqueParams {
+ uint32_t size_of_opaque_states;
+ uint32_t mmap_prot;
+ uint32_t mmap_flags;
+ uint32_t reserved[13];
+ };
+ VGetrandomOpaqueParams param{0, 0, 0, {}};
+ // When getrandom vDSO symbol is called with special parameters (~0 for state
+ // size), it populates the desired configuration into VGetrandomOpaqueParams.
+ int res = symbol(
+ /*buf=*/nullptr, /*count=*/0, /*flags=*/0,
+ /*opaque_states=*/&param,
+ /*size_of_opaque_states=*/~0);
+ // Test that the size of the states are correctly populated after a successful
+ // call.
+ EXPECT_EQ(res, 0);
+ EXPECT_GT(param.size_of_opaque_states, 0u);
+}
+
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/__support/wchar/string_converter_test.cpp b/libc/test/src/__support/wchar/string_converter_test.cpp
index d514df9..e45358d 100644
--- a/libc/test/src/__support/wchar/string_converter_test.cpp
+++ b/libc/test/src/__support/wchar/string_converter_test.cpp
@@ -34,32 +34,32 @@ TEST(LlvmLibcStringConverterTest, UTF8To32) {
LIBC_NAMESPACE::internal::StringConverter<char8_t> sc(
reinterpret_cast<const char8_t *>(src), &state, SIZE_MAX);
- auto res = sc.popUTF32();
+ auto res = sc.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x1f921);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4);
- res = sc.popUTF32();
+ res = sc.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x2211);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 7);
- res = sc.popUTF32();
+ res = sc.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xff);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 9);
- res = sc.popUTF32();
+ res = sc.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x41);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 10);
- res = sc.popUTF32();
+ res = sc.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 11);
- res = sc.popUTF32();
+ res = sc.pop<char32_t>();
ASSERT_FALSE(res.has_value());
ASSERT_EQ(res.error(), -1);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 11);
@@ -75,66 +75,66 @@ TEST(LlvmLibcStringConverterTest, UTF32To8) {
LIBC_NAMESPACE::internal::StringConverter<char32_t> sc(
reinterpret_cast<const char32_t *>(src), &state, SIZE_MAX);
- auto res = sc.popUTF8();
+ auto res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xF0);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x9F);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xA4);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xA1);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
// end of clown emoji, sigma symbol begins
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xE2);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 2);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x88);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 2);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x91);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 2);
// end of sigma symbol, y with diaeresis begins
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xC3);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 3);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xBF);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 3);
// end of y with diaeresis, letter A begins
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x41);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4);
// null byte
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 5);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_FALSE(res.has_value());
ASSERT_EQ(res.error(), -1);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 5);
@@ -148,28 +148,28 @@ TEST(LlvmLibcStringConverterTest, UTF32To8PartialRead) {
LIBC_NAMESPACE::internal::StringConverter<char32_t> sc(
reinterpret_cast<const char32_t *>(src), &state, SIZE_MAX, 1);
- auto res = sc.popUTF8();
+ auto res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xF0);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x9F);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xA4);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xA1);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
// can only read 1 character from source string, so error on next pop
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_FALSE(res.has_value());
ASSERT_EQ(res.error(), -1);
}
@@ -181,12 +181,12 @@ TEST(LlvmLibcStringConverterTest, UTF8To32PartialRead) {
LIBC_NAMESPACE::internal::StringConverter<char8_t> sc(
reinterpret_cast<const char8_t *>(src), &state, SIZE_MAX, 5);
- auto res = sc.popUTF32();
+ auto res = sc.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x1f921);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4);
- res = sc.popUTF32();
+ res = sc.pop<char32_t>();
ASSERT_FALSE(res.has_value());
ASSERT_EQ(static_cast<int>(res.error()), -1);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 5);
@@ -200,27 +200,27 @@ TEST(LlvmLibcStringConverterTest, UTF32To8ErrorHandling) {
LIBC_NAMESPACE::internal::StringConverter<char32_t> sc(
reinterpret_cast<const char32_t *>(src), &state, SIZE_MAX);
- auto res = sc.popUTF8();
+ auto res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xF0);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x9F);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xA4);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xA1);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_FALSE(res.has_value());
ASSERT_EQ(static_cast<int>(res.error()), EILSEQ);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
@@ -234,12 +234,12 @@ TEST(LlvmLibcStringConverterTest, UTF8To32ErrorHandling) {
LIBC_NAMESPACE::internal::StringConverter<char8_t> sc(
reinterpret_cast<const char8_t *>(src), &state, SIZE_MAX);
- auto res = sc.popUTF32();
+ auto res = sc.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x1f921);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4);
- res = sc.popUTF32();
+ res = sc.pop<char32_t>();
ASSERT_FALSE(res.has_value());
ASSERT_EQ(static_cast<int>(res.error()), EILSEQ);
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4);
@@ -257,12 +257,12 @@ TEST(LlvmLibcStringConverterTest, InvalidCharacterOutsideBounds) {
LIBC_NAMESPACE::internal::StringConverter<char8_t> sc1(
reinterpret_cast<const char8_t *>(src1), &ps1, 1);
- auto res1 = sc1.popUTF32();
+ auto res1 = sc1.pop<char32_t>();
ASSERT_TRUE(res1.has_value());
ASSERT_EQ(static_cast<int>(res1.value()), 0x1f921);
ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 4);
- res1 = sc1.popUTF32();
+ res1 = sc1.pop<char32_t>();
ASSERT_FALSE(res1.has_value());
// no space to write error NOT invalid character error (EILSEQ)
ASSERT_EQ(static_cast<int>(res1.error()), -1);
@@ -275,27 +275,27 @@ TEST(LlvmLibcStringConverterTest, InvalidCharacterOutsideBounds) {
LIBC_NAMESPACE::internal::StringConverter<char32_t> sc2(
reinterpret_cast<const char32_t *>(src2), &ps2, 4);
- auto res2 = sc2.popUTF8();
+ auto res2 = sc2.pop<char8_t>();
ASSERT_TRUE(res2.has_value());
ASSERT_EQ(static_cast<int>(res2.value()), 0xF0);
ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1);
- res2 = sc2.popUTF8();
+ res2 = sc2.pop<char8_t>();
ASSERT_TRUE(res2.has_value());
ASSERT_EQ(static_cast<int>(res2.value()), 0x9F);
ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1);
- res2 = sc2.popUTF8();
+ res2 = sc2.pop<char8_t>();
ASSERT_TRUE(res2.has_value());
ASSERT_EQ(static_cast<int>(res2.value()), 0xA4);
ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1);
- res2 = sc2.popUTF8();
+ res2 = sc2.pop<char8_t>();
ASSERT_TRUE(res2.has_value());
ASSERT_EQ(static_cast<int>(res2.value()), 0xA1);
ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1);
- res2 = sc2.popUTF8();
+ res2 = sc2.pop<char8_t>();
ASSERT_FALSE(res2.has_value());
// no space to write error NOT invalid character error (EILSEQ)
ASSERT_EQ(static_cast<int>(res2.error()), -1);
@@ -315,22 +315,22 @@ TEST(LlvmLibcStringConverterTest, MultipleStringConverters32To8) {
LIBC_NAMESPACE::internal::StringConverter<char32_t> sc1(
reinterpret_cast<const char32_t *>(src), &state, SIZE_MAX, 1);
- auto res = sc1.popUTF8();
+ auto res = sc1.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xF0);
ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 1);
- res = sc1.popUTF8();
+ res = sc1.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x9F);
ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 1);
- res = sc1.popUTF8();
+ res = sc1.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xA4);
ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 1);
- res = sc1.popUTF8();
+ res = sc1.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xA1);
ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 1);
@@ -340,12 +340,12 @@ TEST(LlvmLibcStringConverterTest, MultipleStringConverters32To8) {
reinterpret_cast<const char32_t *>(src) + sc1.getSourceIndex(), &state,
SIZE_MAX, 1);
- res = sc2.popUTF8();
+ res = sc2.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xC3);
ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1);
- res = sc2.popUTF8();
+ res = sc2.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0xBF);
ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 1);
@@ -357,7 +357,7 @@ TEST(LlvmLibcStringConverterTest, MultipleStringConverters8To32) {
LIBC_NAMESPACE::internal::StringConverter<char8_t> sc1(
reinterpret_cast<const char8_t *>(src), &state, SIZE_MAX, 2);
- auto res = sc1.popUTF32();
+ auto res = sc1.pop<char32_t>();
ASSERT_FALSE(res.has_value());
ASSERT_EQ(static_cast<int>(res.error()), -1);
ASSERT_EQ(static_cast<int>(sc1.getSourceIndex()), 2);
@@ -367,12 +367,12 @@ TEST(LlvmLibcStringConverterTest, MultipleStringConverters8To32) {
reinterpret_cast<const char8_t *>(src) + sc1.getSourceIndex(), &state,
SIZE_MAX, 3);
- res = sc2.popUTF32();
+ res = sc2.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0x1f921);
ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 2);
- res = sc2.popUTF32();
+ res = sc2.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(res.value()), 0);
ASSERT_EQ(static_cast<int>(sc2.getSourceIndex()), 3);
@@ -384,11 +384,11 @@ TEST(LlvmLibcStringConverterTest, DestLimitUTF8To32) {
LIBC_NAMESPACE::internal::StringConverter<char8_t> sc(
reinterpret_cast<const char8_t *>(src), &state, 1);
- auto res = sc.popUTF32();
+ auto res = sc.pop<char32_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 4);
- res = sc.popUTF32(); // no space to pop this into
+ res = sc.pop<char32_t>(); // no space to pop this into
ASSERT_FALSE(res.has_value());
}
@@ -399,23 +399,23 @@ TEST(LlvmLibcStringConverterTest, DestLimitUTF32To8) {
LIBC_NAMESPACE::internal::StringConverter<char32_t> sc(
reinterpret_cast<const char32_t *>(src), &state, 5);
- auto res = sc.popUTF8();
+ auto res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_TRUE(res.has_value());
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
- res = sc.popUTF8();
+ res = sc.pop<char8_t>();
ASSERT_FALSE(res.has_value());
ASSERT_EQ(static_cast<int>(sc.getSourceIndex()), 1);
}
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 43cde0d..4e5563b 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -669,6 +669,25 @@ add_fp_unittest(
)
add_fp_unittest(
+ lroundbf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ lroundbf16_test.cpp
+ HDRS
+ RoundToIntegerTest.h
+ DEPENDS
+ libc.hdr.fenv_macros
+ libc.src.errno.errno
+ libc.src.math.lroundbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
llround_test
NEED_MPFR
SUITE
@@ -741,6 +760,25 @@ add_fp_unittest(
)
add_fp_unittest(
+ llroundbf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ llroundbf16_test.cpp
+ HDRS
+ RoundToIntegerTest.h
+ DEPENDS
+ libc.hdr.fenv_macros
+ libc.src.errno.errno
+ libc.src.math.llroundbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
nearbyint_test
NEED_MPFR
SUITE
@@ -801,6 +839,22 @@ add_fp_unittest(
)
add_fp_unittest(
+ nearbyintbf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ nearbyintbf16_test.cpp
+ HDRS
+ NearbyIntTest.h
+ DEPENDS
+ libc.src.math.nearbyintbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.CPP.array
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
rint_test
NEED_MPFR
SUITE
@@ -869,6 +923,24 @@ add_fp_unittest(
)
add_fp_unittest(
+ rintbf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ rintbf16_test.cpp
+ HDRS
+ RIntTest.h
+ DEPENDS
+ libc.hdr.fenv_macros
+ libc.src.math.rintbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
lrint_test
NEED_MPFR
SUITE
@@ -933,6 +1005,23 @@ add_fp_unittest(
)
add_fp_unittest(
+ lrintbf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ lrintbf16_test.cpp
+ HDRS
+ RoundToIntegerTest.h
+ DEPENDS
+ libc.src.math.lrintbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
llrint_test
NEED_MPFR
SUITE
@@ -997,6 +1086,23 @@ add_fp_unittest(
)
add_fp_unittest(
+ llrintbf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ llrintbf16_test.cpp
+ HDRS
+ RoundToIntegerTest.h
+ DEPENDS
+ libc.src.math.llrintbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
exp_test
NEED_MPFR
SUITE
@@ -2170,6 +2276,17 @@ add_fp_unittest(
)
add_fp_unittest(
+ atanpif16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ atanpif16_test.cpp
+ DEPENDS
+ libc.src.math.atanpif16
+)
+
+add_fp_unittest(
fmul_test
NEED_MPFR
SUITE
@@ -2283,6 +2400,17 @@ add_fp_unittest(
)
add_fp_unittest(
+ asinpif16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ asinpif16_test.cpp
+ DEPENDS
+ libc.src.math.asinpif16
+)
+
+add_fp_unittest(
acosf_test
NEED_MPFR
SUITE
@@ -2972,6 +3100,302 @@ add_fp_unittest(
libc.src.__support.macros.properties.types
)
+add_fp_unittest(
+ bf16add_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16add_test.cpp
+ HDRS
+ AddTest.h
+ DEPENDS
+ libc.src.math.bf16add
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16addf_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16addf_test.cpp
+ HDRS
+ AddTest.h
+ DEPENDS
+ libc.src.math.bf16addf
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16addl_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16addl_test.cpp
+ HDRS
+ AddTest.h
+ DEPENDS
+ libc.src.math.bf16addl
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16addf128_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16addf128_test.cpp
+ HDRS
+ AddTest.h
+ DEPENDS
+ libc.src.math.bf16addf128
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16div_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16div_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.src.math.bf16div
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16divf_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16divf_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.src.math.bf16divf
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16divl_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16divl_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.src.math.bf16divl
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16divf128_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16divf128_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.src.math.bf16divf128
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16fma_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16fma_test.cpp
+ HDRS
+ FmaTest.h
+ DEPENDS
+ libc.src.math.bf16fma
+ libc.src.stdlib.rand
+ libc.src.stdlib.srand
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16fmaf_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16fmaf_test.cpp
+ HDRS
+ FmaTest.h
+ DEPENDS
+ libc.src.math.bf16fmaf
+ libc.src.stdlib.rand
+ libc.src.stdlib.srand
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16fmal_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16fmal_test.cpp
+ HDRS
+ FmaTest.h
+ DEPENDS
+ libc.src.math.bf16fmal
+ libc.src.stdlib.rand
+ libc.src.stdlib.srand
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16fmaf128_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16fmaf128_test.cpp
+ HDRS
+ FmaTest.h
+ DEPENDS
+ libc.src.math.bf16fmaf128
+ libc.src.stdlib.rand
+ libc.src.stdlib.srand
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16mul_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16mul_test.cpp
+ HDRS
+ MulTest.h
+ DEPENDS
+ libc.src.math.bf16mul
+ libc.src.stdlib.rand
+ libc.src.stdlib.srand
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16mulf_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16mulf_test.cpp
+ HDRS
+ MulTest.h
+ DEPENDS
+ libc.src.math.bf16mulf
+ libc.src.stdlib.rand
+ libc.src.stdlib.srand
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16mull_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16mull_test.cpp
+ HDRS
+ MulTest.h
+ DEPENDS
+ libc.src.math.bf16mull
+ libc.src.stdlib.rand
+ libc.src.stdlib.srand
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16mulf128_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16mulf128_test.cpp
+ HDRS
+ MulTest.h
+ DEPENDS
+ libc.src.math.bf16mulf128
+ libc.src.stdlib.rand
+ libc.src.stdlib.srand
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16sub_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16sub_test.cpp
+ HDRS
+ SubTest.h
+ DEPENDS
+ libc.src.math.bf16sub
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16subf_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16subf_test.cpp
+ HDRS
+ SubTest.h
+ DEPENDS
+ libc.src.math.bf16subf
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16subl_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16subl_test.cpp
+ HDRS
+ SubTest.h
+ DEPENDS
+ libc.src.math.bf16subl
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16subf128_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ bf16subf128_test.cpp
+ HDRS
+ SubTest.h
+ DEPENDS
+ libc.src.math.bf16subf128
+ libc.src.__support.FPUtil.bfloat16
+)
+
add_subdirectory(generic)
add_subdirectory(smoke)
diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h
index 6af9cfe..e5e9386 100644
--- a/libc/test/src/math/RoundToIntegerTest.h
+++ b/libc/test/src/math/RoundToIntegerTest.h
@@ -127,8 +127,8 @@ public:
test_one_input(func, FloatType(-1.0), IntType(-1), false);
test_one_input(func, FloatType(10.0), IntType(10), false);
test_one_input(func, FloatType(-10.0), IntType(-10), false);
- test_one_input(func, FloatType(1234.0), IntType(1234), false);
- test_one_input(func, FloatType(-1234.0), IntType(-1234), false);
+ test_one_input(func, FloatType(1232.0), IntType(1232), false);
+ test_one_input(func, FloatType(-1232.0), IntType(-1232), false);
// The rest of this function compares with an equivalent MPFR function
// which rounds floating point numbers to long values. There is no MPFR
diff --git a/libc/test/src/math/asinpif16_test.cpp b/libc/test/src/math/asinpif16_test.cpp
new file mode 100644
index 0000000..3718f39
--- /dev/null
+++ b/libc/test/src/math/asinpif16_test.cpp
@@ -0,0 +1,40 @@
+//===-- Exhaustive test for asinpif16 -------------------------------------===//
+//
+// 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/math/asinpif16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcAsinpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// Range: [0, Inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7c00U;
+
+// Range: [-Inf, 0]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xfc00U;
+
+TEST_F(LlvmLibcAsinpif16Test, PositiveRange) {
+ for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+ float16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asinpi, x,
+ LIBC_NAMESPACE::asinpif16(x), 0.5);
+ }
+}
+
+TEST_F(LlvmLibcAsinpif16Test, NegativeRange) {
+ for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+ float16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asinpi, x,
+ LIBC_NAMESPACE::asinpif16(x), 0.5);
+ }
+}
diff --git a/libc/test/src/math/atanpif16_test.cpp b/libc/test/src/math/atanpif16_test.cpp
new file mode 100644
index 0000000..38771f0
--- /dev/null
+++ b/libc/test/src/math/atanpif16_test.cpp
@@ -0,0 +1,40 @@
+//===-- Exhaustive test for atanpif16 -------------------------------------===//
+//
+// 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/math/atanpif16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcAtanpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// Range: [0, Inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7c00U;
+
+// Range: [-Inf, 0]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xfc00U;
+
+TEST_F(LlvmLibcAtanpif16Test, PositiveRange) {
+ for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+ float16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atanpi, x,
+ LIBC_NAMESPACE::atanpif16(x), 0.5);
+ }
+}
+
+TEST_F(LlvmLibcAtanpif16Test, NegativeRange) {
+ for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+ float16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atanpi, x,
+ LIBC_NAMESPACE::atanpif16(x), 0.5);
+ }
+}
diff --git a/libc/test/src/math/bf16add_test.cpp b/libc/test/src/math/bf16add_test.cpp
new file mode 100644
index 0000000..9e9c594
--- /dev/null
+++ b/libc/test/src/math/bf16add_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16add ---------------------------------------------===//
+//
+// 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 "AddTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16add.h"
+
+LIST_ADD_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16add)
diff --git a/libc/test/src/math/bf16addf128_test.cpp b/libc/test/src/math/bf16addf128_test.cpp
new file mode 100644
index 0000000..46f7ad3
--- /dev/null
+++ b/libc/test/src/math/bf16addf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16addf128 -----------------------------------------===//
+//
+// 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 "AddTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16addf128.h"
+
+LIST_ADD_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16addf128)
diff --git a/libc/test/src/math/bf16addf_test.cpp b/libc/test/src/math/bf16addf_test.cpp
new file mode 100644
index 0000000..06d56cf
--- /dev/null
+++ b/libc/test/src/math/bf16addf_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16addf --------------------------------------------===//
+//
+// 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 "AddTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16addf.h"
+
+LIST_ADD_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16addf)
diff --git a/libc/test/src/math/bf16addl_test.cpp b/libc/test/src/math/bf16addl_test.cpp
new file mode 100644
index 0000000..bf54827
--- /dev/null
+++ b/libc/test/src/math/bf16addl_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16addl --------------------------------------------===//
+//
+// 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 "AddTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16addl.h"
+
+LIST_ADD_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16addl)
diff --git a/libc/test/src/math/bf16div_test.cpp b/libc/test/src/math/bf16div_test.cpp
new file mode 100644
index 0000000..4516351
--- /dev/null
+++ b/libc/test/src/math/bf16div_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16div ---------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16div.h"
+
+LIST_DIV_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16div)
diff --git a/libc/test/src/math/bf16divf128_test.cpp b/libc/test/src/math/bf16divf128_test.cpp
new file mode 100644
index 0000000..c42c5bb
--- /dev/null
+++ b/libc/test/src/math/bf16divf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16divf128 -----------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16divf128.h"
+
+LIST_DIV_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16divf128)
diff --git a/libc/test/src/math/bf16divf_test.cpp b/libc/test/src/math/bf16divf_test.cpp
new file mode 100644
index 0000000..873920b
--- /dev/null
+++ b/libc/test/src/math/bf16divf_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16divf --------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16divf.h"
+
+LIST_DIV_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16divf)
diff --git a/libc/test/src/math/bf16divl_test.cpp b/libc/test/src/math/bf16divl_test.cpp
new file mode 100644
index 0000000..32ecd62
--- /dev/null
+++ b/libc/test/src/math/bf16divl_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16divl --------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16divl.h"
+
+LIST_DIV_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16divl)
diff --git a/libc/test/src/math/bf16fma_test.cpp b/libc/test/src/math/bf16fma_test.cpp
new file mode 100644
index 0000000..81c73a0c
--- /dev/null
+++ b/libc/test/src/math/bf16fma_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fma ---------------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fma.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16fma)
diff --git a/libc/test/src/math/bf16fmaf128_test.cpp b/libc/test/src/math/bf16fmaf128_test.cpp
new file mode 100644
index 0000000..dd8f473
--- /dev/null
+++ b/libc/test/src/math/bf16fmaf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fmaf128 -----------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fmaf128.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16fmaf128)
diff --git a/libc/test/src/math/bf16fmaf_test.cpp b/libc/test/src/math/bf16fmaf_test.cpp
new file mode 100644
index 0000000..04c6748
--- /dev/null
+++ b/libc/test/src/math/bf16fmaf_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fmaf --------------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fmaf.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16fmaf)
diff --git a/libc/test/src/math/bf16fmal_test.cpp b/libc/test/src/math/bf16fmal_test.cpp
new file mode 100644
index 0000000..4c45e2c
--- /dev/null
+++ b/libc/test/src/math/bf16fmal_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fmal --------------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fmal.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16fmal)
diff --git a/libc/test/src/math/bf16mul_test.cpp b/libc/test/src/math/bf16mul_test.cpp
new file mode 100644
index 0000000..3682705
--- /dev/null
+++ b/libc/test/src/math/bf16mul_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bf16mul ---------------------------------------------===//
+//
+// 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 "MulTest.h"
+
+#include "src/math/bf16mul.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+
+LIST_MUL_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16mul)
diff --git a/libc/test/src/math/bf16mulf128_test.cpp b/libc/test/src/math/bf16mulf128_test.cpp
new file mode 100644
index 0000000..6aee2687
--- /dev/null
+++ b/libc/test/src/math/bf16mulf128_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bf16mulf128 -----------------------------------------===//
+//
+// 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 "MulTest.h"
+
+#include "src/math/bf16mulf128.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+
+LIST_MUL_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16mulf128)
diff --git a/libc/test/src/math/bf16mulf_test.cpp b/libc/test/src/math/bf16mulf_test.cpp
new file mode 100644
index 0000000..048b60f
--- /dev/null
+++ b/libc/test/src/math/bf16mulf_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bf16mulf --------------------------------------------===//
+//
+// 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 "MulTest.h"
+
+#include "src/math/bf16mulf.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+
+LIST_MUL_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16mulf)
diff --git a/libc/test/src/math/bf16mull_test.cpp b/libc/test/src/math/bf16mull_test.cpp
new file mode 100644
index 0000000..b8439b2
--- /dev/null
+++ b/libc/test/src/math/bf16mull_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bf16mull --------------------------------------------===//
+//
+// 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 "MulTest.h"
+
+#include "src/math/bf16mull.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+
+LIST_MUL_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16mull)
diff --git a/libc/test/src/math/bf16sub_test.cpp b/libc/test/src/math/bf16sub_test.cpp
new file mode 100644
index 0000000..4a793dc
--- /dev/null
+++ b/libc/test/src/math/bf16sub_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16sub ---------------------------------------------===//
+//
+// 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 "SubTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16sub.h"
+
+LIST_SUB_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16sub)
diff --git a/libc/test/src/math/bf16subf128_test.cpp b/libc/test/src/math/bf16subf128_test.cpp
new file mode 100644
index 0000000..25d6711
--- /dev/null
+++ b/libc/test/src/math/bf16subf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16subf128 -----------------------------------------===//
+//
+// 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 "SubTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16subf128.h"
+
+LIST_SUB_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16subf128)
diff --git a/libc/test/src/math/bf16subf_test.cpp b/libc/test/src/math/bf16subf_test.cpp
new file mode 100644
index 0000000..e8c7440
--- /dev/null
+++ b/libc/test/src/math/bf16subf_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16subf --------------------------------------------===//
+//
+// 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 "SubTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16subf.h"
+
+LIST_SUB_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16subf)
diff --git a/libc/test/src/math/bf16subl_test.cpp b/libc/test/src/math/bf16subl_test.cpp
new file mode 100644
index 0000000..2997369
--- /dev/null
+++ b/libc/test/src/math/bf16subl_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16subl --------------------------------------------===//
+//
+// 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 "SubTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16subl.h"
+
+LIST_SUB_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16subl)
diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt
index 5246337..07c36f424 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -378,6 +378,22 @@ add_fp_unittest(
)
add_fp_unittest(
+ fmodbf16_test
+ NO_RUN_POSTBUILD
+ NEED_MPFR
+ SUITE
+ libc_math_exhaustive_tests
+ SRCS
+ fmodbf16_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.fmodbf16
+ libc.src.__support.FPUtil.bfloat16
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
coshf_test
NO_RUN_POSTBUILD
NEED_MPFR
@@ -567,3 +583,75 @@ add_fp_unittest(
LINK_LIBRARIES
-lpthread
)
+
+add_fp_unittest(
+ bfloat16_add_test
+ NO_RUN_POSTBUILD
+ NEED_MPFR
+ SUITE
+ libc_math_exhaustive_tests
+ SRCS
+ bfloat16_add_test.cpp
+ COMPILE_OPTIONS
+ ${libc_opt_high_flag}
+ DEPENDS
+ .exhaustive_test
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ bfloat16_div_test
+ NO_RUN_POSTBUILD
+ NEED_MPFR
+ SUITE
+ libc_math_exhaustive_tests
+ SRCS
+ bfloat16_div_test.cpp
+ COMPILE_OPTIONS
+ ${libc_opt_high_flag}
+ DEPENDS
+ .exhaustive_test
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ bfloat16_mul_test
+ NO_RUN_POSTBUILD
+ NEED_MPFR
+ SUITE
+ libc_math_exhaustive_tests
+ SRCS
+ bfloat16_mul_test.cpp
+ COMPILE_OPTIONS
+ ${libc_opt_high_flag}
+ DEPENDS
+ .exhaustive_test
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ bfloat16_sub_test
+ NO_RUN_POSTBUILD
+ NEED_MPFR
+ SUITE
+ libc_math_exhaustive_tests
+ SRCS
+ bfloat16_sub_test.cpp
+ COMPILE_OPTIONS
+ ${libc_opt_high_flag}
+ DEPENDS
+ .exhaustive_test
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ LINK_LIBRARIES
+ -lpthread
+)
diff --git a/libc/test/src/math/exhaustive/bfloat16_add_test.cpp b/libc/test/src/math/exhaustive/bfloat16_add_test.cpp
new file mode 100644
index 0000000..3f4c779
--- /dev/null
+++ b/libc/test/src/math/exhaustive/bfloat16_add_test.cpp
@@ -0,0 +1,65 @@
+//===-- Exhaustive tests for bfloat16 addition ----------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPCommon.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+using LIBC_NAMESPACE::fputil::BFloat16;
+
+static BFloat16 add_func(BFloat16 x, BFloat16 y) { return x + y; }
+
+struct Bfloat16AddChecker : public virtual LIBC_NAMESPACE::testing::Test {
+ using FloatType = BFloat16;
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>;
+ using StorageType = typename FPBits::StorageType;
+
+ uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start,
+ uint16_t y_stop, mpfr::RoundingMode rounding) {
+ mpfr::ForceRoundingMode r(rounding);
+ if (!r.success)
+ return true;
+ uint16_t xbits = x_start;
+ uint64_t failed = 0;
+ do {
+ BFloat16 x = FPBits(xbits).get_val();
+ uint16_t ybits = xbits;
+ do {
+ BFloat16 y = FPBits(ybits).get_val();
+ mpfr::BinaryInput<BFloat16> input{x, y};
+ bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY(
+ mpfr::Operation::Add, input, add_func(x, y), 0.5, rounding);
+ failed += (!correct);
+ } while (ybits++ < y_stop);
+ } while (xbits++ < x_stop);
+ return failed;
+ }
+};
+
+using LlvmLibcBfloat16ExhaustiveAddTest =
+ LlvmLibcExhaustiveMathTest<Bfloat16AddChecker, 1 << 2>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcBfloat16ExhaustiveAddTest, PositiveRange) {
+ test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcBfloat16ExhaustiveAddTest, NegativeRange) {
+ test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP);
+}
diff --git a/libc/test/src/math/exhaustive/bfloat16_div_test.cpp b/libc/test/src/math/exhaustive/bfloat16_div_test.cpp
new file mode 100644
index 0000000..2648d5f
--- /dev/null
+++ b/libc/test/src/math/exhaustive/bfloat16_div_test.cpp
@@ -0,0 +1,65 @@
+//===-- Exhaustive tests for bfloat16 division ----------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPCommon.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+using LIBC_NAMESPACE::fputil::BFloat16;
+
+static BFloat16 div_func(BFloat16 x, BFloat16 y) { return x / y; }
+
+struct Bfloat16DivChecker : public virtual LIBC_NAMESPACE::testing::Test {
+ using FloatType = BFloat16;
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>;
+ using StorageType = typename FPBits::StorageType;
+
+ uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start,
+ uint16_t y_stop, mpfr::RoundingMode rounding) {
+ mpfr::ForceRoundingMode r(rounding);
+ if (!r.success)
+ return true;
+ uint16_t xbits = x_start;
+ uint64_t failed = 0;
+ do {
+ BFloat16 x = FPBits(xbits).get_val();
+ uint16_t ybits = xbits;
+ do {
+ BFloat16 y = FPBits(ybits).get_val();
+ mpfr::BinaryInput<BFloat16> input{x, y};
+ bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY(
+ mpfr::Operation::Div, input, div_func(x, y), 0.5, rounding);
+ failed += (!correct);
+ } while (ybits++ < y_stop);
+ } while (xbits++ < x_stop);
+ return failed;
+ }
+};
+
+using LlvmLibcBfloat16ExhaustiveDivTest =
+ LlvmLibcExhaustiveMathTest<Bfloat16DivChecker, 1 << 2>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcBfloat16ExhaustiveDivTest, PositiveRange) {
+ test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcBfloat16ExhaustiveDivTest, NegativeRange) {
+ test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP);
+}
diff --git a/libc/test/src/math/exhaustive/bfloat16_mul_test.cpp b/libc/test/src/math/exhaustive/bfloat16_mul_test.cpp
new file mode 100644
index 0000000..3cbbcb5
--- /dev/null
+++ b/libc/test/src/math/exhaustive/bfloat16_mul_test.cpp
@@ -0,0 +1,65 @@
+//===-- Exhaustive tests for bfloat16 multiplication ----------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPCommon.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+using LIBC_NAMESPACE::fputil::BFloat16;
+
+static BFloat16 mul_func(BFloat16 x, BFloat16 y) { return x * y; }
+
+struct Bfloat16MulChecker : public virtual LIBC_NAMESPACE::testing::Test {
+ using FloatType = BFloat16;
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>;
+ using StorageType = typename FPBits::StorageType;
+
+ uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start,
+ uint16_t y_stop, mpfr::RoundingMode rounding) {
+ mpfr::ForceRoundingMode r(rounding);
+ if (!r.success)
+ return true;
+ uint16_t xbits = x_start;
+ uint64_t failed = 0;
+ do {
+ BFloat16 x = FPBits(xbits).get_val();
+ uint16_t ybits = xbits;
+ do {
+ BFloat16 y = FPBits(ybits).get_val();
+ mpfr::BinaryInput<BFloat16> input{x, y};
+ bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY(
+ mpfr::Operation::Mul, input, mul_func(x, y), 0.5, rounding);
+ failed += (!correct);
+ } while (ybits++ < y_stop);
+ } while (xbits++ < x_stop);
+ return failed;
+ }
+};
+
+using LlvmLibcBfloat16ExhaustiveMulTest =
+ LlvmLibcExhaustiveMathTest<Bfloat16MulChecker, 1 << 2>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcBfloat16ExhaustiveMulTest, PositiveRange) {
+ test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcBfloat16ExhaustiveMulTest, NegativeRange) {
+ test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP);
+}
diff --git a/libc/test/src/math/exhaustive/bfloat16_sub_test.cpp b/libc/test/src/math/exhaustive/bfloat16_sub_test.cpp
new file mode 100644
index 0000000..11bc6f5
--- /dev/null
+++ b/libc/test/src/math/exhaustive/bfloat16_sub_test.cpp
@@ -0,0 +1,65 @@
+//===-- Exhaustive tests for bfloat16 subtraction -------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "utils/MPFRWrapper/MPCommon.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+using LIBC_NAMESPACE::fputil::BFloat16;
+
+static BFloat16 sub_func(BFloat16 x, BFloat16 y) { return x - y; }
+
+struct Bfloat16SubChecker : public virtual LIBC_NAMESPACE::testing::Test {
+ using FloatType = BFloat16;
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<bfloat16>;
+ using StorageType = typename FPBits::StorageType;
+
+ uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start,
+ uint16_t y_stop, mpfr::RoundingMode rounding) {
+ mpfr::ForceRoundingMode r(rounding);
+ if (!r.success)
+ return true;
+ uint16_t xbits = x_start;
+ uint64_t failed = 0;
+ do {
+ BFloat16 x = FPBits(xbits).get_val();
+ uint16_t ybits = xbits;
+ do {
+ BFloat16 y = FPBits(ybits).get_val();
+ mpfr::BinaryInput<BFloat16> input{x, y};
+ bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY(
+ mpfr::Operation::Sub, input, sub_func(x, y), 0.5, rounding);
+ failed += (!correct);
+ } while (ybits++ < y_stop);
+ } while (xbits++ < x_stop);
+ return failed;
+ }
+};
+
+using LlvmLibcBfloat16ExhaustiveSubTest =
+ LlvmLibcExhaustiveMathTest<Bfloat16SubChecker, 1 << 2>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcBfloat16ExhaustiveSubTest, PositiveRange) {
+ test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcBfloat16ExhaustiveSubTest, NegativeRange) {
+ test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP);
+}
diff --git a/libc/test/src/math/exhaustive/exhaustive_test.h b/libc/test/src/math/exhaustive/exhaustive_test.h
index cdf459c..8be65ba 100644
--- a/libc/test/src/math/exhaustive/exhaustive_test.h
+++ b/libc/test/src/math/exhaustive/exhaustive_test.h
@@ -164,7 +164,7 @@ struct LlvmLibcExhaustiveMathTest
range_begin = current_value;
if (stop >= Increment && stop - Increment >= current_value) {
- range_end = current_value + Increment;
+ range_end = static_cast<StorageType>(current_value + Increment);
} else {
range_end = stop;
}
diff --git a/libc/test/src/math/exhaustive/fmodbf16_test.cpp b/libc/test/src/math/exhaustive/fmodbf16_test.cpp
new file mode 100644
index 0000000..122be7a
--- /dev/null
+++ b/libc/test/src/math/exhaustive/fmodbf16_test.cpp
@@ -0,0 +1,42 @@
+//===-- Exhaustive test for fmodbf16 --------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmodbf16.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+using LlvmLibcFmodf16ExhaustiveTest =
+ LlvmLibcBinaryOpExhaustiveMathTest<bfloat16, mpfr::Operation::Fmod,
+ LIBC_NAMESPACE::fmodbf16>;
+
+// range: [0, inf]
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7f80U;
+
+// range: [-0, -inf]
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xff80U;
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostivePositiveRange) {
+ test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, PostiveNegativeRange) {
+ test_full_range_all_roundings(POS_START, POS_STOP, NEG_START, NEG_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativePositiveRange) {
+ test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcFmodf16ExhaustiveTest, NegativeNegativeRange) {
+ test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP);
+}
diff --git a/libc/test/src/math/explogxf_test.cpp b/libc/test/src/math/explogxf_test.cpp
index 49cc962..4d35309 100644
--- a/libc/test/src/math/explogxf_test.cpp
+++ b/libc/test/src/math/explogxf_test.cpp
@@ -9,11 +9,11 @@
#include "hdr/math_macros.h"
#include "in_float_range_test_helper.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/math/acoshf_utils.h"
+#include "src/__support/math/exp10f_utils.h"
#include "src/math/fabs.h"
#include "src/math/fabsf.h"
-#include "src/math/generic/explogxf.h"
#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
using LlvmLibcExplogfTest = LIBC_NAMESPACE::testing::FPTest<float>;
diff --git a/libc/test/src/math/llrintbf16_test.cpp b/libc/test/src/math/llrintbf16_test.cpp
new file mode 100644
index 0000000..e841e62
--- /dev/null
+++ b/libc/test/src/math/llrintbf16_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for llrintbf16 ------------------------------------------===//
+//
+// 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 "RoundToIntegerTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/llrintbf16.h"
+
+LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(bfloat16, long long,
+ LIBC_NAMESPACE::llrintbf16)
diff --git a/libc/test/src/math/llroundbf16_test.cpp b/libc/test/src/math/llroundbf16_test.cpp
new file mode 100644
index 0000000..c3b7ea4
--- /dev/null
+++ b/libc/test/src/math/llroundbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for llroundbf16 -----------------------------------------===//
+//
+// 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 "RoundToIntegerTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/llroundbf16.h"
+
+LIST_ROUND_TO_INTEGER_TESTS(bfloat16, long long, LIBC_NAMESPACE::llroundbf16)
diff --git a/libc/test/src/math/lrintbf16_test.cpp b/libc/test/src/math/lrintbf16_test.cpp
new file mode 100644
index 0000000..65a5633b8
--- /dev/null
+++ b/libc/test/src/math/lrintbf16_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for lrintbf16 -------------------------------------------===//
+//
+// 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 "RoundToIntegerTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/lrintbf16.h"
+
+LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(bfloat16, long,
+ LIBC_NAMESPACE::lrintbf16)
diff --git a/libc/test/src/math/lroundbf16_test.cpp b/libc/test/src/math/lroundbf16_test.cpp
new file mode 100644
index 0000000..2f2b7b1
--- /dev/null
+++ b/libc/test/src/math/lroundbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for lroundbf16 ------------------------------------------===//
+//
+// 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 "RoundToIntegerTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/lroundbf16.h"
+
+LIST_ROUND_TO_INTEGER_TESTS(bfloat16, long, LIBC_NAMESPACE::lroundbf16)
diff --git a/libc/test/src/math/nearbyintbf16_test.cpp b/libc/test/src/math/nearbyintbf16_test.cpp
new file mode 100644
index 0000000..2d64fc5
--- /dev/null
+++ b/libc/test/src/math/nearbyintbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for nearbyintbf16 ---------------------------------------===//
+//
+// 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 "NearbyIntTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/nearbyintbf16.h"
+
+LIST_NEARBYINT_TESTS(bfloat16, LIBC_NAMESPACE::nearbyintbf16)
diff --git a/libc/test/src/math/rintbf16_test.cpp b/libc/test/src/math/rintbf16_test.cpp
new file mode 100644
index 0000000..c78dcf6
--- /dev/null
+++ b/libc/test/src/math/rintbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for rintbf16 --------------------------------------------===//
+//
+// 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 "RIntTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/rintbf16.h"
+
+LIST_RINT_TESTS(bfloat16, LIBC_NAMESPACE::rintbf16)
diff --git a/libc/test/src/math/smoke/AddTest.h b/libc/test/src/math/smoke/AddTest.h
index 68a4bbe..4bd794c 100644
--- a/libc/test/src/math/smoke/AddTest.h
+++ b/libc/test/src/math/smoke/AddTest.h
@@ -47,6 +47,10 @@ public:
EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.zero));
EXPECT_FP_EQ(inf, func(in.inf, in.neg_zero));
EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.neg_zero));
+ EXPECT_FP_EQ(inf, func(in.zero, in.inf));
+ EXPECT_FP_EQ(inf, func(in.neg_zero, in.inf));
+ EXPECT_FP_EQ(neg_inf, func(in.zero, in.neg_inf));
+ EXPECT_FP_EQ(neg_inf, func(in.neg_zero, in.neg_inf));
}
void test_invalid_operations(AddFunc func) {
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 40b7a342..152f38d 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -345,6 +345,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ truncbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ truncbf16_test.cpp
+ HDRS
+ TruncTest.h
+ DEPENDS
+ libc.src.math.truncbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
canonicalize_test
SUITE
libc-math-smoke-tests
@@ -420,6 +433,22 @@ add_fp_unittest(
)
add_fp_unittest(
+ canonicalizebf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ canonicalizebf16_test.cpp
+ HDRS
+ CanonicalizeTest.h
+ DEPENDS
+ libc.src.math.canonicalizebf16
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.integer_literals
+)
+
+add_fp_unittest(
iscanonical_test
SUITE
libc-math-smoke-tests
@@ -480,6 +509,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ iscanonicalbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ iscanonicalbf16_test.cpp
+ HDRS
+ IsCanonicalTest.h
+ DEPENDS
+ libc.src.math.iscanonicalbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
ceil_test
SUITE
libc-math-smoke-tests
@@ -544,6 +586,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ ceilbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ ceilbf16_test.cpp
+ HDRS
+ CeilTest.h
+ DEPENDS
+ libc.src.math.ceilbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
dfmal_test
SUITE
libc-math-smoke-tests
@@ -664,6 +719,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ floorbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ floorbf16_test.cpp
+ HDRS
+ FloorTest.h
+ DEPENDS
+ libc.src.math.floorbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
round_test
SUITE
libc-math-smoke-tests
@@ -728,6 +796,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ roundbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ roundbf16_test.cpp
+ HDRS
+ RoundTest.h
+ DEPENDS
+ libc.src.math.roundbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
roundeven_test
SUITE
libc-math-smoke-tests
@@ -792,6 +873,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ roundevenbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ roundevenbf16_test.cpp
+ HDRS
+ RoundEvenTest.h
+ DEPENDS
+ libc.src.math.roundevenbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
lround_test
SUITE
libc-math-smoke-tests
@@ -872,6 +966,23 @@ add_fp_unittest(
)
add_fp_unittest(
+ lroundbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ lroundbf16_test.cpp
+ HDRS
+ RoundToIntegerTest.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.math.lroundbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
llround_test
SUITE
libc-math-smoke-tests
@@ -952,6 +1063,23 @@ add_fp_unittest(
)
add_fp_unittest(
+ llroundbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ llroundbf16_test.cpp
+ HDRS
+ RoundToIntegerTest.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.math.llroundbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
rint_test
SUITE
libc-math-smoke-tests
@@ -1022,6 +1150,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ rintbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ rintbf16_test.cpp
+ HDRS
+ RIntTest.h
+ DEPENDS
+ libc.src.math.rintbf16
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
lrint_test
SUITE
libc-math-smoke-tests
@@ -1102,6 +1245,23 @@ add_fp_unittest(
)
add_fp_unittest(
+ lrintbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ lrintbf16_test.cpp
+ HDRS
+ RoundToIntegerTest.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.math.lrintbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
llrint_test
SUITE
libc-math-smoke-tests
@@ -1182,6 +1342,23 @@ add_fp_unittest(
)
add_fp_unittest(
+ llrintbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ llrintbf16_test.cpp
+ HDRS
+ RoundToIntegerTest.h
+ DEPENDS
+ libc.src.errno.errno
+ libc.src.math.llrintbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
exp_test
SUITE
libc-math-smoke-tests
@@ -1412,6 +1589,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ copysignbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ copysignbf16_test.cpp
+ HDRS
+ CopySignTest.h
+ DEPENDS
+ libc.src.math.copysignbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
frexp_test
SUITE
libc-math-smoke-tests
@@ -1472,6 +1664,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ frexpbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ frexpbf16_test.cpp
+ HDRS
+ FrexpTest.h
+ DEPENDS
+ libc.src.math.frexpbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
fromfp_test
SUITE
libc-math-smoke-tests
@@ -1532,6 +1737,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ fromfpbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fromfpbf16_test.cpp
+ HDRS
+ FromfpTest.h
+ DEPENDS
+ libc.src.math.fromfpbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
fromfpx_test
SUITE
libc-math-smoke-tests
@@ -1592,6 +1810,20 @@ add_fp_unittest(
)
add_fp_unittest(
+ fromfpxbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fromfpxbf16_test.cpp
+ HDRS
+ FromfpxTest.h
+ DEPENDS
+ libc.src.math.fromfpxbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+
+add_fp_unittest(
ufromfp_test
SUITE
libc-math-smoke-tests
@@ -1652,6 +1884,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ ufromfpbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ ufromfpbf16_test.cpp
+ HDRS
+ UfromfpTest.h
+ DEPENDS
+ libc.src.math.ufromfpbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
ufromfpx_test
SUITE
libc-math-smoke-tests
@@ -1712,6 +1957,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ ufromfpxbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ ufromfpxbf16_test.cpp
+ HDRS
+ UfromfpxTest.h
+ DEPENDS
+ libc.src.math.ufromfpxbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
ilogb_test
SUITE
libc-math-smoke-tests
@@ -1787,6 +2045,22 @@ add_fp_unittest(
)
add_fp_unittest(
+ ilogbbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ ilogbbf16_test.cpp
+ HDRS
+ ILogbTest.h
+ DEPENDS
+ libc.src.math.ilogbbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
issignaling_test
SUITE
libc-math-smoke-tests
@@ -1847,6 +2121,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ issignalingbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ issignalingbf16_test.cpp
+ HDRS
+ IsSignalingTest.h
+ DEPENDS
+ libc.src.math.issignalingbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
llogb_test
SUITE
libc-math-smoke-tests
@@ -1922,6 +2209,22 @@ add_fp_unittest(
)
add_fp_unittest(
+ llogbbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ llogbbf16_test.cpp
+ HDRS
+ ILogbTest.h
+ DEPENDS
+ libc.src.math.llogbbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
ldexp_test
SUITE
libc-math-smoke-tests
@@ -1931,6 +2234,7 @@ add_fp_unittest(
LdExpTest.h
DEPENDS
libc.src.math.ldexp
+ libc.src.__support.CPP.algorithm
libc.src.__support.CPP.limits
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.normal_float
@@ -1946,6 +2250,7 @@ add_fp_unittest(
LdExpTest.h
DEPENDS
libc.src.math.ldexpf
+ libc.src.__support.CPP.algorithm
libc.src.__support.CPP.limits
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.normal_float
@@ -1961,6 +2266,7 @@ add_fp_unittest(
LdExpTest.h
DEPENDS
libc.src.math.ldexpl
+ libc.src.__support.CPP.algorithm
libc.src.__support.CPP.limits
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.normal_float
@@ -1976,6 +2282,7 @@ add_fp_unittest(
LdExpTest.h
DEPENDS
libc.src.math.ldexpf16
+ libc.src.__support.CPP.algorithm
libc.src.__support.CPP.limits
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.normal_float
@@ -1991,12 +2298,30 @@ add_fp_unittest(
LdExpTest.h
DEPENDS
libc.src.math.ldexpf128
+ libc.src.__support.CPP.algorithm
libc.src.__support.CPP.limits
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.normal_float
)
add_fp_unittest(
+ ldexpbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ ldexpbf16_test.cpp
+ HDRS
+ LdExpTest.h
+ DEPENDS
+ libc.src.math.ldexpbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.CPP.limits
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.normal_float
+)
+
+add_fp_unittest(
logb_test
SUITE
libc-math-smoke-tests
@@ -2067,6 +2392,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ logbbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ logbbf16_test.cpp
+ HDRS
+ LogbTest.h
+ DEPENDS
+ libc.src.math.logbbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
modf_test
SUITE
libc-math-smoke-tests
@@ -2142,6 +2482,22 @@ add_fp_unittest(
)
add_fp_unittest(
+ modfbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ modfbf16_test.cpp
+ HDRS
+ ModfTest.h
+ DEPENDS
+ libc.src.math.modfbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.nearest_integer_operations
+)
+
+add_fp_unittest(
fdimf_test
SUITE
libc-math-smoke-tests
@@ -2212,6 +2568,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fdimbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fdimbf16_test.cpp
+ HDRS
+ FDimTest.h
+ DEPENDS
+ libc.src.math.fdimbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fminf_test
SUITE
libc-math-smoke-tests
@@ -2282,6 +2653,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fminbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fminbf16_test.cpp
+ HDRS
+ FMinTest.h
+ DEPENDS
+ libc.src.math.fminbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fmaxf_test
SUITE
libc-math-smoke-tests
@@ -2352,6 +2738,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fmaxbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fmaxbf16_test.cpp
+ HDRS
+ FMaxTest.h
+ DEPENDS
+ libc.src.math.fmaxbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fmaximuml_test
SUITE
libc-math-smoke-tests
@@ -2436,6 +2837,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fmaximumbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fmaximumbf16_test.cpp
+ HDRS
+ FMaximumTest.h
+ DEPENDS
+ libc.src.math.fmaximumbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fmaximum_num_test
SUITE
libc-math-smoke-tests
@@ -2492,6 +2908,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fmaximum_numbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fmaximum_numbf16_test.cpp
+ HDRS
+ FMaximumTest.h
+ DEPENDS
+ libc.src.math.fmaximum_numbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fmaximum_magf_test
SUITE
libc-math-smoke-tests
@@ -2567,6 +2998,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fmaximum_magbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fmaximum_magbf16_test.cpp
+ HDRS
+ FMaximumTest.h
+ DEPENDS
+ libc.src.math.fmaximum_magbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fmaximum_mag_numf_test
SUITE
libc-math-smoke-tests
@@ -2637,6 +3083,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fmaximum_mag_numbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fmaximum_mag_numbf16_test.cpp
+ HDRS
+ FMaximumTest.h
+ DEPENDS
+ libc.src.math.fmaximum_mag_numbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fminimuml_test
SUITE
libc-math-smoke-tests
@@ -2707,6 +3168,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fminimumbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fminimumbf16_test.cpp
+ HDRS
+ FMaximumTest.h
+ DEPENDS
+ libc.src.math.fminimumbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fminimum_numf_test
SUITE
libc-math-smoke-tests
@@ -2777,6 +3253,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fminimum_numbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fminimum_numf16_test.cpp
+ HDRS
+ FMaximumTest.h
+ DEPENDS
+ libc.src.math.fminimum_numf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fminimum_magf_test
SUITE
libc-math-smoke-tests
@@ -2847,6 +3338,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fminimum_magbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fminimum_magbf16_test.cpp
+ HDRS
+ FMaximumTest.h
+ DEPENDS
+ libc.src.math.fminimum_magbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fminimum_mag_numf_test
SUITE
libc-math-smoke-tests
@@ -2917,6 +3423,21 @@ add_fp_unittest(
)
add_fp_unittest(
+ fminimum_mag_numbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fminimum_mag_numbf16_test.cpp
+ HDRS
+ FMaximumTest.h
+ DEPENDS
+ libc.src.math.fminimum_mag_numbf16
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
fmul_test
SUITE
libc-math-smoke-tests
@@ -3132,6 +3653,20 @@ add_fp_unittest(
)
add_fp_unittest(
+ remquobf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ remquobf16_test.cpp
+ HDRS
+ RemQuoTest.h
+ DEPENDS
+ libc.src.math.remquobf16
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
hypotf_test
SUITE
libc-math-smoke-tests
@@ -3248,6 +3783,22 @@ add_fp_unittest(
)
add_fp_unittest(
+ nanbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nanbf16_test.cpp
+ DEPENDS
+ libc.hdr.signal_macros
+ libc.src.math.nanbf16
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ # FIXME: The nan tests currently have death tests, which aren't supported for
+ # hermetic tests.
+ UNIT_TEST_ONLY
+)
+
+add_fp_unittest(
nearbyint_test
SUITE
libc-math-smoke-tests
@@ -3313,6 +3864,20 @@ add_fp_unittest(
)
add_fp_unittest(
+ nearbyintbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nearbyintbf16_test.cpp
+ HDRS
+ NearbyIntTest.h
+ DEPENDS
+ libc.hdr.fenv_macros
+ libc.src.math.nearbyintbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
nextafter_test
SUITE
libc-math-smoke-tests
@@ -3392,6 +3957,23 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ nextafterbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextafterbf16_test.cpp
+ HDRS
+ NextAfterTest.h
+ DEPENDS
+ libc.hdr.fenv_macros
+ libc.src.math.nextafterbf16
+ libc.src.__support.CPP.bit
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
# FIXME: These tests are currently spurious for the GPU.
if(NOT LIBC_TARGET_OS_IS_GPU)
add_fp_unittest(
@@ -3460,6 +4042,23 @@ add_fp_unittest(
)
add_fp_unittest(
+ nexttowardbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nexttowardbf16_test.cpp
+ HDRS
+ NextTowardTest.h
+ DEPENDS
+ libc.hdr.fenv_macros
+ libc.src.math.nexttowardbf16
+ libc.src.__support.CPP.bit
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
nextdown_test
SUITE
libc-math-smoke-tests
@@ -3520,6 +4119,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ nextdownbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextdownbf16_test.cpp
+ HDRS
+ NextDownTest.h
+ DEPENDS
+ libc.src.math.nextdownbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
nextup_test
SUITE
libc-math-smoke-tests
@@ -3579,6 +4191,19 @@ add_fp_unittest(
libc.src.math.nextupf128
)
+add_fp_unittest(
+ nextupbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ nextupbf16_test.cpp
+ HDRS
+ NextUpTest.h
+ DEPENDS
+ libc.src.math.nextupbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
# TODO(lntue): The current implementation of fputil::general::fma<float> is only
# correctly rounded for the default rounding mode round-to-nearest tie-to-even.
add_fp_unittest(
@@ -3879,6 +4504,23 @@ add_fp_unittest(
)
add_fp_unittest(
+ fmodbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fmodbf16_test.cpp
+ HDRS
+ FModTest.h
+ DEPENDS
+ libc.hdr.fenv_macros
+ libc.src.errno.errno
+ libc.src.math.fmodbf16
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fenv_impl
+ UNIT_TEST_ONLY
+)
+
+add_fp_unittest(
coshf_test
SUITE
libc-math-smoke-tests
@@ -3979,6 +4621,18 @@ add_fp_unittest(
)
add_fp_unittest(
+ atanpif16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ atanpif16_test.cpp
+ DEPENDS
+ libc.src.math.atanpif16
+ libc.src.errno.errno
+)
+
+add_fp_unittest(
asinhf_test
SUITE
libc-math-smoke-tests
@@ -4002,6 +4656,18 @@ add_fp_unittest(
)
add_fp_unittest(
+ asinpif16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ asinpif16_test.cpp
+ DEPENDS
+ libc.src.math.asinpif16
+ libc.src.errno.errno
+)
+
+add_fp_unittest(
acoshf_test
SUITE
libc-math-smoke-tests
@@ -4245,6 +4911,22 @@ add_fp_unittest(
)
add_fp_unittest(
+ scalblnbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ scalblnbf16_test.cpp
+ HDRS
+ ScalbnTest.h
+ DEPENDS
+ libc.src.math.scalblnbf16
+ libc.src.__support.CPP.limits
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.normal_float
+)
+
+add_fp_unittest(
scalbn_test
SUITE
libc-math-smoke-tests
@@ -4320,6 +5002,22 @@ add_fp_unittest(
)
add_fp_unittest(
+ scalbnbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ scalbnbf16_test.cpp
+ HDRS
+ ScalbnTest.h
+ DEPENDS
+ libc.src.math.scalbnbf16
+ libc.src.__support.CPP.limits
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.normal_float
+)
+
+add_fp_unittest(
erff_test
SUITE
libc-math-smoke-tests
@@ -4414,6 +5112,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ totalorderbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ totalorderbf16_test.cpp
+ HDRS
+ TotalOrderTest.h
+ DEPENDS
+ libc.src.math.totalorderbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
totalordermag_test
SUITE
libc-math-smoke-tests
@@ -4474,6 +5185,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ totalordermagbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ totalordermagbf16_test.cpp
+ HDRS
+ TotalOrderMagTest.h
+ DEPENDS
+ libc.src.math.totalordermagbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
getpayload_test
SUITE
libc-math-smoke-tests
@@ -4534,6 +5258,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ getpayloadbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ getpayloadbf16_test.cpp
+ HDRS
+ GetPayloadTest.h
+ DEPENDS
+ libc.src.math.getpayloadbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
setpayload_test
SUITE
libc-math-smoke-tests
@@ -4594,6 +5331,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ setpayloadbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ setpayloadbf16_test.cpp
+ HDRS
+ SetPayloadTest.h
+ DEPENDS
+ libc.src.math.setpayloadbf16
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
setpayloadsig_test
SUITE
libc-math-smoke-tests
@@ -4653,6 +5403,18 @@ add_fp_unittest(
libc.src.math.setpayloadsigf128
)
+add_fp_unittest(
+ setpayloadsigbf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ setpayloadsigbf16_test.cpp
+ HDRS
+ SetPayloadTest.h
+ DEPENDS
+ libc.src.math.setpayloadsigbf16
+ libc.src.__support.FPUtil.bfloat16
+)
add_fp_unittest(
f16add_test
@@ -5307,6 +6069,69 @@ add_fp_unittest(
)
add_fp_unittest(
+ bfloat16_add_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bfloat16_add_test.cpp
+ HDRS
+ AddTest.h
+ DEPENDS
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.properties.os
+ libc.src.__support.macros.properties.types
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+)
+
+add_fp_unittest(
+ bfloat16_div_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bfloat16_div_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.src.__support.FPUtil.bfloat16
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+)
+
+add_fp_unittest(
+ bfloat16_mul_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bfloat16_mul_test.cpp
+ HDRS
+ MulTest.h
+ DEPENDS
+ libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.bfloat16
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+)
+
+add_fp_unittest(
+ bfloat16_sub_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bfloat16_sub_test.cpp
+ HDRS
+ SubTest.h
+ DEPENDS
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.macros.properties.os
+ libc.src.__support.macros.properties.types
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+)
+
+add_fp_unittest(
add_same_type_test
SUITE
libc-math-smoke-tests
@@ -5337,3 +6162,312 @@ add_fp_unittest(
libc.src.__support.macros.properties.os
libc.src.__support.macros.properties.types
)
+
+add_fp_unittest(
+ bf16add_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16add_test.cpp
+ HDRS
+ AddTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16add
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.properties.os
+)
+
+add_fp_unittest(
+ bf16addf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16addf_test.cpp
+ HDRS
+ AddTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16addf
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.properties.os
+)
+
+add_fp_unittest(
+ bf16addl_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16addl_test.cpp
+ HDRS
+ AddTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16addl
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.properties.os
+)
+
+add_fp_unittest(
+ bf16addf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16addf128_test.cpp
+ HDRS
+ AddTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16addf128
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.properties.os
+)
+
+add_fp_unittest(
+ bf16fma_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16fma_test.cpp
+ HDRS
+ FmaTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16fma
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16fmaf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16fmaf_test.cpp
+ HDRS
+ FmaTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16fmaf
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16fmal_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16fmal_test.cpp
+ HDRS
+ FmaTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16fmal
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16fmaf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16fmaf128_test.cpp
+ HDRS
+ FmaTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16fmaf128
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16div_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16div_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16div
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16divf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16divf_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16divf
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16divl_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16divl_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16divl
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16divf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16divf128_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16divf128
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16mul_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16mul_test.cpp
+ HDRS
+ MulTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16mul
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16mulf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16mulf_test.cpp
+ HDRS
+ MulTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16mulf
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16mull_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16mull_test.cpp
+ HDRS
+ MulTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16mull
+ libc.src.__support.FPUtil.bfloat16
+)
+
+add_fp_unittest(
+ bf16mulf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16mulf128_test.cpp
+ HDRS
+ MulTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16mulf128
+ libc.src.__support.FPUtil.bfloat16
+)
+
+
+add_fp_unittest(
+ bf16sub_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16sub_test.cpp
+ HDRS
+ SubTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16sub
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.properties.os
+)
+
+add_fp_unittest(
+ bf16subf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16subf_test.cpp
+ HDRS
+ SubTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16subf
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.properties.os
+)
+
+add_fp_unittest(
+ bf16subl_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16subl_test.cpp
+ HDRS
+ SubTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16subl
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.properties.os
+)
+
+add_fp_unittest(
+ bf16subf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ bf16subf128_test.cpp
+ HDRS
+ SubTest.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.bf16subf128
+ libc.src.__support.FPUtil.bfloat16
+ libc.src.__support.macros.properties.os
+)
diff --git a/libc/test/src/math/smoke/CeilTest.h b/libc/test/src/math/smoke/CeilTest.h
index 7998eab..1839db9 100644
--- a/libc/test/src/math/smoke/CeilTest.h
+++ b/libc/test/src/math/smoke/CeilTest.h
@@ -59,10 +59,12 @@ public:
EXPECT_FP_EQ(T(-10.0), func(T(-10.32)));
EXPECT_FP_EQ(T(11.0), func(T(10.65)));
EXPECT_FP_EQ(T(-10.0), func(T(-10.65)));
+ EXPECT_FP_EQ(T(50.0), func(T(49.62)));
+ EXPECT_FP_EQ(T(-50.0), func(T(-50.31)));
EXPECT_FP_EQ(T(124.0), func(T(123.38)));
EXPECT_FP_EQ(T(-123.0), func(T(-123.38)));
EXPECT_FP_EQ(T(124.0), func(T(123.96)));
- EXPECT_FP_EQ(T(-123.0), func(T(-123.96)));
+ EXPECT_FP_EQ(T(-123.0), func(T(-123.5)));
}
};
diff --git a/libc/test/src/math/smoke/DivTest.h b/libc/test/src/math/smoke/DivTest.h
index d807479..ff82f68 100644
--- a/libc/test/src/math/smoke/DivTest.h
+++ b/libc/test/src/math/smoke/DivTest.h
@@ -47,6 +47,11 @@ public:
EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.zero));
EXPECT_FP_EQ(neg_inf, func(in.inf, in.neg_zero));
EXPECT_FP_EQ(inf, func(in.neg_inf, in.neg_zero));
+ EXPECT_FP_EQ(zero, func(in.min_normal, in.inf));
+ EXPECT_FP_EQ(zero, func(in.zero, in.inf));
+ EXPECT_FP_EQ(zero, func(in.neg_zero, in.neg_inf));
+ EXPECT_FP_EQ(neg_zero, func(in.min_normal, in.neg_inf));
+ EXPECT_FP_EQ(neg_zero, func(in.zero, in.neg_inf));
}
void test_division_by_zero(DivFunc func) {
diff --git a/libc/test/src/math/smoke/FModTest.h b/libc/test/src/math/smoke/FModTest.h
index 04cbc65..e74ee09 100644
--- a/libc/test/src/math/smoke/FModTest.h
+++ b/libc/test/src/math/smoke/FModTest.h
@@ -31,12 +31,22 @@ class FmodTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
DECLARE_SPECIAL_CONSTANTS(T)
+ static constexpr T one = T(1.0);
+ static constexpr T two = T(2.0);
+ static constexpr T neg_two = T(-2.0);
+ static constexpr T three = T(3.0);
+ static constexpr T val_neg_1_1 = T(-1.1);
+ static constexpr T val_6_5 = T(6.5);
+ static constexpr T val_neg_6_5 = T(-6.5);
+ static constexpr T val_2_25 = T(2.25);
+ static constexpr T val_neg_2_25 = T(-2.25);
+
public:
typedef T (*FModFunc)(T, T);
void testSpecialNumbers(FModFunc f) {
// fmod (+0, y) == +0 for y != 0.
- TEST_SPECIAL(zero, T(3.0), zero, false, 0);
+ TEST_SPECIAL(zero, three, zero, false, 0);
TEST_SPECIAL(zero, min_denormal, zero, false, 0);
TEST_SPECIAL(zero, -min_denormal, zero, false, 0);
TEST_SPECIAL(zero, min_normal, zero, false, 0);
@@ -45,7 +55,7 @@ public:
TEST_SPECIAL(zero, -max_normal, zero, false, 0);
// fmod (-0, y) == -0 for y != 0.
- TEST_SPECIAL(neg_zero, T(3.0), neg_zero, false, 0);
+ TEST_SPECIAL(neg_zero, three, neg_zero, false, 0);
TEST_SPECIAL(neg_zero, min_denormal, neg_zero, false, 0);
TEST_SPECIAL(neg_zero, -min_denormal, neg_zero, false, 0);
TEST_SPECIAL(neg_zero, min_normal, neg_zero, false, 0);
@@ -54,8 +64,8 @@ public:
TEST_SPECIAL(neg_zero, -max_normal, neg_zero, false, 0);
// fmod (+inf, y) == aNaN plus invalid exception.
- TEST_SPECIAL(inf, T(3.0), aNaN, true, FE_INVALID);
- TEST_SPECIAL(inf, T(-1.1), aNaN, true, FE_INVALID);
+ TEST_SPECIAL(inf, three, aNaN, true, FE_INVALID);
+ TEST_SPECIAL(inf, val_neg_1_1, aNaN, true, FE_INVALID);
TEST_SPECIAL(inf, zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(inf, neg_zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(inf, min_denormal, aNaN, true, FE_INVALID);
@@ -65,8 +75,8 @@ public:
TEST_SPECIAL(inf, neg_inf, aNaN, true, FE_INVALID);
// fmod (-inf, y) == aNaN plus invalid exception.
- TEST_SPECIAL(neg_inf, T(3.0), aNaN, true, FE_INVALID);
- TEST_SPECIAL(neg_inf, T(-1.1), aNaN, true, FE_INVALID);
+ TEST_SPECIAL(neg_inf, three, aNaN, true, FE_INVALID);
+ TEST_SPECIAL(neg_inf, val_neg_1_1, aNaN, true, FE_INVALID);
TEST_SPECIAL(neg_inf, zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(neg_inf, neg_zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(neg_inf, min_denormal, aNaN, true, FE_INVALID);
@@ -76,8 +86,8 @@ public:
TEST_SPECIAL(neg_inf, neg_inf, aNaN, true, FE_INVALID);
// fmod (x, +0) == aNaN plus invalid exception.
- TEST_SPECIAL(T(3.0), zero, aNaN, true, FE_INVALID);
- TEST_SPECIAL(T(-1.1), zero, aNaN, true, FE_INVALID);
+ TEST_SPECIAL(three, zero, aNaN, true, FE_INVALID);
+ TEST_SPECIAL(val_neg_1_1, zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(zero, zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(neg_zero, zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(min_denormal, zero, aNaN, true, FE_INVALID);
@@ -85,8 +95,8 @@ public:
TEST_SPECIAL(max_normal, zero, aNaN, true, FE_INVALID);
// fmod (x, -0) == aNaN plus invalid exception.
- TEST_SPECIAL(T(3.0), neg_zero, aNaN, true, FE_INVALID);
- TEST_SPECIAL(T(-1.1), neg_zero, aNaN, true, FE_INVALID);
+ TEST_SPECIAL(three, neg_zero, aNaN, true, FE_INVALID);
+ TEST_SPECIAL(val_neg_1_1, neg_zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(zero, neg_zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(neg_zero, neg_zero, aNaN, true, FE_INVALID);
TEST_SPECIAL(min_denormal, neg_zero, aNaN, true, FE_INVALID);
@@ -99,21 +109,21 @@ public:
TEST_SPECIAL(min_denormal, inf, min_denormal, false, 0);
TEST_SPECIAL(min_normal, inf, min_normal, false, 0);
TEST_SPECIAL(max_normal, inf, max_normal, false, 0);
- TEST_SPECIAL(T(3.0), inf, T(3.0), false, 0);
+ TEST_SPECIAL(three, inf, three, false, 0);
// fmod (x, -inf) == x for x not infinite.
TEST_SPECIAL(zero, neg_inf, zero, false, 0);
TEST_SPECIAL(neg_zero, neg_inf, neg_zero, false, 0);
TEST_SPECIAL(min_denormal, neg_inf, min_denormal, false, 0);
TEST_SPECIAL(min_normal, neg_inf, min_normal, false, 0);
TEST_SPECIAL(max_normal, neg_inf, max_normal, false, 0);
- TEST_SPECIAL(T(3.0), neg_inf, T(3.0), false, 0);
+ TEST_SPECIAL(three, neg_inf, three, false, 0);
TEST_SPECIAL(zero, aNaN, aNaN, false, 0);
TEST_SPECIAL(zero, neg_aNaN, aNaN, false, 0);
TEST_SPECIAL(neg_zero, aNaN, aNaN, false, 0);
TEST_SPECIAL(neg_zero, neg_aNaN, aNaN, false, 0);
- TEST_SPECIAL(T(1.0), aNaN, aNaN, false, 0);
- TEST_SPECIAL(T(1.0), neg_aNaN, aNaN, false, 0);
+ TEST_SPECIAL(one, aNaN, aNaN, false, 0);
+ TEST_SPECIAL(one, neg_aNaN, aNaN, false, 0);
TEST_SPECIAL(inf, aNaN, aNaN, false, 0);
TEST_SPECIAL(inf, neg_aNaN, aNaN, false, 0);
TEST_SPECIAL(neg_inf, aNaN, aNaN, false, 0);
@@ -122,8 +132,8 @@ public:
TEST_SPECIAL(zero, neg_sNaN, aNaN, false, FE_INVALID);
TEST_SPECIAL(neg_zero, sNaN, aNaN, false, FE_INVALID);
TEST_SPECIAL(neg_zero, neg_sNaN, aNaN, false, FE_INVALID);
- TEST_SPECIAL(T(1.0), sNaN, aNaN, false, FE_INVALID);
- TEST_SPECIAL(T(1.0), neg_sNaN, aNaN, false, FE_INVALID);
+ TEST_SPECIAL(one, sNaN, aNaN, false, FE_INVALID);
+ TEST_SPECIAL(one, neg_sNaN, aNaN, false, FE_INVALID);
TEST_SPECIAL(inf, sNaN, aNaN, false, FE_INVALID);
TEST_SPECIAL(inf, neg_sNaN, aNaN, false, FE_INVALID);
TEST_SPECIAL(neg_inf, sNaN, aNaN, false, FE_INVALID);
@@ -132,8 +142,8 @@ public:
TEST_SPECIAL(neg_aNaN, zero, aNaN, false, 0);
TEST_SPECIAL(aNaN, neg_zero, aNaN, false, 0);
TEST_SPECIAL(neg_aNaN, neg_zero, aNaN, false, 0);
- TEST_SPECIAL(aNaN, T(1.0), aNaN, false, 0);
- TEST_SPECIAL(neg_aNaN, T(1.0), aNaN, false, 0);
+ TEST_SPECIAL(aNaN, one, aNaN, false, 0);
+ TEST_SPECIAL(neg_aNaN, one, aNaN, false, 0);
TEST_SPECIAL(aNaN, inf, aNaN, false, 0);
TEST_SPECIAL(neg_aNaN, inf, aNaN, false, 0);
TEST_SPECIAL(aNaN, neg_inf, aNaN, false, 0);
@@ -142,8 +152,8 @@ public:
TEST_SPECIAL(neg_sNaN, zero, aNaN, false, FE_INVALID);
TEST_SPECIAL(sNaN, neg_zero, aNaN, false, FE_INVALID);
TEST_SPECIAL(neg_sNaN, neg_zero, aNaN, false, FE_INVALID);
- TEST_SPECIAL(sNaN, T(1.0), aNaN, false, FE_INVALID);
- TEST_SPECIAL(neg_sNaN, T(1.0), aNaN, false, FE_INVALID);
+ TEST_SPECIAL(sNaN, one, aNaN, false, FE_INVALID);
+ TEST_SPECIAL(neg_sNaN, one, aNaN, false, FE_INVALID);
TEST_SPECIAL(sNaN, inf, aNaN, false, FE_INVALID);
TEST_SPECIAL(neg_sNaN, inf, aNaN, false, FE_INVALID);
TEST_SPECIAL(sNaN, neg_inf, aNaN, false, FE_INVALID);
@@ -165,10 +175,10 @@ public:
TEST_SPECIAL(neg_sNaN, sNaN, aNaN, false, FE_INVALID);
TEST_SPECIAL(neg_sNaN, neg_sNaN, aNaN, false, FE_INVALID);
- TEST_SPECIAL(T(6.5), T(2.25), T(2.0), false, 0);
- TEST_SPECIAL(T(-6.5), T(2.25), T(-2.0), false, 0);
- TEST_SPECIAL(T(6.5), T(-2.25), T(2.0), false, 0);
- TEST_SPECIAL(T(-6.5), T(-2.25), T(-2.0), false, 0);
+ TEST_SPECIAL(val_6_5, val_2_25, two, false, 0);
+ TEST_SPECIAL(val_neg_6_5, val_2_25, neg_two, false, 0);
+ TEST_SPECIAL(val_6_5, val_neg_2_25, two, false, 0);
+ TEST_SPECIAL(val_neg_6_5, val_neg_2_25, neg_two, false, 0);
TEST_SPECIAL(max_normal, max_normal, zero, false, 0);
TEST_SPECIAL(max_normal, -max_normal, zero, false, 0);
diff --git a/libc/test/src/math/smoke/FloorTest.h b/libc/test/src/math/smoke/FloorTest.h
index bc19e4f..cbcf276 100644
--- a/libc/test/src/math/smoke/FloorTest.h
+++ b/libc/test/src/math/smoke/FloorTest.h
@@ -59,10 +59,11 @@ public:
EXPECT_FP_EQ(T(-11.0), func(T(-10.32)));
EXPECT_FP_EQ(T(10.0), func(T(10.65)));
EXPECT_FP_EQ(T(-11.0), func(T(-10.65)));
+ EXPECT_FP_EQ(T(50.0), func(T(50.31)));
+ EXPECT_FP_EQ(T(-50.0), func(T(-49.63)));
EXPECT_FP_EQ(T(123.0), func(T(123.38)));
EXPECT_FP_EQ(T(-124.0), func(T(-123.38)));
- EXPECT_FP_EQ(T(123.0), func(T(123.96)));
- EXPECT_FP_EQ(T(-124.0), func(T(-123.96)));
+ EXPECT_FP_EQ(T(-124.0), func(T(-123.5)));
}
};
diff --git a/libc/test/src/math/smoke/FromfpTest.h b/libc/test/src/math/smoke/FromfpTest.h
index 5620518..708ec25 100644
--- a/libc/test/src/math/smoke/FromfpTest.h
+++ b/libc/test/src/math/smoke/FromfpTest.h
@@ -85,10 +85,10 @@ public:
EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_UPWARD, 5U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_UPWARD, 5U));
EXPECT_FP_EQ(T(-10.0), func(T(-10.65), FP_INT_UPWARD, 5U));
- EXPECT_FP_EQ(T(124.0), func(T(123.38), FP_INT_UPWARD, 8U));
- EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_UPWARD, 8U));
- EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_UPWARD, 8U));
- EXPECT_FP_EQ(T(-123.0), func(T(-123.96), FP_INT_UPWARD, 8U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.25), FP_INT_UPWARD, 8U));
+ EXPECT_FP_EQ(T(-63.0), func(T(-63.25), FP_INT_UPWARD, 8U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_UPWARD, 8U));
+ EXPECT_FP_EQ(T(-63.0), func(T(-63.75), FP_INT_UPWARD, 8U));
}
void testFractionsUpwardOutsideRange(FromfpFunc func) {
@@ -139,10 +139,10 @@ public:
EXPECT_FP_EQ(T(-11.0), func(T(-10.32), FP_INT_DOWNWARD, 5U));
EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 5U));
EXPECT_FP_EQ(T(-11.0), func(T(-10.65), FP_INT_DOWNWARD, 5U));
- EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 8U));
- EXPECT_FP_EQ(T(-124.0), func(T(-123.38), FP_INT_DOWNWARD, 8U));
- EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 8U));
- EXPECT_FP_EQ(T(-124.0), func(T(-123.96), FP_INT_DOWNWARD, 8U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_DOWNWARD, 8U));
+ EXPECT_FP_EQ(T(-64.0), func(T(-63.25), FP_INT_DOWNWARD, 8U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.75), FP_INT_DOWNWARD, 8U));
+ EXPECT_FP_EQ(T(-64.0), func(T(-63.75), FP_INT_DOWNWARD, 8U));
}
void testFractionsDownwardOutsideRange(FromfpFunc func) {
@@ -193,10 +193,10 @@ public:
EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_TOWARDZERO, 5U));
EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_TOWARDZERO, 5U));
EXPECT_FP_EQ(T(-10.0), func(T(-10.65), FP_INT_TOWARDZERO, 5U));
- EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 8U));
- EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_TOWARDZERO, 8U));
- EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 8U));
- EXPECT_FP_EQ(T(-123.0), func(T(-123.96), FP_INT_TOWARDZERO, 8U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TOWARDZERO, 8U));
+ EXPECT_FP_EQ(T(-63.0), func(T(-63.25), FP_INT_TOWARDZERO, 8U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.75), FP_INT_TOWARDZERO, 8U));
+ EXPECT_FP_EQ(T(-63.0), func(T(-63.75), FP_INT_TOWARDZERO, 8U));
}
void testFractionsTowardZeroOutsideRange(FromfpFunc func) {
@@ -241,10 +241,10 @@ public:
EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_TONEARESTFROMZERO, 5U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 5U));
EXPECT_FP_EQ(T(-11.0), func(T(-10.65), FP_INT_TONEARESTFROMZERO, 5U));
- EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 8U));
- EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_TONEARESTFROMZERO, 8U));
- EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 8U));
- EXPECT_FP_EQ(T(-124.0), func(T(-123.96), FP_INT_TONEARESTFROMZERO, 8U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TONEARESTFROMZERO, 8U));
+ EXPECT_FP_EQ(T(-63.0), func(T(-63.25), FP_INT_TONEARESTFROMZERO, 8U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_TONEARESTFROMZERO, 8U));
+ EXPECT_FP_EQ(T(-64.0), func(T(-63.75), FP_INT_TONEARESTFROMZERO, 8U));
}
void testFractionsToNearestFromZeroOutsideRange(FromfpFunc func) {
@@ -297,10 +297,10 @@ public:
EXPECT_FP_EQ(T(-10.0), func(T(-10.32), FP_INT_TONEAREST, 5U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEAREST, 5U));
EXPECT_FP_EQ(T(-11.0), func(T(-10.65), FP_INT_TONEAREST, 5U));
- EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEAREST, 8U));
- EXPECT_FP_EQ(T(-123.0), func(T(-123.38), FP_INT_TONEAREST, 8U));
- EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEAREST, 8U));
- EXPECT_FP_EQ(T(-124.0), func(T(-123.96), FP_INT_TONEAREST, 8U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TONEAREST, 8U));
+ EXPECT_FP_EQ(T(-63.0), func(T(-63.25), FP_INT_TONEAREST, 8U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_TONEAREST, 8U));
+ EXPECT_FP_EQ(T(-64.0), func(T(-63.75), FP_INT_TONEAREST, 8U));
EXPECT_FP_EQ(T(2.0), func(T(2.3), FP_INT_TONEAREST, 3U));
EXPECT_FP_EQ(T(-2.0), func(T(-2.3), FP_INT_TONEAREST, 2U));
@@ -391,14 +391,12 @@ public:
EXPECT_FP_EQ(T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U));
EXPECT_FP_EQ(T(-11.0),
func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U));
- EXPECT_FP_EQ(T(123.0),
- func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
- EXPECT_FP_EQ(T(-123.0),
- func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
- EXPECT_FP_EQ(T(124.0),
- func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
- EXPECT_FP_EQ(T(-124.0),
- func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
+ EXPECT_FP_EQ(T(-63.0),
+ func(T(-63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
+ EXPECT_FP_EQ(T(-64.0),
+ func(T(-63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U));
EXPECT_FP_EQ(T(2.0), func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 3U));
EXPECT_FP_EQ(T(-2.0), func(T(-2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
diff --git a/libc/test/src/math/smoke/FromfpxTest.h b/libc/test/src/math/smoke/FromfpxTest.h
index a175a66..1930b22 100644
--- a/libc/test/src/math/smoke/FromfpxTest.h
+++ b/libc/test/src/math/smoke/FromfpxTest.h
@@ -101,13 +101,13 @@ public:
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(-10.0), func(T(-10.65), FP_INT_UPWARD, 5U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.38), FP_INT_UPWARD, 8U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.25), FP_INT_UPWARD, 8U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(-123.0), func(T(-123.38), FP_INT_UPWARD, 8U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-63.0), func(T(-63.25), FP_INT_UPWARD, 8U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_UPWARD, 8U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.75), FP_INT_UPWARD, 8U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(-123.0), func(T(-123.96), FP_INT_UPWARD, 8U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-63.0), func(T(-63.75), FP_INT_UPWARD, 8U),
FE_INEXACT);
}
@@ -175,14 +175,14 @@ public:
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(-11.0), func(T(-10.65), FP_INT_DOWNWARD, 5U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 8U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_DOWNWARD, 8U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-124.0), func(T(-123.38), FP_INT_DOWNWARD, 8U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 8U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-64.0), func(T(-63.25), FP_INT_DOWNWARD, 8U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.75), FP_INT_DOWNWARD, 8U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-64.0), func(T(-63.75), FP_INT_DOWNWARD, 8U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-124.0), func(T(-123.96), FP_INT_DOWNWARD, 8U), FE_INEXACT);
}
void testFractionsDownwardOutsideRange(FromfpxFunc func) {
@@ -249,14 +249,14 @@ public:
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
T(-10.0), func(T(-10.65), FP_INT_TOWARDZERO, 5U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_TOWARDZERO, 8U),
+ FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-123.0), func(T(-123.38), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
+ T(-63.0), func(T(-63.25), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.75), FP_INT_TOWARDZERO, 8U),
+ FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-123.0), func(T(-123.96), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
+ T(-63.0), func(T(-63.75), FP_INT_TOWARDZERO, 8U), FE_INEXACT);
}
void testFractionsTowardZeroOutsideRange(FromfpxFunc func) {
@@ -318,13 +318,13 @@ public:
EXPECT_FP_EQ_WITH_EXCEPTION(
T(-11.0), func(T(-10.65), FP_INT_TONEARESTFROMZERO, 5U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
+ T(63.0), func(T(63.25), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-123.0), func(T(-123.38), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
+ T(-63.0), func(T(-63.25), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
+ T(64.0), func(T(63.75), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-124.0), func(T(-123.96), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
+ T(-64.0), func(T(-63.75), FP_INT_TONEARESTFROMZERO, 8U), FE_INEXACT);
}
void testFractionsToNearestFromZeroOutsideRange(FromfpxFunc func) {
@@ -393,14 +393,14 @@ public:
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(-11.0), func(T(-10.65), FP_INT_TONEAREST, 5U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_TONEAREST, 8U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_TONEAREST, 8U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-123.0), func(T(-123.38), FP_INT_TONEAREST, 8U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_TONEAREST, 8U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-63.0), func(T(-63.25), FP_INT_TONEAREST, 8U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.75), FP_INT_TONEAREST, 8U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(-64.0), func(T(-63.75), FP_INT_TONEAREST, 8U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-124.0), func(T(-123.96), FP_INT_TONEAREST, 8U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.3), FP_INT_TONEAREST, 3U),
FE_INEXACT);
@@ -530,16 +530,16 @@ public:
T(-11.0), func(T(-10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 5U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(123.0), func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
+ T(63.0), func(T(63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-123.0), func(T(-123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
+ T(-63.0), func(T(-63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(124.0), func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
+ T(64.0), func(T(63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(-124.0), func(T(-123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
+ T(-64.0), func(T(-63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 8U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
diff --git a/libc/test/src/math/smoke/GetPayloadTest.h b/libc/test/src/math/smoke/GetPayloadTest.h
index 1b1bf4f..486ea42 100644
--- a/libc/test/src/math/smoke/GetPayloadTest.h
+++ b/libc/test/src/math/smoke/GetPayloadTest.h
@@ -51,23 +51,50 @@ public:
EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, sNaN));
EXPECT_FP_EQ(default_snan_payload, funcWrapper(func, neg_sNaN));
- T qnan_42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
- T neg_qnan_42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
- T snan_42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
- T neg_snan_42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
- EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, qnan_42));
- EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_qnan_42));
- EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, snan_42));
- EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_snan_42));
-
- T qnan_123 = FPBits::quiet_nan(Sign::POS, 0x123).get_val();
- T neg_qnan_123 = FPBits::quiet_nan(Sign::NEG, 0x123).get_val();
- T snan_123 = FPBits::signaling_nan(Sign::POS, 0x123).get_val();
- T neg_snan_123 = FPBits::signaling_nan(Sign::NEG, 0x123).get_val();
- EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, qnan_123));
- EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_qnan_123));
- EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, snan_123));
- EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_snan_123));
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 6) {
+ // [S] [E..E] [QM..M] -> number of M bits should be at least 6
+ // 0x31 = 0b110001 = 6 bits
+ T qnan_31 = FPBits::quiet_nan(Sign::POS, 0x31).get_val();
+ T neg_qnan_31 = FPBits::quiet_nan(Sign::NEG, 0x31).get_val();
+ T snan_31 = FPBits::signaling_nan(Sign::POS, 0x31).get_val();
+ T neg_snan_31 = FPBits::signaling_nan(Sign::NEG, 0x31).get_val();
+ EXPECT_FP_EQ(T(0x31.0p+0), funcWrapper(func, qnan_31));
+ EXPECT_FP_EQ(T(0x31.0p+0), funcWrapper(func, neg_qnan_31));
+ EXPECT_FP_EQ(T(0x31.0p+0), funcWrapper(func, snan_31));
+ EXPECT_FP_EQ(T(0x31.0p+0), funcWrapper(func, neg_snan_31));
+
+ // 0x15 = 0b10101 = 5 bits
+ T qnan_15 = FPBits::quiet_nan(Sign::POS, 0x15).get_val();
+ T neg_qnan_15 = FPBits::quiet_nan(Sign::NEG, 0x15).get_val();
+ T snan_15 = FPBits::signaling_nan(Sign::POS, 0x15).get_val();
+ T neg_snan_15 = FPBits::signaling_nan(Sign::NEG, 0x15).get_val();
+ EXPECT_FP_EQ(T(0x15.0p+0), funcWrapper(func, qnan_15));
+ EXPECT_FP_EQ(T(0x15.0p+0), funcWrapper(func, neg_qnan_15));
+ EXPECT_FP_EQ(T(0x15.0p+0), funcWrapper(func, snan_15));
+ EXPECT_FP_EQ(T(0x15.0p+0), funcWrapper(func, neg_snan_15));
+ }
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 7) {
+ T qnan_42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
+ T neg_qnan_42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
+ T snan_42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
+ T neg_snan_42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
+ EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, qnan_42));
+ EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_qnan_42));
+ EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, snan_42));
+ EXPECT_FP_EQ(T(0x42.0p+0), funcWrapper(func, neg_snan_42));
+ }
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 9) {
+ T qnan_123 = FPBits::quiet_nan(Sign::POS, 0x123).get_val();
+ T neg_qnan_123 = FPBits::quiet_nan(Sign::NEG, 0x123).get_val();
+ T snan_123 = FPBits::signaling_nan(Sign::POS, 0x123).get_val();
+ T neg_snan_123 = FPBits::signaling_nan(Sign::NEG, 0x123).get_val();
+ EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, qnan_123));
+ EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_qnan_123));
+ EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, snan_123));
+ EXPECT_FP_EQ(T(0x123.0p+0), funcWrapper(func, neg_snan_123));
+ }
}
};
diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h
index 8de70ad..d005f05 100644
--- a/libc/test/src/math/smoke/LdExpTest.h
+++ b/libc/test/src/math/smoke/LdExpTest.h
@@ -10,7 +10,8 @@
#define LLVM_LIBC_TEST_SRC_MATH_LDEXPTEST_H
#include "hdr/stdint_proxy.h"
-#include "src/__support/CPP/limits.h" // INT_MAX
+#include "src/__support/CPP/algorithm.h" // cpp::min
+#include "src/__support/CPP/limits.h" // INT_MAX
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/NormalFloat.h"
#include "test/UnitTest/FEnvSafeTest.h"
@@ -135,8 +136,8 @@ public:
// Normal which trigger mantissa overflow.
T x = NormalFloat(Sign::POS, -FPBits::EXP_BIAS + 1,
StorageType(2) * NormalFloat::ONE - StorageType(1));
- ASSERT_FP_EQ(func(x, -1), x / 2);
- ASSERT_FP_EQ(func(-x, -1), -x / 2);
+ ASSERT_FP_EQ(func(x, -1), T(x / 2));
+ ASSERT_FP_EQ(func(-x, -1), -T(x / 2));
// Start with a normal number high exponent but pass a very low number for
// exp. The result should be a subnormal number.
@@ -154,7 +155,9 @@ public:
// Start with a subnormal number but pass a very high number for exponent.
// The result should not be infinity.
- x = NormalFloat(Sign::POS, -FPBits::EXP_BIAS + 1, NormalFloat::ONE >> 10);
+ x = NormalFloat(Sign::POS, -FPBits::EXP_BIAS + 1,
+ NormalFloat::ONE >>
+ LIBC_NAMESPACE::cpp::min(FPBits::FRACTION_LEN, 10));
exp = FPBits::MAX_BIASED_EXPONENT + 5;
ASSERT_FALSE(FPBits(func(x, exp)).is_inf());
// But if the exp is large enough to oversome than the normalization shift,
diff --git a/libc/test/src/math/smoke/ModfTest.h b/libc/test/src/math/smoke/ModfTest.h
index 24cfb115..71f1c6b 100644
--- a/libc/test/src/math/smoke/ModfTest.h
+++ b/libc/test/src/math/smoke/ModfTest.h
@@ -76,10 +76,16 @@ public:
EXPECT_FP_EQ(T(-0.75), func(T(-10.75), &integral));
EXPECT_FP_EQ(integral, T(-10.0));
- EXPECT_FP_EQ(T(0.125), func(T(100.125), &integral));
+ EXPECT_FP_EQ(T(0.125), func(T(31.125), &integral));
+ EXPECT_FP_EQ(integral, T(31.0));
+
+ EXPECT_FP_EQ(T(-0.125), func(T(-31.125), &integral));
+ EXPECT_FP_EQ(integral, T(-31.0));
+
+ EXPECT_FP_EQ(T(0.5), func(T(100.5), &integral));
EXPECT_FP_EQ(integral, T(100.0));
- EXPECT_FP_EQ(T(-0.125), func(T(-100.125), &integral));
+ EXPECT_FP_EQ(T(-0.5), func(T(-100.5), &integral));
EXPECT_FP_EQ(integral, T(-100.0));
}
diff --git a/libc/test/src/math/smoke/MulTest.h b/libc/test/src/math/smoke/MulTest.h
index cf7f41a..5020067 100644
--- a/libc/test/src/math/smoke/MulTest.h
+++ b/libc/test/src/math/smoke/MulTest.h
@@ -53,10 +53,12 @@ public:
EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, func(in.zero, in.neg_zero));
EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, func(in.neg_zero, in.zero));
- EXPECT_FP_EQ_ALL_ROUNDING(OutType(1.0), func(1.0, 1.0));
- EXPECT_FP_EQ_ALL_ROUNDING(OutType(15.0), func(3.0, 5.0));
- EXPECT_FP_EQ_ALL_ROUNDING(OutType(0x1.0p-13), func(0x1.0p+1, 0x1.0p-14));
- EXPECT_FP_EQ_ALL_ROUNDING(OutType(0x1.0p-10), func(0x1.0p+2, 0x1.0p-12));
+ EXPECT_FP_EQ_ALL_ROUNDING(OutType(1.0), func(InType(1.0), InType(1.0)));
+ EXPECT_FP_EQ_ALL_ROUNDING(OutType(15.0), func(InType(3.0), InType(5.0)));
+ EXPECT_FP_EQ_ALL_ROUNDING(OutType(0x1.0p-13),
+ func(InType(0x1.0p+1), InType(0x1.0p-14)));
+ EXPECT_FP_EQ_ALL_ROUNDING(OutType(0x1.0p-10),
+ func(InType(0x1.0p+2), InType(0x1.0p-12)));
}
void test_invalid_operations(MulFunc func) {
diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h
index be27c9f..b7e59f7 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -12,6 +12,7 @@
#include "src/__support/CPP/bit.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/sign.h"
#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -42,6 +43,8 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
const T neg_inf = FPBits::inf(Sign::NEG).get_val();
const T zero = FPBits::zero(Sign::POS).get_val();
const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+ const T one = FPBits::one(Sign::POS).get_val();
+ const T neg_one = FPBits::one(Sign::NEG).get_val();
const T nan = FPBits::quiet_nan().get_val();
static constexpr StorageType min_subnormal =
@@ -55,8 +58,8 @@ public:
typedef T (*NextAfterFunc)(T, T);
void testNaN(NextAfterFunc func) {
- ASSERT_FP_EQ(func(nan, 0), nan);
- ASSERT_FP_EQ(func(0, nan), nan);
+ ASSERT_FP_EQ(func(nan, zero), nan);
+ ASSERT_FP_EQ(func(zero, nan), nan);
}
void testBoundaries(NextAfterFunc func) {
@@ -65,68 +68,68 @@ public:
// 'from' is zero|neg_zero.
T x = zero;
- T result = func(x, T(1));
+ T result = func(x, one);
StorageType expected_bits = 1;
T expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
- result = func(x, T(-1));
+ result = func(x, neg_one);
expected_bits = FPBits::SIGN_MASK + 1;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
x = neg_zero;
- result = func(x, 1);
+ result = func(x, one);
expected_bits = 1;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
- result = func(x, -1);
+ result = func(x, neg_one);
expected_bits = FPBits::SIGN_MASK + 1;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
// 'from' is max subnormal value.
x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_subnormal);
- result = func(x, 1);
+ result = func(x, one);
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
ASSERT_FP_EQ(result, expected);
- result = func(x, 0);
+ result = func(x, zero);
expected_bits = max_subnormal - 1;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
x = -x;
- result = func(x, -1);
+ result = func(x, neg_one);
expected_bits = FPBits::SIGN_MASK + min_normal;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ(result, expected);
- result = func(x, 0);
+ result = func(x, zero);
expected_bits = FPBits::SIGN_MASK + max_subnormal - 1;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
// 'from' is min subnormal value.
x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_subnormal);
- result = func(x, 1);
+ result = func(x, one);
expected_bits = min_subnormal + 1;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
- ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), zero);
+ ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, zero), zero);
x = -x;
- result = func(x, -1);
+ result = func(x, neg_one);
expected_bits = FPBits::SIGN_MASK + min_subnormal + 1;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
- ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, 0), T(-0.0));
+ ASSERT_FP_EQ_WITH_UNDERFLOW(func(x, zero), neg_zero);
// 'from' is min normal.
x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
- result = func(x, 0);
+ result = func(x, zero);
expected_bits = max_subnormal;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
@@ -137,7 +140,7 @@ public:
ASSERT_FP_EQ(result, expected);
x = -x;
- result = func(x, 0);
+ result = func(x, zero);
expected_bits = FPBits::SIGN_MASK + max_subnormal;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ_WITH_UNDERFLOW(result, expected);
@@ -157,14 +160,14 @@ public:
// 'from' is infinity.
x = inf;
- result = func(x, 0);
+ result = func(x, zero);
expected_bits = max_normal;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ(result, expected);
ASSERT_FP_EQ(func(x, inf), inf);
x = neg_inf;
- result = func(x, 0);
+ result = func(x, zero);
expected_bits = FPBits::SIGN_MASK + max_normal;
expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
ASSERT_FP_EQ(result, expected);
@@ -172,7 +175,7 @@ public:
// 'from' is a power of 2.
x = T(32.0);
- result = func(x, 0);
+ result = func(x, zero);
FPBits x_bits = FPBits(x);
FPBits result_bits = FPBits(result);
ASSERT_EQ(result_bits.get_biased_exponent(),
@@ -187,7 +190,7 @@ public:
x = -x;
- result = func(x, 0);
+ result = func(x, zero);
result_bits = FPBits(result);
ASSERT_EQ(result_bits.get_biased_exponent(),
uint16_t(x_bits.get_biased_exponent() - 1));
diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h
index d2f352c..43e71c6 100644
--- a/libc/test/src/math/smoke/NextTowardTest.h
+++ b/libc/test/src/math/smoke/NextTowardTest.h
@@ -62,8 +62,8 @@ public:
typedef T (*NextTowardFunc)(T, long double);
void testNaN(NextTowardFunc func) {
- ASSERT_FP_EQ(func(nan, 0), nan);
- ASSERT_FP_EQ(func(0, to_nan), nan);
+ ASSERT_FP_EQ(func(nan, to_zero), nan);
+ ASSERT_FP_EQ(func(zero, to_nan), nan);
}
void testBoundaries(NextTowardFunc func) {
diff --git a/libc/test/src/math/smoke/RoundTest.h b/libc/test/src/math/smoke/RoundTest.h
index beb7000..72889da 100644
--- a/libc/test/src/math/smoke/RoundTest.h
+++ b/libc/test/src/math/smoke/RoundTest.h
@@ -59,8 +59,10 @@ public:
EXPECT_FP_EQ(T(-10.0), func(T(-10.32)));
EXPECT_FP_EQ(T(11.0), func(T(10.65)));
EXPECT_FP_EQ(T(-11.0), func(T(-10.65)));
- EXPECT_FP_EQ(T(123.0), func(T(123.38)));
- EXPECT_FP_EQ(T(-123.0), func(T(-123.38)));
+ EXPECT_FP_EQ(T(50.0), func(T(49.63)));
+ EXPECT_FP_EQ(T(-50.0), func(T(-50.31)));
+ EXPECT_FP_EQ(T(124.0), func(T(123.5)));
+ EXPECT_FP_EQ(T(-124.0), func(T(-123.5)));
EXPECT_FP_EQ(T(124.0), func(T(123.96)));
EXPECT_FP_EQ(T(-124.0), func(T(-123.96)));
}
diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h
index 2b460ae..6866e91 100644
--- a/libc/test/src/math/smoke/RoundToIntegerTest.h
+++ b/libc/test/src/math/smoke/RoundToIntegerTest.h
@@ -97,8 +97,8 @@ public:
test_one_input(func, F(-1.0), I(-1), false);
test_one_input(func, F(10.0), I(10), false);
test_one_input(func, F(-10.0), I(-10), false);
- test_one_input(func, F(1234.0), I(1234), false);
- test_one_input(func, F(-1234.0), I(-1234), false);
+ test_one_input(func, F(1232.0), I(1232), false);
+ test_one_input(func, F(-1232.0), I(-1232), false);
}
void testRoundNumbers(RoundToIntegerFunc func) {
@@ -124,7 +124,7 @@ public:
continue;
// All subnormal numbers should round to zero.
if (TestModes) {
- if (x > 0) {
+ if (x > zero) {
LIBC_NAMESPACE::fputil::set_round(FE_UPWARD);
test_one_input(func, x, I(1), false);
LIBC_NAMESPACE::fputil::set_round(FE_DOWNWARD);
diff --git a/libc/test/src/math/smoke/SetPayloadSigTest.h b/libc/test/src/math/smoke/SetPayloadSigTest.h
index f4804796..7b26c98 100644
--- a/libc/test/src/math/smoke/SetPayloadSigTest.h
+++ b/libc/test/src/math/smoke/SetPayloadSigTest.h
@@ -54,15 +54,31 @@ public:
EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 1).uintval(),
FPBits(res).uintval());
- EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
- EXPECT_TRUE(FPBits(res).is_signaling_nan());
- EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x42).uintval(),
- FPBits(res).uintval());
-
- EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
- EXPECT_TRUE(FPBits(res).is_signaling_nan());
- EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x123).uintval(),
- FPBits(res).uintval());
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 6) {
+ EXPECT_EQ(0, func(&res, T(0x31.0p+0)));
+ EXPECT_TRUE(FPBits(res).is_signaling_nan());
+ EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x31).uintval(),
+ FPBits(res).uintval());
+
+ EXPECT_EQ(0, func(&res, T(0x15.0p+0)));
+ EXPECT_TRUE(FPBits(res).is_signaling_nan());
+ EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x15).uintval(),
+ FPBits(res).uintval());
+ }
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 7) {
+ EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
+ EXPECT_TRUE(FPBits(res).is_signaling_nan());
+ EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x42).uintval(),
+ FPBits(res).uintval());
+ }
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 9) {
+ EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
+ EXPECT_TRUE(FPBits(res).is_signaling_nan());
+ EXPECT_EQ(FPBits::signaling_nan(Sign::POS, 0x123).uintval(),
+ FPBits(res).uintval());
+ }
FPBits nan_payload_bits = FPBits::one();
nan_payload_bits.set_biased_exponent(FPBits::FRACTION_LEN - 2 +
diff --git a/libc/test/src/math/smoke/SetPayloadTest.h b/libc/test/src/math/smoke/SetPayloadTest.h
index 9ede567..b86b325 100644
--- a/libc/test/src/math/smoke/SetPayloadTest.h
+++ b/libc/test/src/math/smoke/SetPayloadTest.h
@@ -54,15 +54,33 @@ public:
EXPECT_TRUE(FPBits(res).is_quiet_nan());
EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 1).uintval(), FPBits(res).uintval());
- EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
- EXPECT_TRUE(FPBits(res).is_quiet_nan());
- EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x42).uintval(),
- FPBits(res).uintval());
-
- EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
- EXPECT_TRUE(FPBits(res).is_quiet_nan());
- EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x123).uintval(),
- FPBits(res).uintval());
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 5) {
+ EXPECT_EQ(0, func(&res, T(0x15.0p+0)));
+ EXPECT_TRUE(FPBits(res).is_quiet_nan());
+ EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x15).uintval(),
+ FPBits(res).uintval());
+ }
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 6) {
+ EXPECT_EQ(0, func(&res, T(0x31.0p+0)));
+ EXPECT_TRUE(FPBits(res).is_quiet_nan());
+ EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x31).uintval(),
+ FPBits(res).uintval());
+ }
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 7) {
+ EXPECT_EQ(0, func(&res, T(0x42.0p+0)));
+ EXPECT_TRUE(FPBits(res).is_quiet_nan());
+ EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x42).uintval(),
+ FPBits(res).uintval());
+ }
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 9) {
+ EXPECT_EQ(0, func(&res, T(0x123.0p+0)));
+ EXPECT_TRUE(FPBits(res).is_quiet_nan());
+ EXPECT_EQ(FPBits::quiet_nan(Sign::POS, 0x123).uintval(),
+ FPBits(res).uintval());
+ }
// The following code is creating a NaN payload manually to prevent a
// conversion from BigInt to float128.
diff --git a/libc/test/src/math/smoke/SubTest.h b/libc/test/src/math/smoke/SubTest.h
index c344db2..4ff4f3d 100644
--- a/libc/test/src/math/smoke/SubTest.h
+++ b/libc/test/src/math/smoke/SubTest.h
@@ -47,6 +47,10 @@ public:
EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.zero));
EXPECT_FP_EQ(inf, func(in.inf, in.neg_zero));
EXPECT_FP_EQ(neg_inf, func(in.neg_inf, in.neg_zero));
+ EXPECT_FP_EQ(neg_inf, func(in.zero, in.inf));
+ EXPECT_FP_EQ(neg_inf, func(in.neg_zero, in.inf));
+ EXPECT_FP_EQ(inf, func(in.zero, in.neg_inf));
+ EXPECT_FP_EQ(inf, func(in.neg_zero, in.neg_inf));
}
void test_invalid_operations(SubFunc func) {
diff --git a/libc/test/src/math/smoke/TotalOrderMagTest.h b/libc/test/src/math/smoke/TotalOrderMagTest.h
index 0a13fd2..8a389df 100644
--- a/libc/test/src/math/smoke/TotalOrderMagTest.h
+++ b/libc/test/src/math/smoke/TotalOrderMagTest.h
@@ -106,24 +106,45 @@ public:
}
void testNaNPayloads(TotalOrderMagFunc func) {
- T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
- T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
- T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
- T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
-
EXPECT_TRUE(funcWrapper(func, aNaN, aNaN));
EXPECT_TRUE(funcWrapper(func, sNaN, sNaN));
- EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42));
- EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42));
- EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN));
- EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN));
EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_aNaN));
EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_sNaN));
- EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_qnan_0x42));
- EXPECT_FALSE(funcWrapper(func, neg_sNaN, neg_snan_0x42));
- EXPECT_FALSE(funcWrapper(func, neg_qnan_0x42, neg_aNaN));
- EXPECT_TRUE(funcWrapper(func, neg_snan_0x42, neg_sNaN));
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 5) {
+ T qnan_0x15 = FPBits::quiet_nan(Sign::POS, 0x15).get_val();
+ T neg_qnan_0x15 = FPBits::quiet_nan(Sign::NEG, 0x15).get_val();
+ T snan_0x15 = FPBits::signaling_nan(Sign::POS, 0x15).get_val();
+ T neg_snan_0x15 = FPBits::signaling_nan(Sign::NEG, 0x15).get_val();
+
+ EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x15));
+ EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x15));
+ EXPECT_FALSE(funcWrapper(func, qnan_0x15, aNaN));
+ EXPECT_TRUE(funcWrapper(func, snan_0x15, sNaN));
+
+ EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_qnan_0x15));
+ EXPECT_FALSE(funcWrapper(func, neg_sNaN, neg_snan_0x15));
+ EXPECT_FALSE(funcWrapper(func, neg_qnan_0x15, neg_aNaN));
+ EXPECT_TRUE(funcWrapper(func, neg_snan_0x15, neg_sNaN));
+ }
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 7) {
+ T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
+ T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
+ T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
+ T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
+
+ EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42));
+ EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42));
+ EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN));
+ EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN));
+
+ EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_qnan_0x42));
+ EXPECT_FALSE(funcWrapper(func, neg_sNaN, neg_snan_0x42));
+ EXPECT_FALSE(funcWrapper(func, neg_qnan_0x42, neg_aNaN));
+ EXPECT_TRUE(funcWrapper(func, neg_snan_0x42, neg_sNaN));
+ }
}
};
diff --git a/libc/test/src/math/smoke/TotalOrderTest.h b/libc/test/src/math/smoke/TotalOrderTest.h
index e426eb3..50aac20 100644
--- a/libc/test/src/math/smoke/TotalOrderTest.h
+++ b/libc/test/src/math/smoke/TotalOrderTest.h
@@ -104,24 +104,45 @@ public:
}
void testNaNPayloads(TotalOrderFunc func) {
- T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
- T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
- T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
- T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
-
EXPECT_TRUE(funcWrapper(func, aNaN, aNaN));
EXPECT_TRUE(funcWrapper(func, sNaN, sNaN));
- EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42));
- EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42));
- EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN));
- EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN));
EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_aNaN));
EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_sNaN));
- EXPECT_FALSE(funcWrapper(func, neg_aNaN, neg_qnan_0x42));
- EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_snan_0x42));
- EXPECT_TRUE(funcWrapper(func, neg_qnan_0x42, neg_aNaN));
- EXPECT_FALSE(funcWrapper(func, neg_snan_0x42, neg_sNaN));
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 5) {
+ T qnan_0x15 = FPBits::quiet_nan(Sign::POS, 0x15).get_val();
+ T neg_qnan_0x15 = FPBits::quiet_nan(Sign::NEG, 0x15).get_val();
+ T snan_0x15 = FPBits::signaling_nan(Sign::POS, 0x15).get_val();
+ T neg_snan_0x15 = FPBits::signaling_nan(Sign::NEG, 0x15).get_val();
+
+ EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x15));
+ EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x15));
+ EXPECT_FALSE(funcWrapper(func, qnan_0x15, aNaN));
+ EXPECT_TRUE(funcWrapper(func, snan_0x15, sNaN));
+
+ EXPECT_FALSE(funcWrapper(func, neg_aNaN, neg_qnan_0x15));
+ EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_snan_0x15));
+ EXPECT_TRUE(funcWrapper(func, neg_qnan_0x15, neg_aNaN));
+ EXPECT_FALSE(funcWrapper(func, neg_snan_0x15, neg_sNaN));
+ }
+
+ if constexpr (FPBits::FRACTION_LEN - 1 >= 7) {
+ T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
+ T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
+ T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
+ T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
+
+ EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42));
+ EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42));
+ EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN));
+ EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN));
+
+ EXPECT_FALSE(funcWrapper(func, neg_aNaN, neg_qnan_0x42));
+ EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_snan_0x42));
+ EXPECT_TRUE(funcWrapper(func, neg_qnan_0x42, neg_aNaN));
+ EXPECT_FALSE(funcWrapper(func, neg_snan_0x42, neg_sNaN));
+ }
}
};
diff --git a/libc/test/src/math/smoke/TruncTest.h b/libc/test/src/math/smoke/TruncTest.h
index 49688e8..e088f29 100644
--- a/libc/test/src/math/smoke/TruncTest.h
+++ b/libc/test/src/math/smoke/TruncTest.h
@@ -61,8 +61,8 @@ public:
EXPECT_FP_EQ(T(-10.0), func(T(-10.65)));
EXPECT_FP_EQ(T(123.0), func(T(123.38)));
EXPECT_FP_EQ(T(-123.0), func(T(-123.38)));
- EXPECT_FP_EQ(T(123.0), func(T(123.96)));
- EXPECT_FP_EQ(T(-123.0), func(T(-123.96)));
+ EXPECT_FP_EQ(T(123.0), func(T(123.5)));
+ EXPECT_FP_EQ(T(-123.0), func(T(-123.5)));
}
};
diff --git a/libc/test/src/math/smoke/UfromfpTest.h b/libc/test/src/math/smoke/UfromfpTest.h
index 84c9f80..16785de 100644
--- a/libc/test/src/math/smoke/UfromfpTest.h
+++ b/libc/test/src/math/smoke/UfromfpTest.h
@@ -76,8 +76,8 @@ public:
EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_UPWARD, 2U));
EXPECT_FP_EQ(T(11.0), func(T(10.32), FP_INT_UPWARD, 4U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_UPWARD, 4U));
- EXPECT_FP_EQ(T(124.0), func(T(123.38), FP_INT_UPWARD, 7U));
- EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_UPWARD, 7U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.25), FP_INT_UPWARD, 7U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_UPWARD, 7U));
}
void testFractionsUpwardOutsideRange(UfromfpFunc func) {
@@ -120,8 +120,8 @@ public:
EXPECT_FP_EQ(T(1.0), func(T(1.75), FP_INT_DOWNWARD, 1U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_DOWNWARD, 4U));
EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 4U));
- EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 7U));
- EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 7U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_DOWNWARD, 7U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.75), FP_INT_DOWNWARD, 7U));
}
void testFractionsDownwardOutsideRange(UfromfpFunc func) {
@@ -167,8 +167,8 @@ public:
EXPECT_FP_EQ(T(1.0), func(T(1.75), FP_INT_TOWARDZERO, 1U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_TOWARDZERO, 4U));
EXPECT_FP_EQ(T(10.0), func(T(10.65), FP_INT_TOWARDZERO, 4U));
- EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 7U));
- EXPECT_FP_EQ(T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 7U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TOWARDZERO, 7U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.75), FP_INT_TOWARDZERO, 7U));
}
void testFractionsTowardZeroOutsideRange(UfromfpFunc func) {
@@ -206,8 +206,8 @@ public:
EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_TONEARESTFROMZERO, 2U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_TONEARESTFROMZERO, 4U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 4U));
- EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 7U));
- EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 7U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TONEARESTFROMZERO, 7U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_TONEARESTFROMZERO, 7U));
}
void testFractionsToNearestFromZeroOutsideRange(UfromfpFunc func) {
@@ -254,8 +254,8 @@ public:
EXPECT_FP_EQ(T(2.0), func(T(1.75), FP_INT_TONEAREST, 2U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), FP_INT_TONEAREST, 4U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), FP_INT_TONEAREST, 4U));
- EXPECT_FP_EQ(T(123.0), func(T(123.38), FP_INT_TONEAREST, 7U));
- EXPECT_FP_EQ(T(124.0), func(T(123.96), FP_INT_TONEAREST, 7U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), FP_INT_TONEAREST, 7U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.75), FP_INT_TONEAREST, 7U));
EXPECT_FP_EQ(T(2.0), func(T(2.3), FP_INT_TONEAREST, 2U));
EXPECT_FP_EQ(T(2.0), func(T(2.5), FP_INT_TONEAREST, 2U));
@@ -332,10 +332,8 @@ public:
EXPECT_FP_EQ(T(2.0), func(T(1.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
EXPECT_FP_EQ(T(10.0), func(T(10.32), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
EXPECT_FP_EQ(T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U));
- EXPECT_FP_EQ(T(123.0),
- func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U));
- EXPECT_FP_EQ(T(124.0),
- func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U));
+ EXPECT_FP_EQ(T(63.0), func(T(63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U));
+ EXPECT_FP_EQ(T(64.0), func(T(63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U));
EXPECT_FP_EQ(T(2.0), func(T(2.3), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
EXPECT_FP_EQ(T(2.0), func(T(2.5), UNKNOWN_MATH_ROUNDING_DIRECTION, 2U));
diff --git a/libc/test/src/math/smoke/UfromfpxTest.h b/libc/test/src/math/smoke/UfromfpxTest.h
index 5916492..1d4d3a3 100644
--- a/libc/test/src/math/smoke/UfromfpxTest.h
+++ b/libc/test/src/math/smoke/UfromfpxTest.h
@@ -87,9 +87,9 @@ public:
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.65), FP_INT_UPWARD, 4U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.38), FP_INT_UPWARD, 7U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.25), FP_INT_UPWARD, 7U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_UPWARD, 7U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.75), FP_INT_UPWARD, 7U),
FE_INEXACT);
}
@@ -141,9 +141,9 @@ public:
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.65), FP_INT_DOWNWARD, 4U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_DOWNWARD, 7U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_DOWNWARD, 7U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.96), FP_INT_DOWNWARD, 7U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.75), FP_INT_DOWNWARD, 7U),
FE_INEXACT);
}
@@ -201,10 +201,10 @@ public:
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(10.0), func(T(10.65), FP_INT_TOWARDZERO, 4U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(123.0), func(T(123.38), FP_INT_TOWARDZERO, 7U), FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(
- T(123.0), func(T(123.96), FP_INT_TOWARDZERO, 7U), FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_TOWARDZERO, 7U),
+ FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.75), FP_INT_TOWARDZERO, 7U),
+ FE_INEXACT);
}
void testFractionsTowardZeroOutsideRange(UfromfpxFunc func) {
@@ -252,9 +252,9 @@ public:
EXPECT_FP_EQ_WITH_EXCEPTION(
T(11.0), func(T(10.65), FP_INT_TONEARESTFROMZERO, 4U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(123.0), func(T(123.38), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT);
+ T(63.0), func(T(63.25), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(124.0), func(T(123.96), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT);
+ T(64.0), func(T(63.75), FP_INT_TONEARESTFROMZERO, 7U), FE_INEXACT);
}
void testFractionsToNearestFromZeroOutsideRange(UfromfpxFunc func) {
@@ -311,9 +311,9 @@ public:
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(11.0), func(T(10.65), FP_INT_TONEAREST, 4U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(123.0), func(T(123.38), FP_INT_TONEAREST, 7U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(63.0), func(T(63.25), FP_INT_TONEAREST, 7U),
FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(T(124.0), func(T(123.96), FP_INT_TONEAREST, 7U),
+ EXPECT_FP_EQ_WITH_EXCEPTION(T(64.0), func(T(63.75), FP_INT_TONEAREST, 7U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(T(2.0), func(T(2.3), FP_INT_TONEAREST, 2U),
@@ -414,10 +414,10 @@ public:
T(11.0), func(T(10.65), UNKNOWN_MATH_ROUNDING_DIRECTION, 4U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(123.0), func(T(123.38), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
+ T(63.0), func(T(63.25), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
- T(124.0), func(T(123.96), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
+ T(64.0), func(T(63.75), UNKNOWN_MATH_ROUNDING_DIRECTION, 7U),
FE_INEXACT);
EXPECT_FP_EQ_WITH_EXCEPTION(
diff --git a/libc/test/src/math/smoke/asinpif16_test.cpp b/libc/test/src/math/smoke/asinpif16_test.cpp
new file mode 100644
index 0000000..5303eed
--- /dev/null
+++ b/libc/test/src/math/smoke/asinpif16_test.cpp
@@ -0,0 +1,86 @@
+//===-- Unittests for asinpif16 -------------------------------------------===//
+//
+// 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/math/asinpif16.h"
+#include "test/UnitTest/FPMatcher.h"
+
+using LlvmLibcAsinpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAsinpif16Test, SpecialNumbers) {
+ // zero
+ EXPECT_FP_EQ(zero, LIBC_NAMESPACE::asinpif16(zero));
+
+ // +/-1
+ EXPECT_FP_EQ(0.5f16, LIBC_NAMESPACE::asinpif16(1.0));
+ EXPECT_FP_EQ(-0.5f16, LIBC_NAMESPACE::asinpif16(-1.0));
+
+ // NaN inputs
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(FPBits::quiet_nan().get_val()));
+
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(FPBits::signaling_nan().get_val()));
+
+ // infinity inputs -> should return NaN
+ libc_errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(), LIBC_NAMESPACE::asinpif16(inf));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ libc_errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(neg_inf));
+ EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAsinpif16Test, OutOfRange) {
+ // Test values > 1
+ libc_errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(1.5f16));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ libc_errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(2.0f16));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ // Test values < -1
+ libc_errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(-1.5f16));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ libc_errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(-2.0f16));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ // Test maximum normal value (should be > 1 for float16)
+ libc_errno = 0;
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::asinpif16(FPBits::max_normal().get_val()));
+ EXPECT_MATH_ERRNO(EDOM);
+}
+
+TEST_F(LlvmLibcAsinpif16Test, SymmetryProperty) {
+ // Test that asinpi(-x) = -asinpi(x)
+ constexpr float16 TEST_VALS[] = {0.1f16, 0.25f16, 0.5f16, 0.75f16,
+ 0.9f16, 0.99f16, 1.0f16};
+
+ for (float16 x : TEST_VALS) {
+ FPBits neg_x_bits(x);
+ neg_x_bits.set_sign(Sign::NEG);
+ float16 neg_x = neg_x_bits.get_val();
+
+ float16 pos_result = LIBC_NAMESPACE::asinpif16(x);
+ float16 neg_result = LIBC_NAMESPACE::asinpif16(neg_x);
+
+ EXPECT_FP_EQ(pos_result, FPBits(neg_result).abs().get_val());
+ }
+}
diff --git a/libc/test/src/math/smoke/atanpif16_test.cpp b/libc/test/src/math/smoke/atanpif16_test.cpp
new file mode 100644
index 0000000..9eb1005a
--- /dev/null
+++ b/libc/test/src/math/smoke/atanpif16_test.cpp
@@ -0,0 +1,64 @@
+//===-- Unittests for atanpif16 -------------------------------------------===//
+//
+// 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/math/atanpif16.h"
+#include "test/UnitTest/FPMatcher.h"
+
+using LIBC_NAMESPACE::cpp::array;
+using LlvmLibcAtanpif16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcAtanpif16Test, SpecialNumbers) {
+ // zero
+ EXPECT_FP_EQ(zero, LIBC_NAMESPACE::atanpif16(zero));
+ EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::atanpif16(neg_zero));
+
+ // NaN inputs
+ EXPECT_FP_EQ(FPBits::quiet_nan().get_val(),
+ LIBC_NAMESPACE::atanpif16(FPBits::quiet_nan().get_val()));
+
+ EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::atanpif16(aNaN));
+
+ // infinity inputs -> should return +/-0.5
+ EXPECT_FP_EQ(0.5f16, LIBC_NAMESPACE::atanpif16(inf));
+ EXPECT_FP_EQ(-0.5f16, LIBC_NAMESPACE::atanpif16(neg_inf));
+}
+
+TEST_F(LlvmLibcAtanpif16Test, SymmetryProperty) {
+ // Test that atanpi(-x) = -atanpi(x)
+ constexpr array<float16, 12> TEST_VALS = {
+ 0.1f16, 0.25f16, 0.5f16, 0.75f16, 1.0f16, 1.5f16,
+ 2.0f16, 5.0f16, 10.0f16, 50.0f16, 100.0f16, 1000.0f16};
+
+ for (float16 x : TEST_VALS) {
+ FPBits neg_x_bits(x);
+ neg_x_bits.set_sign(Sign::NEG);
+ float16 neg_x = neg_x_bits.get_val();
+
+ float16 pos_result = LIBC_NAMESPACE::atanpif16(x);
+ float16 neg_result = LIBC_NAMESPACE::atanpif16(neg_x);
+
+ EXPECT_FP_EQ(pos_result, FPBits(neg_result).abs().get_val());
+ }
+}
+
+TEST_F(LlvmLibcAtanpif16Test, MonotonicityProperty) {
+ // Test that atanpi is monotonically increasing
+ constexpr array<float16, 15> TEST_VALS = {
+ -1000.0f16, -100.0f16, -10.0f16, -2.0f16, -1.0f16,
+ -0.5f16, -0.1f16, 0.0f16, 0.1f16, 0.5f16,
+ 1.0f16, 2.0f16, 10.0f16, 100.0f16, 1000.0f16};
+ for (size_t i = 0; i < TEST_VALS.size() - 1; ++i) {
+ float16 x1 = TEST_VALS[i];
+ float16 x2 = TEST_VALS[i + 1];
+ float16 result1 = LIBC_NAMESPACE::atanpif16(x1);
+ float16 result2 = LIBC_NAMESPACE::atanpif16(x2);
+
+ EXPECT_TRUE(result1 < result2);
+ }
+}
diff --git a/libc/test/src/math/smoke/bf16add_test.cpp b/libc/test/src/math/smoke/bf16add_test.cpp
new file mode 100644
index 0000000..9e9c594
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16add_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16add ---------------------------------------------===//
+//
+// 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 "AddTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16add.h"
+
+LIST_ADD_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16add)
diff --git a/libc/test/src/math/smoke/bf16addf128_test.cpp b/libc/test/src/math/smoke/bf16addf128_test.cpp
new file mode 100644
index 0000000..46f7ad3
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16addf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16addf128 -----------------------------------------===//
+//
+// 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 "AddTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16addf128.h"
+
+LIST_ADD_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16addf128)
diff --git a/libc/test/src/math/smoke/bf16addf_test.cpp b/libc/test/src/math/smoke/bf16addf_test.cpp
new file mode 100644
index 0000000..06d56cf
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16addf_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16addf --------------------------------------------===//
+//
+// 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 "AddTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16addf.h"
+
+LIST_ADD_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16addf)
diff --git a/libc/test/src/math/smoke/bf16addl_test.cpp b/libc/test/src/math/smoke/bf16addl_test.cpp
new file mode 100644
index 0000000..bf54827
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16addl_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16addl --------------------------------------------===//
+//
+// 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 "AddTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16addl.h"
+
+LIST_ADD_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16addl)
diff --git a/libc/test/src/math/smoke/bf16div_test.cpp b/libc/test/src/math/smoke/bf16div_test.cpp
new file mode 100644
index 0000000..4516351
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16div_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16div ---------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16div.h"
+
+LIST_DIV_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16div)
diff --git a/libc/test/src/math/smoke/bf16divf128_test.cpp b/libc/test/src/math/smoke/bf16divf128_test.cpp
new file mode 100644
index 0000000..c42c5bb
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16divf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16divf128 -----------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16divf128.h"
+
+LIST_DIV_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16divf128)
diff --git a/libc/test/src/math/smoke/bf16divf_test.cpp b/libc/test/src/math/smoke/bf16divf_test.cpp
new file mode 100644
index 0000000..873920b
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16divf_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16divf --------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16divf.h"
+
+LIST_DIV_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16divf)
diff --git a/libc/test/src/math/smoke/bf16divl_test.cpp b/libc/test/src/math/smoke/bf16divl_test.cpp
new file mode 100644
index 0000000..32ecd62
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16divl_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16divl --------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16divl.h"
+
+LIST_DIV_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16divl)
diff --git a/libc/test/src/math/smoke/bf16fma_test.cpp b/libc/test/src/math/smoke/bf16fma_test.cpp
new file mode 100644
index 0000000..81c73a0c
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16fma_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fma ---------------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fma.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16fma)
diff --git a/libc/test/src/math/smoke/bf16fmaf128_test.cpp b/libc/test/src/math/smoke/bf16fmaf128_test.cpp
new file mode 100644
index 0000000..dd8f473
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16fmaf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fmaf128 -----------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fmaf128.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16fmaf128)
diff --git a/libc/test/src/math/smoke/bf16fmaf_test.cpp b/libc/test/src/math/smoke/bf16fmaf_test.cpp
new file mode 100644
index 0000000..04c6748
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16fmaf_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fmaf --------------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fmaf.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16fmaf)
diff --git a/libc/test/src/math/smoke/bf16fmal_test.cpp b/libc/test/src/math/smoke/bf16fmal_test.cpp
new file mode 100644
index 0000000..4c45e2c
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16fmal_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16fmal --------------------------------------------===//
+//
+// 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 "FmaTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16fmal.h"
+
+LIST_NARROWING_FMA_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16fmal)
diff --git a/libc/test/src/math/smoke/bf16mul_test.cpp b/libc/test/src/math/smoke/bf16mul_test.cpp
new file mode 100644
index 0000000..db6f0cb
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16mul_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16mul ---------------------------------------------===//
+//
+// 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 "MulTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16mul.h"
+
+LIST_MUL_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16mul)
diff --git a/libc/test/src/math/smoke/bf16mulf128_test.cpp b/libc/test/src/math/smoke/bf16mulf128_test.cpp
new file mode 100644
index 0000000..03cb9f2
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16mulf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16mulf128 -----------------------------------------===//
+//
+// 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 "MulTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16mulf128.h"
+
+LIST_MUL_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16mulf128)
diff --git a/libc/test/src/math/smoke/bf16mulf_test.cpp b/libc/test/src/math/smoke/bf16mulf_test.cpp
new file mode 100644
index 0000000..ec40e98
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16mulf_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16mulf --------------------------------------------===//
+//
+// 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 "MulTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16mulf.h"
+
+LIST_MUL_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16mulf)
diff --git a/libc/test/src/math/smoke/bf16mull_test.cpp b/libc/test/src/math/smoke/bf16mull_test.cpp
new file mode 100644
index 0000000..4cb9c9c
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16mull_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16mull --------------------------------------------===//
+//
+// 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 "MulTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16mull.h"
+
+LIST_MUL_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16mull)
diff --git a/libc/test/src/math/smoke/bf16sub_test.cpp b/libc/test/src/math/smoke/bf16sub_test.cpp
new file mode 100644
index 0000000..4a793dc
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16sub_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16sub ---------------------------------------------===//
+//
+// 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 "SubTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16sub.h"
+
+LIST_SUB_TESTS(bfloat16, double, LIBC_NAMESPACE::bf16sub)
diff --git a/libc/test/src/math/smoke/bf16subf128_test.cpp b/libc/test/src/math/smoke/bf16subf128_test.cpp
new file mode 100644
index 0000000..25d6711
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16subf128_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16subf128 -----------------------------------------===//
+//
+// 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 "SubTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16subf128.h"
+
+LIST_SUB_TESTS(bfloat16, float128, LIBC_NAMESPACE::bf16subf128)
diff --git a/libc/test/src/math/smoke/bf16subf_test.cpp b/libc/test/src/math/smoke/bf16subf_test.cpp
new file mode 100644
index 0000000..e8c7440
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16subf_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16subf --------------------------------------------===//
+//
+// 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 "SubTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16subf.h"
+
+LIST_SUB_TESTS(bfloat16, float, LIBC_NAMESPACE::bf16subf)
diff --git a/libc/test/src/math/smoke/bf16subl_test.cpp b/libc/test/src/math/smoke/bf16subl_test.cpp
new file mode 100644
index 0000000..2997369
--- /dev/null
+++ b/libc/test/src/math/smoke/bf16subl_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for bf16subl --------------------------------------------===//
+//
+// 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 "SubTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/bf16subl.h"
+
+LIST_SUB_TESTS(bfloat16, long double, LIBC_NAMESPACE::bf16subl)
diff --git a/libc/test/src/math/smoke/bfloat16_add_test.cpp b/libc/test/src/math/smoke/bfloat16_add_test.cpp
new file mode 100644
index 0000000..1db65a9
--- /dev/null
+++ b/libc/test/src/math/smoke/bfloat16_add_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bfloat16 addition -----------------------------------===//
+//
+// 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 "AddTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+
+static bfloat16 add_func(bfloat16 x, bfloat16 y) { return x + y; }
+
+LIST_ADD_TESTS(bfloat16, bfloat16, add_func)
diff --git a/libc/test/src/math/smoke/bfloat16_div_test.cpp b/libc/test/src/math/smoke/bfloat16_div_test.cpp
new file mode 100644
index 0000000..c1ab598
--- /dev/null
+++ b/libc/test/src/math/smoke/bfloat16_div_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bfloat16 division -----------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+
+static bfloat16 div_func(bfloat16 x, bfloat16 y) { return x / y; }
+
+LIST_DIV_TESTS(bfloat16, bfloat16, div_func)
diff --git a/libc/test/src/math/smoke/bfloat16_mul_test.cpp b/libc/test/src/math/smoke/bfloat16_mul_test.cpp
new file mode 100644
index 0000000..03e38d8
--- /dev/null
+++ b/libc/test/src/math/smoke/bfloat16_mul_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bfloat16 multiplication -----------------------------===//
+//
+// 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 "MulTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+
+static bfloat16 mul_func(bfloat16 x, bfloat16 y) { return x * y; }
+
+LIST_MUL_TESTS(bfloat16, bfloat16, mul_func)
diff --git a/libc/test/src/math/smoke/bfloat16_sub_test.cpp b/libc/test/src/math/smoke/bfloat16_sub_test.cpp
new file mode 100644
index 0000000..5eb4a9b
--- /dev/null
+++ b/libc/test/src/math/smoke/bfloat16_sub_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for bfloat16 subtraction --------------------------------===//
+//
+// 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 "SubTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+
+static bfloat16 sub_func(bfloat16 x, bfloat16 y) { return x - y; }
+
+LIST_SUB_TESTS(bfloat16, bfloat16, sub_func)
diff --git a/libc/test/src/math/smoke/canonicalizebf16_test.cpp b/libc/test/src/math/smoke/canonicalizebf16_test.cpp
new file mode 100644
index 0000000..bf955c2
--- /dev/null
+++ b/libc/test/src/math/smoke/canonicalizebf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for canonicalizebf16 ------------------------------------===//
+//
+// 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 "CanonicalizeTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/canonicalizebf16.h"
+
+LIST_CANONICALIZE_TESTS(bfloat16, LIBC_NAMESPACE::canonicalizebf16)
diff --git a/libc/test/src/math/smoke/ceilbf16_test.cpp b/libc/test/src/math/smoke/ceilbf16_test.cpp
new file mode 100644
index 0000000..dcaf058
--- /dev/null
+++ b/libc/test/src/math/smoke/ceilbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for ceilbf16 --------------------------------------------===//
+//
+// 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 "CeilTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/ceilbf16.h"
+
+LIST_CEIL_TESTS(bfloat16, LIBC_NAMESPACE::ceilbf16)
diff --git a/libc/test/src/math/smoke/copysignbf16_test.cpp b/libc/test/src/math/smoke/copysignbf16_test.cpp
new file mode 100644
index 0000000..71a97e3
--- /dev/null
+++ b/libc/test/src/math/smoke/copysignbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for copysignbf16 ----------------------------------------===//
+//
+// 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 "CopySignTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/copysignbf16.h"
+
+LIST_COPYSIGN_TESTS(bfloat16, LIBC_NAMESPACE::copysignbf16)
diff --git a/libc/test/src/math/smoke/fdimbf16_test.cpp b/libc/test/src/math/smoke/fdimbf16_test.cpp
new file mode 100644
index 0000000..43e8039
--- /dev/null
+++ b/libc/test/src/math/smoke/fdimbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fdimbf16 --------------------------------------------===//
+//
+// 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 "FDimTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fdimbf16.h"
+
+LIST_FDIM_TESTS(bfloat16, LIBC_NAMESPACE::fdimbf16);
diff --git a/libc/test/src/math/smoke/floorbf16_test.cpp b/libc/test/src/math/smoke/floorbf16_test.cpp
new file mode 100644
index 0000000..9cc77cd
--- /dev/null
+++ b/libc/test/src/math/smoke/floorbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for floorbf16 -------------------------------------------===//
+//
+// 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 "FloorTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/floorbf16.h"
+
+LIST_FLOOR_TESTS(bfloat16, LIBC_NAMESPACE::floorbf16)
diff --git a/libc/test/src/math/smoke/fmaxbf16_test.cpp b/libc/test/src/math/smoke/fmaxbf16_test.cpp
new file mode 100644
index 0000000..8ff9313
--- /dev/null
+++ b/libc/test/src/math/smoke/fmaxbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fmaxbf16 --------------------------------------------===//
+//
+// 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 "FMaxTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmaxbf16.h"
+
+LIST_FMAX_TESTS(bfloat16, LIBC_NAMESPACE::fmaxbf16)
diff --git a/libc/test/src/math/smoke/fmaximum_mag_numbf16_test.cpp b/libc/test/src/math/smoke/fmaximum_mag_numbf16_test.cpp
new file mode 100644
index 0000000..9e435cc
--- /dev/null
+++ b/libc/test/src/math/smoke/fmaximum_mag_numbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fmaximum_mag_numbf16 --------------------------------===//
+//
+// 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 "FMaximumMagNumTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmaximum_mag_numbf16.h"
+
+LIST_FMAXIMUM_MAG_NUM_TESTS(bfloat16, LIBC_NAMESPACE::fmaximum_mag_numbf16)
diff --git a/libc/test/src/math/smoke/fmaximum_magbf16_test.cpp b/libc/test/src/math/smoke/fmaximum_magbf16_test.cpp
new file mode 100644
index 0000000..22a0bc3
--- /dev/null
+++ b/libc/test/src/math/smoke/fmaximum_magbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fmaximum_magbf16 ------------------------------------===//
+//
+// 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 "FMaximumMagTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmaximum_magbf16.h"
+
+LIST_FMAXIMUM_MAG_TESTS(bfloat16, LIBC_NAMESPACE::fmaximum_magbf16)
diff --git a/libc/test/src/math/smoke/fmaximum_numbf16_test.cpp b/libc/test/src/math/smoke/fmaximum_numbf16_test.cpp
new file mode 100644
index 0000000..25dbe9f
--- /dev/null
+++ b/libc/test/src/math/smoke/fmaximum_numbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fmaximum_numbf16 ------------------------------------===//
+//
+// 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 "FMaximumNumTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmaximum_numbf16.h"
+
+LIST_FMAXIMUM_NUM_TESTS(bfloat16, LIBC_NAMESPACE::fmaximum_numbf16)
diff --git a/libc/test/src/math/smoke/fmaximumbf16_test.cpp b/libc/test/src/math/smoke/fmaximumbf16_test.cpp
new file mode 100644
index 0000000..e2cf56b
--- /dev/null
+++ b/libc/test/src/math/smoke/fmaximumbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fmaximumbf16 ----------------------------------------===//
+//
+// 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 "FMaximumTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmaximumbf16.h"
+
+LIST_FMAXIMUM_TESTS(bfloat16, LIBC_NAMESPACE::fmaximumbf16)
diff --git a/libc/test/src/math/smoke/fminbf16_test.cpp b/libc/test/src/math/smoke/fminbf16_test.cpp
new file mode 100644
index 0000000..195a0ac
--- /dev/null
+++ b/libc/test/src/math/smoke/fminbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fminbf16 --------------------------------------------===//
+//
+// 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 "FMinTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fminbf16.h"
+
+LIST_FMIN_TESTS(bfloat16, LIBC_NAMESPACE::fminbf16)
diff --git a/libc/test/src/math/smoke/fminimum_mag_numbf16_test.cpp b/libc/test/src/math/smoke/fminimum_mag_numbf16_test.cpp
new file mode 100644
index 0000000..ed3d447
--- /dev/null
+++ b/libc/test/src/math/smoke/fminimum_mag_numbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fminimum_mag_numbf16 --------------------------------===//
+//
+// 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 "FMinimumMagNumTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fminimum_mag_numbf16.h"
+
+LIST_FMINIMUM_MAG_NUM_TESTS(bfloat16, LIBC_NAMESPACE::fminimum_mag_numbf16)
diff --git a/libc/test/src/math/smoke/fminimum_magbf16_test.cpp b/libc/test/src/math/smoke/fminimum_magbf16_test.cpp
new file mode 100644
index 0000000..94251e0
--- /dev/null
+++ b/libc/test/src/math/smoke/fminimum_magbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fminimum_magbf16 ------------------------------------===//
+//
+// 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 "FMinimumMagTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fminimum_magbf16.h"
+
+LIST_FMINIMUM_MAG_TESTS(bfloat16, LIBC_NAMESPACE::fminimum_magbf16)
diff --git a/libc/test/src/math/smoke/fminimum_numbf16_test.cpp b/libc/test/src/math/smoke/fminimum_numbf16_test.cpp
new file mode 100644
index 0000000..fe8bb51
--- /dev/null
+++ b/libc/test/src/math/smoke/fminimum_numbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fminimum_numbf16 ------------------------------------===//
+//
+// 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 "FMinimumNumTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fminimum_numbf16.h"
+
+LIST_FMINIMUM_NUM_TESTS(bfloat16, LIBC_NAMESPACE::fminimum_numbf16)
diff --git a/libc/test/src/math/smoke/fminimumbf16_test.cpp b/libc/test/src/math/smoke/fminimumbf16_test.cpp
new file mode 100644
index 0000000..3667e90
--- /dev/null
+++ b/libc/test/src/math/smoke/fminimumbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fminimumbf16 ----------------------------------------===//
+//
+// 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 "FMinimumTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fminimumbf16.h"
+
+LIST_FMINIMUM_TESTS(bfloat16, LIBC_NAMESPACE::fminimumbf16)
diff --git a/libc/test/src/math/smoke/fmodbf16_test.cpp b/libc/test/src/math/smoke/fmodbf16_test.cpp
new file mode 100644
index 0000000..8f30941
--- /dev/null
+++ b/libc/test/src/math/smoke/fmodbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fmodbf16 --------------------------------------------===//
+//
+// 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 "FModTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fmodbf16.h"
+
+LIST_FMOD_TESTS(bfloat16, LIBC_NAMESPACE::fmodbf16)
diff --git a/libc/test/src/math/smoke/frexpbf16_test.cpp b/libc/test/src/math/smoke/frexpbf16_test.cpp
new file mode 100644
index 0000000..3c80edb
--- /dev/null
+++ b/libc/test/src/math/smoke/frexpbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for frexpbf16 -------------------------------------------===//
+//
+// 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 "FrexpTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/frexpbf16.h"
+
+LIST_FREXP_TESTS(bfloat16, LIBC_NAMESPACE::frexpbf16);
diff --git a/libc/test/src/math/smoke/fromfpbf16_test.cpp b/libc/test/src/math/smoke/fromfpbf16_test.cpp
new file mode 100644
index 0000000..45d70b2
--- /dev/null
+++ b/libc/test/src/math/smoke/fromfpbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fromfpbf16 ------------------------------------------===//
+//
+// 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 "FromfpTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fromfpbf16.h"
+
+LIST_FROMFP_TESTS(bfloat16, LIBC_NAMESPACE::fromfpbf16)
diff --git a/libc/test/src/math/smoke/fromfpxbf16_test.cpp b/libc/test/src/math/smoke/fromfpxbf16_test.cpp
new file mode 100644
index 0000000..d930ba3
--- /dev/null
+++ b/libc/test/src/math/smoke/fromfpxbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for fromfpxbf16 -----------------------------------------===//
+//
+// 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 "FromfpxTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/fromfpxbf16.h"
+
+LIST_FROMFPX_TESTS(bfloat16, LIBC_NAMESPACE::fromfpxbf16)
diff --git a/libc/test/src/math/smoke/getpayloadbf16_test.cpp b/libc/test/src/math/smoke/getpayloadbf16_test.cpp
new file mode 100644
index 0000000..51a5fad
--- /dev/null
+++ b/libc/test/src/math/smoke/getpayloadbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for getpayloadbf16 --------------------------------------===//
+//
+// 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 "GetPayloadTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/getpayloadbf16.h"
+
+LIST_GETPAYLOAD_TESTS(bfloat16, LIBC_NAMESPACE::getpayloadbf16)
diff --git a/libc/test/src/math/smoke/ilogbbf16_test.cpp b/libc/test/src/math/smoke/ilogbbf16_test.cpp
new file mode 100644
index 0000000..d9fa03a
--- /dev/null
+++ b/libc/test/src/math/smoke/ilogbbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for ilogbbf16 -------------------------------------------===//
+//
+// 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 "ILogbTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/ilogbbf16.h"
+
+LIST_INTLOGB_TESTS(int, bfloat16, LIBC_NAMESPACE::ilogbbf16);
diff --git a/libc/test/src/math/smoke/iscanonicalbf16_test.cpp b/libc/test/src/math/smoke/iscanonicalbf16_test.cpp
new file mode 100644
index 0000000..3d73588
--- /dev/null
+++ b/libc/test/src/math/smoke/iscanonicalbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for iscanonicalbf16 -------------------------------------===//
+//
+// 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 "IsCanonicalTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/iscanonicalbf16.h"
+
+LIST_ISCANONICAL_TESTS(bfloat16, LIBC_NAMESPACE::iscanonicalbf16)
diff --git a/libc/test/src/math/smoke/issignalingbf16_test.cpp b/libc/test/src/math/smoke/issignalingbf16_test.cpp
new file mode 100644
index 0000000..ed7e5af
--- /dev/null
+++ b/libc/test/src/math/smoke/issignalingbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for issignalingbf16 -------------------------------------===//
+//
+// 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 "IsSignalingTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/issignalingbf16.h"
+
+LIST_ISSIGNALING_TESTS(bfloat16, LIBC_NAMESPACE::issignalingbf16)
diff --git a/libc/test/src/math/smoke/ldexpbf16_test.cpp b/libc/test/src/math/smoke/ldexpbf16_test.cpp
new file mode 100644
index 0000000..2e57eb8
--- /dev/null
+++ b/libc/test/src/math/smoke/ldexpbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for ldexpbf16 -------------------------------------------===//
+//
+// 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 "LdExpTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/ldexpbf16.h"
+
+LIST_LDEXP_TESTS(bfloat16, LIBC_NAMESPACE::ldexpbf16);
diff --git a/libc/test/src/math/smoke/llogbbf16_test.cpp b/libc/test/src/math/smoke/llogbbf16_test.cpp
new file mode 100644
index 0000000..4454fbf
--- /dev/null
+++ b/libc/test/src/math/smoke/llogbbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for llogbbf16 -------------------------------------------===//
+//
+// 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 "ILogbTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/llogbbf16.h"
+
+LIST_INTLOGB_TESTS(long, bfloat16, LIBC_NAMESPACE::llogbbf16);
diff --git a/libc/test/src/math/smoke/llrintbf16_test.cpp b/libc/test/src/math/smoke/llrintbf16_test.cpp
new file mode 100644
index 0000000..e841e62
--- /dev/null
+++ b/libc/test/src/math/smoke/llrintbf16_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for llrintbf16 ------------------------------------------===//
+//
+// 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 "RoundToIntegerTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/llrintbf16.h"
+
+LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(bfloat16, long long,
+ LIBC_NAMESPACE::llrintbf16)
diff --git a/libc/test/src/math/smoke/llroundbf16_test.cpp b/libc/test/src/math/smoke/llroundbf16_test.cpp
new file mode 100644
index 0000000..c3b7ea4
--- /dev/null
+++ b/libc/test/src/math/smoke/llroundbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for llroundbf16 -----------------------------------------===//
+//
+// 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 "RoundToIntegerTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/llroundbf16.h"
+
+LIST_ROUND_TO_INTEGER_TESTS(bfloat16, long long, LIBC_NAMESPACE::llroundbf16)
diff --git a/libc/test/src/math/smoke/logbbf16_test.cpp b/libc/test/src/math/smoke/logbbf16_test.cpp
new file mode 100644
index 0000000..4ceec3d
--- /dev/null
+++ b/libc/test/src/math/smoke/logbbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for logbbf16 --------------------------------------------===//
+//
+// 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 "LogbTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/logbbf16.h"
+
+LIST_LOGB_TESTS(bfloat16, LIBC_NAMESPACE::logbbf16)
diff --git a/libc/test/src/math/smoke/lrintbf16_test.cpp b/libc/test/src/math/smoke/lrintbf16_test.cpp
new file mode 100644
index 0000000..65a5633b8
--- /dev/null
+++ b/libc/test/src/math/smoke/lrintbf16_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for lrintbf16 -------------------------------------------===//
+//
+// 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 "RoundToIntegerTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/lrintbf16.h"
+
+LIST_ROUND_TO_INTEGER_TESTS_WITH_MODES(bfloat16, long,
+ LIBC_NAMESPACE::lrintbf16)
diff --git a/libc/test/src/math/smoke/lroundbf16_test.cpp b/libc/test/src/math/smoke/lroundbf16_test.cpp
new file mode 100644
index 0000000..2f2b7b1
--- /dev/null
+++ b/libc/test/src/math/smoke/lroundbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for lroundbf16 ------------------------------------------===//
+//
+// 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 "RoundToIntegerTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/lroundbf16.h"
+
+LIST_ROUND_TO_INTEGER_TESTS(bfloat16, long, LIBC_NAMESPACE::lroundbf16)
diff --git a/libc/test/src/math/smoke/modfbf16_test.cpp b/libc/test/src/math/smoke/modfbf16_test.cpp
new file mode 100644
index 0000000..88ebed5
--- /dev/null
+++ b/libc/test/src/math/smoke/modfbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for modfbf16 --------------------------------------------===//
+//
+// 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 "ModfTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/modfbf16.h"
+
+LIST_MODF_TESTS(bfloat16, LIBC_NAMESPACE::modfbf16)
diff --git a/libc/test/src/math/smoke/nanbf16_test.cpp b/libc/test/src/math/smoke/nanbf16_test.cpp
new file mode 100644
index 0000000..4154f6ed
--- /dev/null
+++ b/libc/test/src/math/smoke/nanbf16_test.cpp
@@ -0,0 +1,55 @@
+//===-- Unittests for nanbf16 ---------------------------------------------===//
+//
+// 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/signal_macros.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/nanbf16.h"
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+class LlvmLibcNanf16Test : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+public:
+ using StorageType = LIBC_NAMESPACE::fputil::FPBits<bfloat16>::StorageType;
+
+ void run_test(const char *input_str, StorageType bits) {
+ bfloat16 result = LIBC_NAMESPACE::nanbf16(input_str);
+ auto actual_fp = LIBC_NAMESPACE::fputil::FPBits<bfloat16>(result);
+ auto expected_fp = LIBC_NAMESPACE::fputil::FPBits<bfloat16>(bits);
+ EXPECT_EQ(actual_fp.uintval(), expected_fp.uintval());
+ }
+};
+
+TEST_F(LlvmLibcNanf16Test, NCharSeq) {
+ run_test("", 0x7fc0);
+
+ // 0x7fc0 + 0x1f (31) = 0x7cdf
+ run_test("31", 0x7fdf);
+
+ // 0x7fc0 + 0x15 = 0x7fd5
+ run_test("0x15", 0x7fd5);
+
+ run_test("1a", 0x7fc0);
+ run_test("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_",
+ 0x7fc0);
+ run_test("10000000000000000000000000000", 0x7fc0);
+}
+
+TEST_F(LlvmLibcNanf16Test, RandomString) {
+ run_test(" 1234", 0x7fc0);
+ run_test("-1234", 0x7fc0);
+ run_test("asd&f", 0x7fc0);
+ run_test("123 ", 0x7fc0);
+}
+
+#if defined(LIBC_ADD_NULL_CHECKS)
+TEST_F(LlvmLibcNanf16Test, InvalidInput) {
+ EXPECT_DEATH([] { LIBC_NAMESPACE::nanbf16(nullptr); }, WITH_SIGNAL(-1));
+}
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/math/smoke/nearbyintbf16_test.cpp b/libc/test/src/math/smoke/nearbyintbf16_test.cpp
new file mode 100644
index 0000000..2d64fc5
--- /dev/null
+++ b/libc/test/src/math/smoke/nearbyintbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for nearbyintbf16 ---------------------------------------===//
+//
+// 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 "NearbyIntTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/nearbyintbf16.h"
+
+LIST_NEARBYINT_TESTS(bfloat16, LIBC_NAMESPACE::nearbyintbf16)
diff --git a/libc/test/src/math/smoke/nextafterbf16_test.cpp b/libc/test/src/math/smoke/nextafterbf16_test.cpp
new file mode 100644
index 0000000..b73a3cb
--- /dev/null
+++ b/libc/test/src/math/smoke/nextafterbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for nextafterbf16 ---------------------------------------===//
+//
+// 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 "NextAfterTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/nextafterbf16.h"
+
+LIST_NEXTAFTER_TESTS(bfloat16, LIBC_NAMESPACE::nextafterbf16)
diff --git a/libc/test/src/math/smoke/nextdownbf16_test.cpp b/libc/test/src/math/smoke/nextdownbf16_test.cpp
new file mode 100644
index 0000000..3002064
--- /dev/null
+++ b/libc/test/src/math/smoke/nextdownbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for nextdownbf16 ----------------------------------------===//
+//
+// 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 "NextDownTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/nextdownbf16.h"
+
+LIST_NEXTDOWN_TESTS(bfloat16, LIBC_NAMESPACE::nextdownbf16)
diff --git a/libc/test/src/math/smoke/nexttowardbf16_test.cpp b/libc/test/src/math/smoke/nexttowardbf16_test.cpp
new file mode 100644
index 0000000..c1f35fc
--- /dev/null
+++ b/libc/test/src/math/smoke/nexttowardbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for nexttowardbf16 --------------------------------------===//
+//
+// 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 "NextTowardTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/nexttowardbf16.h"
+
+LIST_NEXTTOWARD_TESTS(bfloat16, LIBC_NAMESPACE::nexttowardbf16)
diff --git a/libc/test/src/math/smoke/nextupbf16_test.cpp b/libc/test/src/math/smoke/nextupbf16_test.cpp
new file mode 100644
index 0000000..49ad2f7
--- /dev/null
+++ b/libc/test/src/math/smoke/nextupbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for nextupbf16 ------------------------------------------===//
+//
+// 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 "NextUpTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/nextupbf16.h"
+
+LIST_NEXTUP_TESTS(bfloat16, LIBC_NAMESPACE::nextupbf16)
diff --git a/libc/test/src/math/smoke/remquobf16_test.cpp b/libc/test/src/math/smoke/remquobf16_test.cpp
new file mode 100644
index 0000000..3f754bb
--- /dev/null
+++ b/libc/test/src/math/smoke/remquobf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for remquobf16 ------------------------------------------===//
+//
+// 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 "RemQuoTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/remquobf16.h"
+
+LIST_REMQUO_TESTS(bfloat16, LIBC_NAMESPACE::remquobf16)
diff --git a/libc/test/src/math/smoke/rintbf16_test.cpp b/libc/test/src/math/smoke/rintbf16_test.cpp
new file mode 100644
index 0000000..c78dcf6
--- /dev/null
+++ b/libc/test/src/math/smoke/rintbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for rintbf16 --------------------------------------------===//
+//
+// 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 "RIntTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/rintbf16.h"
+
+LIST_RINT_TESTS(bfloat16, LIBC_NAMESPACE::rintbf16)
diff --git a/libc/test/src/math/smoke/roundbf16_test.cpp b/libc/test/src/math/smoke/roundbf16_test.cpp
new file mode 100644
index 0000000..5163868
--- /dev/null
+++ b/libc/test/src/math/smoke/roundbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for roundbf16 -------------------------------------------===//
+//
+// 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 "RoundTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/roundbf16.h"
+
+LIST_ROUND_TESTS(bfloat16, LIBC_NAMESPACE::roundbf16)
diff --git a/libc/test/src/math/smoke/roundevenbf16_test.cpp b/libc/test/src/math/smoke/roundevenbf16_test.cpp
new file mode 100644
index 0000000..711c37a
--- /dev/null
+++ b/libc/test/src/math/smoke/roundevenbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for roundevenbf16 ---------------------------------------===//
+//
+// 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 "RoundEvenTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/roundevenbf16.h"
+
+LIST_ROUNDEVEN_TESTS(bfloat16, LIBC_NAMESPACE::roundevenbf16)
diff --git a/libc/test/src/math/smoke/scalblnbf16_test.cpp b/libc/test/src/math/smoke/scalblnbf16_test.cpp
new file mode 100644
index 0000000..c6fc3aa
--- /dev/null
+++ b/libc/test/src/math/smoke/scalblnbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for scalblnbf16 -----------------------------------------===//
+//
+// 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 "ScalbnTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/scalblnbf16.h"
+
+LIST_SCALBN_TESTS(bfloat16, long, LIBC_NAMESPACE::scalblnbf16)
diff --git a/libc/test/src/math/smoke/scalbnbf16_test.cpp b/libc/test/src/math/smoke/scalbnbf16_test.cpp
new file mode 100644
index 0000000..855fd75
--- /dev/null
+++ b/libc/test/src/math/smoke/scalbnbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for scalbnbf16 ------------------------------------------===//
+//
+// 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 "ScalbnTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/scalbnbf16.h"
+
+LIST_SCALBN_TESTS(bfloat16, int, LIBC_NAMESPACE::scalbnbf16)
diff --git a/libc/test/src/math/smoke/setpayloadbf16_test.cpp b/libc/test/src/math/smoke/setpayloadbf16_test.cpp
new file mode 100644
index 0000000..198b454
--- /dev/null
+++ b/libc/test/src/math/smoke/setpayloadbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for setpayloadbf16 --------------------------------------===//
+//
+// 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 "SetPayloadTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/setpayloadbf16.h"
+
+LIST_SETPAYLOAD_TESTS(bfloat16, LIBC_NAMESPACE::setpayloadbf16)
diff --git a/libc/test/src/math/smoke/setpayloadsigbf16_test.cpp b/libc/test/src/math/smoke/setpayloadsigbf16_test.cpp
new file mode 100644
index 0000000..aa6a3e9
--- /dev/null
+++ b/libc/test/src/math/smoke/setpayloadsigbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for setpayloadsigbf16 -----------------------------------===//
+//
+// 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 "SetPayloadSigTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/setpayloadsigbf16.h"
+
+LIST_SETPAYLOADSIG_TESTS(bfloat16, LIBC_NAMESPACE::setpayloadsigbf16)
diff --git a/libc/test/src/math/smoke/totalorderbf16_test.cpp b/libc/test/src/math/smoke/totalorderbf16_test.cpp
new file mode 100644
index 0000000..11aeeac
--- /dev/null
+++ b/libc/test/src/math/smoke/totalorderbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for totalorderbf16 --------------------------------------===//
+//
+// 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 "TotalOrderTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/totalorderbf16.h"
+
+LIST_TOTALORDER_TESTS(bfloat16, LIBC_NAMESPACE::totalorderbf16)
diff --git a/libc/test/src/math/smoke/totalordermagbf16_test.cpp b/libc/test/src/math/smoke/totalordermagbf16_test.cpp
new file mode 100644
index 0000000..b5a5a1b
--- /dev/null
+++ b/libc/test/src/math/smoke/totalordermagbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for totalordermagbf16 -----------------------------------===//
+//
+// 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 "TotalOrderMagTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/totalordermagbf16.h"
+
+LIST_TOTALORDERMAG_TESTS(bfloat16, LIBC_NAMESPACE::totalordermagbf16)
diff --git a/libc/test/src/math/smoke/truncbf16_test.cpp b/libc/test/src/math/smoke/truncbf16_test.cpp
new file mode 100644
index 0000000..970fa69
--- /dev/null
+++ b/libc/test/src/math/smoke/truncbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for truncbf16 -------------------------------------------===//
+//
+// 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 "TruncTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/truncbf16.h"
+
+LIST_TRUNC_TESTS(bfloat16, LIBC_NAMESPACE::truncbf16)
diff --git a/libc/test/src/math/smoke/ufromfpbf16_test.cpp b/libc/test/src/math/smoke/ufromfpbf16_test.cpp
new file mode 100644
index 0000000..2c516b0
--- /dev/null
+++ b/libc/test/src/math/smoke/ufromfpbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for ufromfpbf16 -----------------------------------------===//
+//
+// 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 "UfromfpTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/ufromfpbf16.h"
+
+LIST_UFROMFP_TESTS(bfloat16, LIBC_NAMESPACE::ufromfpbf16)
diff --git a/libc/test/src/math/smoke/ufromfpxbf16_test.cpp b/libc/test/src/math/smoke/ufromfpxbf16_test.cpp
new file mode 100644
index 0000000..56e2727
--- /dev/null
+++ b/libc/test/src/math/smoke/ufromfpxbf16_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for ufromfpxbf16 ----------------------------------------===//
+//
+// 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 "UfromfpxTest.h"
+
+#include "src/__support/FPUtil/bfloat16.h"
+#include "src/math/ufromfpxbf16.h"
+
+LIST_UFROMFPX_TESTS(bfloat16, LIBC_NAMESPACE::ufromfpxbf16)
diff --git a/libc/test/src/stdfix/BitsFxTest.h b/libc/test/src/stdfix/BitsFxTest.h
index eca6ab1..cdb363f 100644
--- a/libc/test/src/stdfix/BitsFxTest.h
+++ b/libc/test/src/stdfix/BitsFxTest.h
@@ -54,7 +54,7 @@ public:
if (max >= 11 && FXRep::FRACTION_LEN >= kMinFbits) {
// (10.71875)_10 = (1010.1011100)_2
- constexpr long long kExpected = 1372;
+ constexpr int64_t kExpected = 1372;
EXPECT_EQ(
static_cast<XType>(kExpected << (FXRep::FRACTION_LEN - kMinFbits)),
func(special_num_t));
@@ -63,9 +63,11 @@ public:
if constexpr (FXRep::SIGN_LEN > 0) {
if (min <= -11 && FXRep::FRACTION_LEN >= kMinFbits) {
// (-10.71875)_10 = (-1010.1011100)_2
- constexpr long long kExpected = -1372;
- EXPECT_EQ(static_cast<XType>(kExpected
- << (FXRep::FRACTION_LEN - kMinFbits)),
+ constexpr int64_t kExpected =
+ static_cast<int64_t>(static_cast<uint64_t>(-1372)
+ << (FXRep::FRACTION_LEN - kMinFbits));
+
+ EXPECT_EQ(static_cast<XType>(kExpected),
func(negative_special_num_t));
}
}
diff --git a/libc/test/src/string/strcspn_test.cpp b/libc/test/src/string/strcspn_test.cpp
index d83b3cf..ec98f72 100644
--- a/libc/test/src/string/strcspn_test.cpp
+++ b/libc/test/src/string/strcspn_test.cpp
@@ -48,3 +48,7 @@ TEST(LlvmLibcStrCSpnTest, DuplicatedCharactersNotPartOfComplementarySpan) {
EXPECT_EQ(LIBC_NAMESPACE::strcspn("aaaa", "aa"), size_t{0});
EXPECT_EQ(LIBC_NAMESPACE::strcspn("aaaa", "baa"), size_t{0});
}
+
+TEST(LlvmLibcStrCSpnTest, TopBitSet) {
+ EXPECT_EQ(LIBC_NAMESPACE::strcspn("hello\x80world", "\x80"), size_t{5});
+}
diff --git a/libc/test/src/string/strpbrk_test.cpp b/libc/test/src/string/strpbrk_test.cpp
index fbe14da..cc80246 100644
--- a/libc/test/src/string/strpbrk_test.cpp
+++ b/libc/test/src/string/strpbrk_test.cpp
@@ -60,3 +60,7 @@ TEST(LlvmLibcStrPBrkTest, FindsFirstOfRepeated) {
TEST(LlvmLibcStrPBrkTest, FindsFirstInBreakset) {
EXPECT_STREQ(LIBC_NAMESPACE::strpbrk("12345", "34"), "345");
}
+
+TEST(LlvmLibcStrPBrkTest, TopBitSet) {
+ EXPECT_STREQ(LIBC_NAMESPACE::strpbrk("hello\x80world", "\x80 "), "\x80world");
+}
diff --git a/libc/test/src/string/strsep_test.cpp b/libc/test/src/string/strsep_test.cpp
index 06318de..553edd9 100644
--- a/libc/test/src/string/strsep_test.cpp
+++ b/libc/test/src/string/strsep_test.cpp
@@ -18,21 +18,21 @@ TEST(LlvmLibcStrsepTest, NullSrc) {
TEST(LlvmLibcStrsepTest, NoTokenFound) {
{
char s[] = "";
- char *string = s, *orig = s;
+ char *string = s;
EXPECT_STREQ(LIBC_NAMESPACE::strsep(&string, ""), nullptr);
- EXPECT_EQ(orig, string);
+ EXPECT_TRUE(string == nullptr);
}
{
char s[] = "abcde";
char *string = s, *orig = s;
EXPECT_STREQ(LIBC_NAMESPACE::strsep(&string, ""), orig);
- EXPECT_EQ(string, orig + 5);
+ EXPECT_TRUE(string == nullptr);
}
{
char s[] = "abcde";
char *string = s, *orig = s;
EXPECT_STREQ(LIBC_NAMESPACE::strsep(&string, "fghijk"), orig);
- EXPECT_EQ(string, orig + 5);
+ EXPECT_TRUE(string == nullptr);
}
}
@@ -53,6 +53,22 @@ TEST(LlvmLibcStrsepTest, DelimitersShouldNotBeIncludedInToken) {
}
}
+TEST(LlvmLibcStrsepTest, SubsequentSearchesReturnNull) {
+ char s[] = "a";
+ char *string = s;
+ ASSERT_STREQ(LIBC_NAMESPACE::strsep(&string, ":"), "a");
+ ASSERT_EQ(LIBC_NAMESPACE::strsep(&string, ":"), nullptr);
+ ASSERT_EQ(LIBC_NAMESPACE::strsep(&string, ":"), nullptr);
+}
+
+TEST(LlvmLibcStrsepTest, TopBitSet) {
+ char top_bit_set_str[] = "hello\x80world";
+ char *p = top_bit_set_str;
+ ASSERT_STREQ(LIBC_NAMESPACE::strsep(&p, "\x80"), "hello");
+ ASSERT_STREQ(LIBC_NAMESPACE::strsep(&p, "\x80"), "world");
+ ASSERT_EQ(LIBC_NAMESPACE::strsep(&p, "\x80"), nullptr);
+}
+
#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcStrsepTest, CrashOnNullPtr) {
diff --git a/libc/test/src/string/strspn_test.cpp b/libc/test/src/string/strspn_test.cpp
index 82f9b2a..813612f 100644
--- a/libc/test/src/string/strspn_test.cpp
+++ b/libc/test/src/string/strspn_test.cpp
@@ -85,6 +85,10 @@ TEST(LlvmLibcStrSpnTest, DuplicatedCharactersToBeSearchedForShouldStillMatch) {
EXPECT_EQ(LIBC_NAMESPACE::strspn("aaaa", "aa"), size_t{4});
}
+TEST(LlvmLibcStrSpnTest, TopBitSet) {
+ EXPECT_EQ(LIBC_NAMESPACE::strspn("hello\x80world", "helo\x80rld"), size_t{6});
+}
+
#if defined(LIBC_ADD_NULL_CHECKS)
TEST(LlvmLibcStrSpnTest, CrashOnNullPtr) {
diff --git a/libc/test/src/string/strtok_r_test.cpp b/libc/test/src/string/strtok_r_test.cpp
index fdc27ba..8c4d3c36 100644
--- a/libc/test/src/string/strtok_r_test.cpp
+++ b/libc/test/src/string/strtok_r_test.cpp
@@ -122,3 +122,20 @@ TEST(LlvmLibcStrTokReentrantTest, DelimitersShouldNotBeIncludedInToken) {
token = LIBC_NAMESPACE::strtok_r(nullptr, "_:,_", &reserve);
ASSERT_STREQ(token, nullptr);
}
+
+TEST(LlvmLibcStrTokReentrantTest, SubsequentSearchesReturnNull) {
+ char src[] = "a";
+ char *reserve = nullptr;
+ char *token = LIBC_NAMESPACE::strtok_r(src, ":", &reserve);
+ ASSERT_STREQ(token, "a");
+ ASSERT_EQ(LIBC_NAMESPACE::strtok_r(nullptr, ":", &reserve), nullptr);
+ ASSERT_EQ(LIBC_NAMESPACE::strtok_r(nullptr, ":", &reserve), nullptr);
+}
+
+TEST(LlvmLibcStrTokReentrantTest, TopBitSet) {
+ char top_bit_set_str[] = "hello\x80world";
+ char *p;
+ ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(top_bit_set_str, "\x80", &p), "hello");
+ ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, "\x80", &p), "world");
+ ASSERT_EQ(LIBC_NAMESPACE::strtok_r(nullptr, "\x80", &p), nullptr);
+}
diff --git a/libc/test/src/string/strtok_test.cpp b/libc/test/src/string/strtok_test.cpp
index b820653..3c097fde 100644
--- a/libc/test/src/string/strtok_test.cpp
+++ b/libc/test/src/string/strtok_test.cpp
@@ -76,3 +76,17 @@ TEST(LlvmLibcStrTokTest, DelimitersShouldNotBeIncludedInToken) {
token = LIBC_NAMESPACE::strtok(nullptr, "_:,_");
ASSERT_STREQ(token, nullptr);
}
+
+TEST(LlvmLibcStrTokTest, SubsequentSearchesReturnNull) {
+ char src[] = "a";
+ ASSERT_STREQ("a", LIBC_NAMESPACE::strtok(src, ":"));
+ ASSERT_EQ(LIBC_NAMESPACE::strtok(nullptr, ":"), nullptr);
+ ASSERT_EQ(LIBC_NAMESPACE::strtok(nullptr, ":"), nullptr);
+}
+
+TEST(LlvmLibcStrTokTest, TopBitSet) {
+ char top_bit_set_str[] = "hello\x80world";
+ ASSERT_STREQ(LIBC_NAMESPACE::strtok(top_bit_set_str, "\x80"), "hello");
+ ASSERT_STREQ(LIBC_NAMESPACE::strtok(nullptr, "\x80"), "world");
+ ASSERT_EQ(LIBC_NAMESPACE::strtok(nullptr, "\x80"), nullptr);
+}
diff --git a/libc/test/src/sys/random/linux/getrandom_test.cpp b/libc/test/src/sys/random/linux/getrandom_test.cpp
index 70ecfbf..249942d 100644
--- a/libc/test/src/sys/random/linux/getrandom_test.cpp
+++ b/libc/test/src/sys/random/linux/getrandom_test.cpp
@@ -19,11 +19,12 @@ using LlvmLibcGetRandomTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
TEST_F(LlvmLibcGetRandomTest, InvalidFlag) {
LIBC_NAMESPACE::cpp::array<char, 10> buffer;
ASSERT_THAT(LIBC_NAMESPACE::getrandom(buffer.data(), buffer.size(), -1),
- Fails(EINVAL));
+ Fails<ssize_t>(EINVAL));
}
TEST_F(LlvmLibcGetRandomTest, InvalidBuffer) {
- ASSERT_THAT(LIBC_NAMESPACE::getrandom(nullptr, 65536, 0), Fails(EFAULT));
+ ASSERT_THAT(LIBC_NAMESPACE::getrandom(nullptr, 65536, 0),
+ Fails<ssize_t>(EFAULT));
}
TEST_F(LlvmLibcGetRandomTest, ReturnsSize) {
diff --git a/libc/test/src/time/timespec_get_test.cpp b/libc/test/src/time/timespec_get_test.cpp
index 327bfef..9758501 100644
--- a/libc/test/src/time/timespec_get_test.cpp
+++ b/libc/test/src/time/timespec_get_test.cpp
@@ -24,6 +24,8 @@ TEST(LlvmLibcTimespecGet, Utc) {
#endif
}
+// Baremetal implementation currently only supports TIME_UTC
+#ifndef LIBC_TARGET_OS_IS_BAREMETAL
TEST(LlvmLibcTimespecGet, Monotonic) {
timespec ts1, ts2;
int result;
@@ -37,6 +39,7 @@ TEST(LlvmLibcTimespecGet, Monotonic) {
ASSERT_GE(ts2.tv_nsec, ts1.tv_nsec);
}
}
+#endif
TEST(LlvmLibcTimespecGet, Unknown) {
timespec ts;
diff --git a/libc/test/src/wchar/mbrtowc_test.cpp b/libc/test/src/wchar/mbrtowc_test.cpp
index c406300..ddf8fc7 100644
--- a/libc/test/src/wchar/mbrtowc_test.cpp
+++ b/libc/test/src/wchar/mbrtowc_test.cpp
@@ -37,18 +37,18 @@ TEST_F(LlvmLibcMBRToWCTest, TwoByte) {
const char ch[2] = {static_cast<char>(0xC2),
static_cast<char>(0x8E)}; // Ž car symbol
wchar_t dest[2];
- mbstate_t *mb;
+ mbstate_t mb;
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
- size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb);
+ size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, &mb);
ASSERT_EQ(static_cast<int>(*dest), 142);
ASSERT_EQ(static_cast<int>(n), 2);
ASSERT_ERRNO_SUCCESS();
// Should fail since we have not read enough
- n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb);
ASSERT_EQ(static_cast<int>(n), -2);
// Should pass after reading one more byte
- n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 1, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 1, &mb);
ASSERT_EQ(static_cast<int>(n), 1);
ASSERT_EQ(static_cast<int>(*dest), 142);
ASSERT_ERRNO_SUCCESS();
@@ -58,19 +58,19 @@ TEST_F(LlvmLibcMBRToWCTest, ThreeByte) {
const char ch[3] = {static_cast<char>(0xE2), static_cast<char>(0x88),
static_cast<char>(0x91)}; // ∑ sigma symbol
wchar_t dest[2];
- mbstate_t *mb;
+ mbstate_t mb;
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
- size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, mb);
+ size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, &mb);
ASSERT_EQ(static_cast<int>(*dest), 8721);
ASSERT_EQ(static_cast<int>(n), 3);
ASSERT_ERRNO_SUCCESS();
// Should fail since we have not read enough
- n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb);
ASSERT_EQ(static_cast<int>(n), -2);
ASSERT_ERRNO_SUCCESS();
// Should pass after reading two more bytes
- n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, &mb);
ASSERT_EQ(static_cast<int>(n), 2);
ASSERT_EQ(static_cast<int>(*dest), 8721);
ASSERT_ERRNO_SUCCESS();
@@ -81,18 +81,18 @@ TEST_F(LlvmLibcMBRToWCTest, FourByte) {
static_cast<char>(0xA4),
static_cast<char>(0xA1)}; // 🤡 clown emoji
wchar_t dest[2];
- mbstate_t *mb;
+ mbstate_t mb;
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
- size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb);
+ size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, &mb);
ASSERT_EQ(static_cast<int>(*dest), 129313);
ASSERT_EQ(static_cast<int>(n), 4);
ASSERT_ERRNO_SUCCESS();
// Should fail since we have not read enough
- n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, &mb);
ASSERT_EQ(static_cast<int>(n), -2);
ASSERT_ERRNO_SUCCESS();
// Should pass after reading two more bytes
- n = LIBC_NAMESPACE::mbrtowc(dest, ch + 2, 2, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest, ch + 2, 2, &mb);
ASSERT_EQ(static_cast<int>(n), 2);
ASSERT_EQ(static_cast<int>(*dest), 129313);
ASSERT_ERRNO_SUCCESS();
@@ -101,9 +101,9 @@ TEST_F(LlvmLibcMBRToWCTest, FourByte) {
TEST_F(LlvmLibcMBRToWCTest, InvalidByte) {
const char ch[1] = {static_cast<char>(0x80)};
wchar_t dest[2];
- mbstate_t *mb;
+ mbstate_t mb;
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
- size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb);
+ size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb);
ASSERT_EQ(static_cast<int>(n), -1);
ASSERT_ERRNO_EQ(EILSEQ);
}
@@ -113,18 +113,18 @@ TEST_F(LlvmLibcMBRToWCTest, InvalidMultiByte) {
static_cast<char>(0x80),
static_cast<char>(0x00)}; // invalid sequence of bytes
wchar_t dest[2];
- mbstate_t *mb;
+ mbstate_t mb;
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
// Trying to push all 4 should error
- size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb);
+ size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, &mb);
ASSERT_EQ(static_cast<int>(n), -1);
ASSERT_ERRNO_EQ(EILSEQ);
// Trying to push just the first one should error
- n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &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::mbrtowc(dest, ch + 1, 2, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest, ch + 1, 2, &mb);
ASSERT_EQ(static_cast<int>(n), 0);
ASSERT_TRUE(*dest == L'\0');
ASSERT_ERRNO_SUCCESS();
@@ -136,10 +136,10 @@ TEST_F(LlvmLibcMBRToWCTest, InvalidLastByte) {
const char ch[4] = {static_cast<char>(0xF1), static_cast<char>(0x80),
static_cast<char>(0x80), static_cast<char>(0xC0)};
wchar_t dest[2];
- mbstate_t *mb;
+ mbstate_t mb;
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
// Trying to push all 4 should error
- size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, mb);
+ size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 4, &mb);
ASSERT_EQ(static_cast<int>(n), -1);
ASSERT_ERRNO_EQ(EILSEQ);
}
@@ -148,10 +148,10 @@ TEST_F(LlvmLibcMBRToWCTest, ValidTwoByteWithExtraRead) {
const char ch[3] = {static_cast<char>(0xC2), static_cast<char>(0x8E),
static_cast<char>(0x80)};
wchar_t dest[2];
- mbstate_t *mb;
+ mbstate_t mb;
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
// Trying to push all 3 should return valid 2 byte
- size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, mb);
+ size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 3, &mb);
ASSERT_EQ(static_cast<int>(n), 2);
ASSERT_EQ(static_cast<int>(*dest), 142);
ASSERT_ERRNO_SUCCESS();
@@ -161,14 +161,14 @@ TEST_F(LlvmLibcMBRToWCTest, TwoValidTwoBytes) {
const char ch[4] = {static_cast<char>(0xC2), static_cast<char>(0x8E),
static_cast<char>(0xC7), static_cast<char>(0x8C)};
wchar_t dest[2];
- mbstate_t *mb;
+ mbstate_t mb;
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
// mbstate should reset after reading first one
- size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, mb);
+ size_t n = LIBC_NAMESPACE::mbrtowc(dest, ch, 2, &mb);
ASSERT_EQ(static_cast<int>(n), 2);
ASSERT_EQ(static_cast<int>(*dest), 142);
ASSERT_ERRNO_SUCCESS();
- n = LIBC_NAMESPACE::mbrtowc(dest + 1, ch + 2, 2, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest + 1, ch + 2, 2, &mb);
ASSERT_EQ(static_cast<int>(n), 2);
ASSERT_EQ(static_cast<int>(*(dest + 1)), 460);
ASSERT_ERRNO_SUCCESS();
@@ -176,16 +176,16 @@ TEST_F(LlvmLibcMBRToWCTest, TwoValidTwoBytes) {
TEST_F(LlvmLibcMBRToWCTest, NullString) {
wchar_t dest[2] = {L'O', L'K'};
- mbstate_t *mb;
+ mbstate_t mb;
LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));
// reading on nullptr should return 0
- size_t n = LIBC_NAMESPACE::mbrtowc(dest, nullptr, 2, mb);
+ size_t n = LIBC_NAMESPACE::mbrtowc(dest, nullptr, 2, &mb);
ASSERT_EQ(static_cast<int>(n), 0);
ASSERT_TRUE(dest[0] == L'O');
ASSERT_ERRNO_SUCCESS();
// reading a null terminator should return 0
const char *ch = "\0";
- n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, mb);
+ n = LIBC_NAMESPACE::mbrtowc(dest, ch, 1, &mb);
ASSERT_EQ(static_cast<int>(n), 0);
ASSERT_ERRNO_SUCCESS();
}
@@ -194,10 +194,10 @@ 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;
+ 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);
+ size_t n = LIBC_NAMESPACE::mbrtowc(nullptr, ch, 10, &mb);
ASSERT_EQ(static_cast<int>(n), 4);
ASSERT_ERRNO_SUCCESS();
}
diff --git a/libc/test/src/wctype/iswalpha_test.cpp b/libc/test/src/wctype/iswalpha_test.cpp
index f3f75f4..a82c005 100644
--- a/libc/test/src/wctype/iswalpha_test.cpp
+++ b/libc/test/src/wctype/iswalpha_test.cpp
@@ -9,46 +9,48 @@
#include "src/__support/CPP/span.h"
#include "src/wctype/iswalpha.h"
-#include "test/UnitTest/LibcTest.h"
#include "test/UnitTest/Test.h"
-namespace {
-
-// TODO: Merge the wctype tests using this framework.
-constexpr char WALPHA_ARRAY[] = {
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
-};
-
-bool in_span(int ch, LIBC_NAMESPACE::cpp::span<const char> arr) {
- for (size_t i = 0; i < arr.size(); ++i)
- if (static_cast<int>(arr[i]) == ch)
- return true;
- return false;
-}
-
-} // namespace
-
TEST(LlvmLibciswalpha, SimpleTest) {
- EXPECT_TRUE(LIBC_NAMESPACE::iswalpha('a'));
- EXPECT_TRUE(LIBC_NAMESPACE::iswalpha('B'));
-
- EXPECT_FALSE(LIBC_NAMESPACE::iswalpha('3'));
- EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(' '));
- EXPECT_FALSE(LIBC_NAMESPACE::iswalpha('?'));
- EXPECT_FALSE(LIBC_NAMESPACE::iswalpha('\0'));
- EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(-1));
+ EXPECT_NE(LIBC_NAMESPACE::iswalpha('a'), 0);
+ EXPECT_NE(LIBC_NAMESPACE::iswalpha('B'), 0);
+
+ EXPECT_EQ(LIBC_NAMESPACE::iswalpha('3'), 0);
+ EXPECT_EQ(LIBC_NAMESPACE::iswalpha(' '), 0);
+ EXPECT_EQ(LIBC_NAMESPACE::iswalpha('?'), 0);
+ EXPECT_EQ(LIBC_NAMESPACE::iswalpha('\0'), 0);
+ EXPECT_EQ(LIBC_NAMESPACE::iswalpha(-1), 0);
}
-TEST(LlvmLibciswalpha, DefaultLocale) {
- // Loops through all characters, verifying that letters return
- // true and everything else returns false.
- for (int ch = -255; ch < 255; ++ch) {
- if (in_span(ch, WALPHA_ARRAY))
- EXPECT_TRUE(LIBC_NAMESPACE::iswalpha(ch));
- else
- EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(ch));
- }
-}
+// TODO: once iswalpha supports more than just ascii-range characters add a
+// proper test.
+
+// namespace {
+
+// // TODO: Merge the wctype tests using this framework.
+// constexpr char WALPHA_ARRAY[] = {
+// 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+// 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+// 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+// 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+// };
+
+// bool in_span(int ch, LIBC_NAMESPACE::cpp::span<const char> arr) {
+// for (size_t i = 0; i < arr.size(); ++i)
+// if (static_cast<int>(arr[i]) == ch)
+// return true;
+// return false;
+// }
+
+// } // namespace
+
+// TEST(LlvmLibciswalpha, DefaultLocale) {
+// // Loops through all characters, verifying that letters return
+// // true and everything else returns false.
+// for (int ch = -255; ch < 255; ++ch) {
+// if (in_span(ch, WALPHA_ARRAY))
+// EXPECT_TRUE(LIBC_NAMESPACE::iswalpha(ch));
+// else
+// EXPECT_FALSE(LIBC_NAMESPACE::iswalpha(ch));
+// }
+// }
diff --git a/libc/utils/MPFRWrapper/CMakeLists.txt b/libc/utils/MPFRWrapper/CMakeLists.txt
index 2669b23..73151c6 100644
--- a/libc/utils/MPFRWrapper/CMakeLists.txt
+++ b/libc/utils/MPFRWrapper/CMakeLists.txt
@@ -43,6 +43,7 @@ if(LIBC_TESTS_CAN_USE_MPFR)
libc.hdr.stdint_proxy
libc.src.__support.CPP.array
libc.src.__support.CPP.stringstream
+ libc.src.__support.FPUtil.bfloat16
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.fpbits_str
LibcTest.unit
diff --git a/libc/utils/MPFRWrapper/MPCommon.cpp b/libc/utils/MPFRWrapper/MPCommon.cpp
index 07339a0..c255220 100644
--- a/libc/utils/MPFRWrapper/MPCommon.cpp
+++ b/libc/utils/MPFRWrapper/MPCommon.cpp
@@ -105,6 +105,21 @@ MPFRNumber MPFRNumber::asinh() const {
return result;
}
+MPFRNumber MPFRNumber::asinpi() const {
+ MPFRNumber result(*this);
+#if MPFR_VERSION >= MPFR_VERSION_NUM(4, 2, 0)
+ mpfr_asinpi(result.value, value, mpfr_rounding);
+ return result;
+#else
+ MPFRNumber value_asin(0.0, 1280);
+ mpfr_asin(value_asin.value, value, MPFR_RNDN);
+ MPFRNumber value_pi(0.0, 1280);
+ mpfr_const_pi(value_pi.value, MPFR_RNDN);
+ mpfr_div(result.value, value_asin.value, value_pi.value, mpfr_rounding);
+ return result;
+#endif
+}
+
MPFRNumber MPFRNumber::atan() const {
MPFRNumber result(*this);
mpfr_atan(result.value, value, mpfr_rounding);
@@ -123,6 +138,21 @@ MPFRNumber MPFRNumber::atanh() const {
return result;
}
+MPFRNumber MPFRNumber::atanpi() const {
+ MPFRNumber result(*this);
+#if MPFR_VERSION >= MPFR_VERSION_NUM(4, 2, 0)
+ mpfr_atanpi(result.value, value, mpfr_rounding);
+ return result;
+#else
+ MPFRNumber value_atan(0.0, mpfr_precision * 3);
+ mpfr_atan(value_atan.value, value, MPFR_RNDN);
+ MPFRNumber value_pi(0.0, mpfr_precision * 3);
+ mpfr_const_pi(value_pi.value, MPFR_RNDN);
+ mpfr_div(result.value, value_atan.value, value_pi.value, mpfr_rounding);
+ return result;
+#endif
+}
+
MPFRNumber MPFRNumber::cbrt() const {
MPFRNumber result(*this);
mpfr_cbrt(result.value, value, mpfr_rounding);
diff --git a/libc/utils/MPFRWrapper/MPCommon.h b/libc/utils/MPFRWrapper/MPCommon.h
index 8bcc69c2..25bdc9b 100644
--- a/libc/utils/MPFRWrapper/MPCommon.h
+++ b/libc/utils/MPFRWrapper/MPCommon.h
@@ -189,9 +189,11 @@ public:
MPFRNumber add(const MPFRNumber &b) const;
MPFRNumber asin() const;
MPFRNumber asinh() const;
+ MPFRNumber asinpi() const;
MPFRNumber atan() const;
MPFRNumber atan2(const MPFRNumber &b);
MPFRNumber atanh() const;
+ MPFRNumber atanpi() const;
MPFRNumber cbrt() const;
MPFRNumber ceil() const;
MPFRNumber cos() const;
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index 8853f96..ed749f1 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -11,6 +11,7 @@
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/stringstream.h"
+#include "src/__support/FPUtil/bfloat16.h"
#include "src/__support/FPUtil/fpbits_str.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/types.h"
@@ -38,10 +39,14 @@ unary_operation(Operation op, InputType input, unsigned int precision,
return mpfrInput.asin();
case Operation::Asinh:
return mpfrInput.asinh();
+ case Operation::Asinpi:
+ return mpfrInput.asinpi();
case Operation::Atan:
return mpfrInput.atan();
case Operation::Atanh:
return mpfrInput.atanh();
+ case Operation::Atanpi:
+ return mpfrInput.atanpi();
case Operation::Cbrt:
return mpfrInput.cbrt();
case Operation::Ceil:
@@ -408,6 +413,23 @@ template void explain_binary_operation_one_output_error(
template void explain_binary_operation_one_output_error(
Operation, const BinaryInput<float128> &, float128, double, RoundingMode);
#endif
+template void explain_binary_operation_one_output_error(
+ Operation, const BinaryInput<bfloat16> &, bfloat16, double, RoundingMode);
+template void
+explain_binary_operation_one_output_error(Operation, const BinaryInput<float> &,
+ bfloat16, double, RoundingMode);
+template void explain_binary_operation_one_output_error(
+ Operation, const BinaryInput<double> &, bfloat16, double, RoundingMode);
+template void
+explain_binary_operation_one_output_error(Operation,
+ const BinaryInput<long double> &,
+ bfloat16, double, RoundingMode);
+#if defined(LIBC_TYPES_HAS_FLOAT128) && \
+ defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
+template void explain_binary_operation_one_output_error(
+ Operation, const BinaryInput<float128> &, bfloat16, double, RoundingMode);
+#endif // defined(LIBC_TYPES_HAS_FLOAT128) &&
+ // defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
template <typename InputType, typename OutputType>
void explain_ternary_operation_one_output_error(
@@ -468,6 +490,21 @@ explain_ternary_operation_one_output_error(Operation,
float16, double, RoundingMode);
#endif
+template void explain_ternary_operation_one_output_error(
+ Operation, const TernaryInput<float> &, bfloat16, double, RoundingMode);
+template void explain_ternary_operation_one_output_error(
+ Operation, const TernaryInput<double> &, bfloat16, double, RoundingMode);
+template void
+explain_ternary_operation_one_output_error(Operation,
+ const TernaryInput<long double> &,
+ bfloat16, double, RoundingMode);
+#if defined(LIBC_TYPES_HAS_FLOAT128) && \
+ defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
+template void explain_ternary_operation_one_output_error(
+ Operation, const TernaryInput<float128> &, bfloat16, double, RoundingMode);
+#endif // defined(LIBC_TYPES_HAS_FLOAT128) &&
+ // defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
+
template <typename InputType, typename OutputType>
bool compare_unary_operation_single_output(Operation op, InputType input,
OutputType libc_result,
@@ -641,7 +678,30 @@ template bool compare_binary_operation_one_output(Operation,
float128, double,
RoundingMode);
#endif
+template bool compare_binary_operation_one_output(Operation,
+ const BinaryInput<bfloat16> &,
+ bfloat16, double,
+ RoundingMode);
+template bool compare_binary_operation_one_output(Operation,
+ const BinaryInput<float> &,
+ bfloat16, double,
+ RoundingMode);
+template bool compare_binary_operation_one_output(Operation,
+ const BinaryInput<double> &,
+ bfloat16, double,
+ RoundingMode);
+template bool
+compare_binary_operation_one_output(Operation, const BinaryInput<long double> &,
+ bfloat16, double, RoundingMode);
+#if defined(LIBC_TYPES_HAS_FLOAT128) && \
+ defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
+template bool compare_binary_operation_one_output(Operation,
+ const BinaryInput<float128> &,
+ bfloat16, double,
+ RoundingMode);
+#endif // defined(LIBC_TYPES_HAS_FLOAT128) &&
+ // defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
template <typename InputType, typename OutputType>
bool compare_ternary_operation_one_output(Operation op,
const TernaryInput<InputType> &input,
@@ -693,6 +753,27 @@ compare_ternary_operation_one_output(Operation,
double, RoundingMode);
#endif
+template bool compare_ternary_operation_one_output(Operation,
+ const TernaryInput<float> &,
+ bfloat16, double,
+ RoundingMode);
+template bool compare_ternary_operation_one_output(Operation,
+ const TernaryInput<double> &,
+ bfloat16, double,
+ RoundingMode);
+template bool
+compare_ternary_operation_one_output(Operation,
+ const TernaryInput<long double> &,
+ bfloat16, double, RoundingMode);
+
+#if defined(LIBC_TYPES_HAS_FLOAT128) && \
+ defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
+template bool
+compare_ternary_operation_one_output(Operation, const TernaryInput<float128> &,
+ bfloat16, double, RoundingMode);
+#endif // defined(LIBC_TYPES_HAS_FLOAT128) &&
+ // defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE)
+
} // namespace internal
template <typename T> bool round_to_long(T x, long &result) {
@@ -712,6 +793,8 @@ template bool round_to_long<float16>(float16, long &);
template bool round_to_long<float128>(float128, long &);
#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
+template bool round_to_long<bfloat16>(bfloat16, long &);
+
template <typename T> bool round_to_long(T x, RoundingMode mode, long &result) {
MPFRNumber mpfr(x);
return mpfr.round_to_long(get_mpfr_rounding_mode(mode), result);
@@ -729,6 +812,8 @@ template bool round_to_long<float16>(float16, RoundingMode, long &);
template bool round_to_long<float128>(float128, RoundingMode, long &);
#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
+template bool round_to_long<bfloat16>(bfloat16, RoundingMode, long &);
+
template <typename T> T round(T x, RoundingMode mode) {
MPFRNumber mpfr(x);
MPFRNumber result = mpfr.rint(get_mpfr_rounding_mode(mode));
@@ -747,6 +832,8 @@ template float16 round<float16>(float16, RoundingMode);
template float128 round<float128>(float128, RoundingMode);
#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
+template bfloat16 round<bfloat16>(bfloat16, RoundingMode);
+
} // namespace mpfr
} // namespace testing
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h
index 45468c6..35d7942 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.h
+++ b/libc/utils/MPFRWrapper/MPFRUtils.h
@@ -30,8 +30,10 @@ enum class Operation : int {
Acospi,
Asin,
Asinh,
+ Asinpi,
Atan,
Atanh,
+ Atanpi,
Cbrt,
Ceil,
Cos,
diff --git a/libc/utils/hdrgen/hdrgen/header.py b/libc/utils/hdrgen/hdrgen/header.py
index b054ed4..2118db6 100644
--- a/libc/utils/hdrgen/hdrgen/header.py
+++ b/libc/utils/hdrgen/hdrgen/header.py
@@ -204,7 +204,7 @@ class HeaderFile:
current_guard = None
for function in self.functions:
- if function.guard == None:
+ if function.guard == None and current_guard == None:
content.append(str(function) + " __NOEXCEPT;")
content.append("")
else:
@@ -221,7 +221,8 @@ class HeaderFile:
content.append(f"#endif // {current_guard}")
content.append("")
current_guard = function.guard
- content.append(f"#ifdef {current_guard}")
+ if current_guard is not None:
+ content.append(f"#ifdef {current_guard}")
content.append(str(function) + " __NOEXCEPT;")
content.append("")
if current_guard != None: